diff --git a/Build/lib/fs-memo.ts b/Build/lib/fs-memo.ts index 3f626e8c..13c14a55 100644 --- a/Build/lib/fs-memo.ts +++ b/Build/lib/fs-memo.ts @@ -3,14 +3,18 @@ import { Cache } from './cache-filesystem'; import type { CacheApplyOption } from './cache-filesystem'; import { isCI } from 'ci-info'; -import { Typeson, set, map, typedArrays } from 'typeson-registry'; +import { xxhash64 } from 'hash-wasm'; + +import { Typeson, set, map, typedArrays, undef, infinity } from 'typeson-registry'; import picocolors from 'picocolors'; import { identity } from './misc'; const typeson = new Typeson().register([ typedArrays, set, - map + map, + undef, + infinity ]); const fsMemoCache = new Cache({ cachePath: path.resolve(__dirname, '../../.cache'), tableName: 'fs_memo_cache' }); @@ -26,6 +30,7 @@ type TypesonValue = | number | boolean | null + | undefined | Set | Map | TypesonObject @@ -45,14 +50,17 @@ export function cache( fn: (...args: Args) => Promise, opt: FsMemoCacheOptions ): (...args: Args) => Promise { - // TODO if cb.toString() is long we should hash it const fixedKey = fn.toString(); return async function cachedCb(...args: Args) { // Construct the complete cache key for this function invocation // typeson.stringify is still limited. For now we uses typescript to guard the args. - const cacheKey = `${fixedKey}|${typeson.stringifySync(args)}`; - const cacheName = fn.name || cacheKey; + const cacheKey = (await Promise.all([ + xxhash64(fixedKey), + xxhash64(typeson.stringifySync(args)) + ])).join('|'); + + const cacheName = fn.name || fixedKey; const { temporaryBypass, incrementTtlWhenHit } = opt; diff --git a/Build/lib/memo-promise.ts b/Build/lib/memo-promise.ts index 04e1f8a8..97123c17 100644 --- a/Build/lib/memo-promise.ts +++ b/Build/lib/memo-promise.ts @@ -1,6 +1,10 @@ const notError = Symbol('notError'); -export function createMemoizedPromise(fn: () => Promise, preload = true): () => Promise { +export function createMemoizedPromise( + fn: () => Promise, + /** whether to create promise immediately or only create after first access */ + preload = true +): () => Promise { let error: Error | typeof notError = notError; let promise: Promise | null = preload