PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/metro-file-map/src/cache
Просмотр файла: DiskCacheManager.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 strict-local
* @format
* @oncall react_native
*/
import type {
BuildParameters,
CacheData,
CacheManager,
CacheManagerFactoryOptions,
CacheManagerWriteOptions,
} from '../flow-types';
import rootRelativeCacheKeys from '../lib/rootRelativeCacheKeys';
import {promises as fsPromises} from 'fs';
import {tmpdir} from 'os';
import path from 'path';
import {Timeout, clearTimeout, setTimeout} from 'timers';
import {deserialize, serialize} from 'v8';
// eslint-disable-next-line import/no-commonjs
const debug = require('debug')('Metro:FileMapCache');
type AutoSaveOptions = $ReadOnly<{
debounceMs: number,
}>;
type DiskCacheConfig = $ReadOnly<{
autoSave?: Partial<AutoSaveOptions> | boolean,
cacheFilePrefix?: ?string,
cacheDirectory?: ?string,
}>;
const DEFAULT_PREFIX = 'metro-file-map';
const DEFAULT_DIRECTORY = tmpdir();
const DEFAULT_AUTO_SAVE_DEBOUNCE_MS = 5000;
export class DiskCacheManager implements CacheManager {
+#autoSaveOpts: ?AutoSaveOptions;
+#cachePath: string;
#debounceTimeout: ?Timeout = null;
#writePromise: Promise<void> = Promise.resolve();
#hasUnwrittenChanges: boolean = false;
#tryWrite: ?() => Promise<void>;
#stopListening: ?() => void;
constructor(
{buildParameters}: CacheManagerFactoryOptions,
{autoSave = {}, cacheDirectory, cacheFilePrefix}: DiskCacheConfig,
) {
this.#cachePath = DiskCacheManager.getCacheFilePath(
buildParameters,
cacheFilePrefix,
cacheDirectory,
);
// Normalise auto-save options.
if (autoSave) {
const {debounceMs = DEFAULT_AUTO_SAVE_DEBOUNCE_MS} =
autoSave === true ? {} : autoSave;
this.#autoSaveOpts = {debounceMs};
}
}
static getCacheFilePath(
buildParameters: BuildParameters,
cacheFilePrefix?: ?string,
cacheDirectory?: ?string,
): string {
const {rootDirHash, relativeConfigHash} =
rootRelativeCacheKeys(buildParameters);
return path.join(
cacheDirectory ?? DEFAULT_DIRECTORY,
`${
cacheFilePrefix ?? DEFAULT_PREFIX
}-${rootDirHash}-${relativeConfigHash}`,
);
}
getCacheFilePath(): string {
return this.#cachePath;
}
async read(): Promise<?CacheData> {
try {
return deserialize(await fsPromises.readFile(this.#cachePath));
} catch (e) {
if (e?.code === 'ENOENT') {
// Cache file not found - not considered an error.
return null;
}
// Rethrow anything else.
throw e;
}
}
async write(
getSnapshot: () => CacheData,
{
changedSinceCacheRead,
eventSource,
onWriteError,
}: CacheManagerWriteOptions,
): Promise<void> {
// Initialise a writer function using a promise queue to ensure writes are
// sequenced.
const tryWrite = (this.#tryWrite = () => {
this.#writePromise = this.#writePromise
.then(async () => {
if (!this.#hasUnwrittenChanges) {
return;
}
const data = getSnapshot();
this.#hasUnwrittenChanges = false;
await fsPromises.writeFile(this.#cachePath, serialize(data));
debug('Written cache to %s', this.#cachePath);
})
.catch(onWriteError);
return this.#writePromise;
});
// Set up auto-save on changes, if enabled.
if (this.#autoSaveOpts) {
const autoSave = this.#autoSaveOpts;
this.#stopListening?.();
this.#stopListening = eventSource.onChange(() => {
this.#hasUnwrittenChanges = true;
if (this.#debounceTimeout) {
this.#debounceTimeout.refresh();
} else {
this.#debounceTimeout = setTimeout(
() => tryWrite(),
autoSave.debounceMs,
).unref();
}
});
}
// Write immediately if state has changed since the cache was read.
if (changedSinceCacheRead) {
this.#hasUnwrittenChanges = true;
await tryWrite();
}
}
async end() {
// Clear any timers
if (this.#debounceTimeout) {
clearTimeout(this.#debounceTimeout);
}
// Remove event listeners
this.#stopListening?.();
// Flush unwritten changes to disk (no-op if no changes)
await this.#tryWrite?.();
}
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!