diff --git a/README.md b/README.md index c65bf1b..11da3ac 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,28 @@ console.log(await getUserById(1)); // Cache was filled an valid. `getFreshValue` was not invoked ``` +### Pre-configuring cachified + +We can create versions of cachified with defaults so that we don't have to +specify the same options every time. + + + +```ts +import { configure } from '@epic-web/cachified'; +import { LRUCache } from 'lru-cache'; + +/* lruCachified now has a default cache */ +const lruCachified = configure({ + cache: new LRUCache({ max: 1000 }), +}); + +const value = await lruCachified({ + key: 'user-1', + getFreshValue: async () => 'ONE', +}); +``` + ### Manually working with the cache During normal app lifecycle there usually is no need for this but for diff --git a/src/cachified.spec.ts b/src/cachified.spec.ts index 52053e1..3d77f55 100644 --- a/src/cachified.spec.ts +++ b/src/cachified.spec.ts @@ -12,6 +12,7 @@ import { } from './index'; import { Deferred } from './createBatch'; import { delay, report } from './testHelpers'; +import { configure } from './configure'; jest.mock('./index', () => { if (process.version.startsWith('v20')) { @@ -1536,6 +1537,22 @@ describe('cachified', () => { }); expect(await getValue(() => () => {})).toBe('FOUR'); }); + + it('supports creating pre-configured cachified functions', async () => { + const configuredCachified = configure({ + cache: new Map(), + }); + + const value = await configuredCachified({ + key: 'test', + // look mom, no cache! + getFreshValue() { + return 'ONE'; + }, + }); + + expect(value).toBe('ONE'); + }); }); function createReporter() { diff --git a/src/configure.ts b/src/configure.ts new file mode 100644 index 0000000..7845b72 --- /dev/null +++ b/src/configure.ts @@ -0,0 +1,43 @@ +import { cachified } from './cachified'; +import { CachifiedOptions, CachifiedOptionsWithSchema } from './common'; +import { CreateReporter, mergeReporters } from './reporter'; + +type PartialOptions< + Options extends CachifiedOptions, + OptionalKeys extends string | number | symbol, +> = Omit & + Partial>>; + +/** + * create a pre-configured version of cachified + */ +export function configure< + ConfigureValue extends unknown, + Opts extends Partial>, +>(defaultOptions: Opts, defaultReporter?: CreateReporter) { + function configuredCachified( + options: PartialOptions< + CachifiedOptionsWithSchema, + keyof Opts + >, + reporter?: CreateReporter, + ): Promise; + async function configuredCachified( + options: PartialOptions, keyof Opts>, + reporter?: CreateReporter, + ): Promise; + function configuredCachified( + options: PartialOptions, keyof Opts>, + reporter?: CreateReporter, + ) { + return cachified( + { + ...defaultOptions, + ...options, + } as any as CachifiedOptions, + mergeReporters(defaultReporter as any as CreateReporter, reporter), + ); + } + + return configuredCachified; +} diff --git a/src/index.ts b/src/index.ts index d65ddcd..ee4528d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,3 +15,4 @@ export { cachified as default } from './cachified'; export { shouldRefresh } from './shouldRefresh'; export { assertCacheEntry } from './assertCacheEntry'; export { softPurge } from './softPurge'; +export { configure } from './configure';