static async createStatistics(storageMethod, build, context) {
    const {id: buildId, projectId, lifecycle} = build;
    if (lifecycle !== 'sealed') throw new Error('Cannot create statistics for unsealed build');

    const runsTimer = startDebugTimer('createStatistics.getRuns');
    const runs = await storageMethod.getRuns(projectId, buildId);
    /** @type {Array<Array<[LHCI.ServerCommand.Run, LH.Result]>>} */
    const runsByUrl = _.groupBy(
      runs.map(run => [run, JSON.parse(run.lhr)]),
      ([run, _]) => run.url
    );
    runsTimer.end();

    log(`creating statistics for ${runs.length} run(s)`);
    const statisicDefinitionEntries = Object.entries(statisticDefinitions);
    const existingStatistics = context.existingStatistics || [];

    const statisticsTimer = startDebugTimer('createStatistics.getStatistics');
    const statistics = await Bluebird.map(
      statisicDefinitionEntries,
      async ([key, fn]) => {
        const name = /** @type {LHCI.ServerCommand.StatisticName} */ (key);

        const statistics = Bluebird.map(
          runsByUrl,
          runs => {
            const url = runs[0][0].url;
            const {value} = fn(runs.map(([_, lhr]) => lhr));
            const existing = existingStatistics.find(
              s => s.name === name && s.value === value && s.url === url
            );
            if (existing && existing.version === STATISTIC_VERSION) return existing;

            return storageMethod._createOrUpdateStatistic(
              {
                projectId,
                buildId,
                url,
                version: STATISTIC_VERSION,
                name,
                value,
              },
              context
            );
          },
          {concurrency: 4}
        );

        log(`created statistics for ${name}`);
        return statistics;
      },
      {concurrency: 8}
    );
    statisticsTimer.end();

    return {
      statistics: statistics.reduce((a, b) => a.concat(b)),
      representativeRuns: computeRepresentativeRuns(runsByUrl),
    };
  }
@template TTransactionHandle
@param {StorageMethod} storageMethod
@param {LHCI.ServerCommand.Build} build
@param {{transaction?: TTransactionHandle, existingStatistics?: Array<LHCI.ServerCommand.Statistic>}} context
@return {Promise<{statistics: Array<LHCI.ServerCommand.Statistic>, representativeRuns: Array<LHCI.ServerCommand.Run>}>}