PHP 7.4.33
Preview: Cache.js.flow Size: 3.77 KB
/var/www/uibuilder.cmshelp.dk/httpdocs/node_modules/metro-cache/src/Cache.js.flow
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 * @oncall react_native
 */

'use strict';

import type {CacheStore} from 'metro-cache';

const {Logger} = require('metro-core');

/**
 * Main cache class. Receives an array of cache instances, and sequentially
 * traverses them to return a previously stored value. It also ensures setting
 * the value in all instances.
 *
 * All get/set operations are logged via Metro's logger.
 */
class Cache<T> {
  _stores: $ReadOnlyArray<CacheStore<T>>;

  _hits: WeakMap<Buffer, CacheStore<T>>;

  constructor(stores: $ReadOnlyArray<CacheStore<T>>) {
    this._hits = new WeakMap();
    this._stores = stores;
  }

  async get(key: Buffer): Promise<?T> {
    const stores = this._stores;
    const length = stores.length;

    for (let i = 0; i < length; i++) {
      const store = stores[i];
      const storeName = store.name ?? store.constructor.name;
      const name = storeName + '::' + key.toString('hex');
      let value = null;

      const logStart = Logger.log(
        Logger.createActionStartEntry({
          action_name: 'Cache get',
          log_entry_label: name,
        }),
      );

      try {
        const valueOrPromise = store.get(key);

        // $FlowFixMe[method-unbinding] added when improving typing for this parameters
        if (valueOrPromise && typeof valueOrPromise.then === 'function') {
          value = await valueOrPromise;
        } else {
          value = valueOrPromise;
        }
      } finally {
        const hitOrMiss = value != null ? 'hit' : 'miss';
        Logger.log({
          ...Logger.createActionEndEntry(logStart),
          action_result: hitOrMiss,
        });

        // Deprecated - will be removed () - use 'Cache get' and action_result
        // (above) instead.
        // TODO: T196506422
        Logger.log(
          Logger.createEntry({
            action_name: 'Cache ' + hitOrMiss,
            log_entry_label: name,
          }),
        );

        if (value != null) {
          this._hits.set(key, store);

          return value;
        }
      }
    }

    return null;
  }

  async set(key: Buffer, value: T): Promise<void> {
    const stores = this._stores;
    const stop = this._hits.get(key);
    const length = stores.length;
    const promises = [];
    const writeErrors = [];
    const storesWithErrors = new Set<string>();

    for (let i = 0; i < length && stores[i] !== stop; i++) {
      const store = stores[i];
      const storeName = store.name ?? store.constructor.name;
      const name = storeName + '::' + key.toString('hex');

      const logStart = Logger.log(
        Logger.createActionStartEntry({
          action_name: 'Cache set',
          log_entry_label: name,
        }),
      );

      promises.push(
        (async () => {
          try {
            await stores[i].set(key, value);
            Logger.log(Logger.createActionEndEntry(logStart));
          } catch (e) {
            Logger.log(Logger.createActionEndEntry(logStart, e));
            storesWithErrors.add(storeName);
            writeErrors.push(
              new Error(`Cache write failed for ${name}`, {cause: e}),
            );
          }
        })(),
      );
    }

    await Promise.allSettled(promises);
    if (writeErrors.length > 0) {
      throw new AggregateError(
        writeErrors,
        `Cache write failed for store(s): ${Array.from(storesWithErrors).join(', ')}`,
      );
    }
  }

  // Returns true if the current configuration disables the cache, such that
  // writing to the cache is a no-op and reading from the cache will always
  // return null.
  get isDisabled(): boolean {
    return this._stores.length === 0;
  }
}

module.exports = Cache;

Directory Contents

Dirs: 1 × Files: 12
Name Size Perms Modified Actions
stores DIR
- drwxr-xr-x 2025-03-28 11:04:32
Edit Download
721 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
2.72 KB lrw-r--r-- 2025-03-28 11:04:32
Edit Download
3.77 KB lrw-r--r-- 2025-03-28 11:04:32
Edit Download
1.01 KB lrw-r--r-- 2025-03-28 11:04:32
Edit Download
559 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
988 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
290 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
281 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
759 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
419 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
14 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
436 B lrw-r--r-- 2025-03-28 11:04:32
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).