Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ users = await cachedGetUsers(); // <-- This will be executed and cached

You can pass an additional parameter `dependencyKeys` property which instructs the plugin about which keys to use to invalidate the cache records if necessary.
This property can be either a number, a string, an array of strings, a function that returns an array of strings or a function that returns a Promise fulfilled with an array of strings.
Both the function and the Promise will receive the result of the method on which the `cacheCandidate` operates.
Both the function and the Promise will receive the result of the method on which the `cacheCandidate` operates as the first argument and the function arguments as the second argument (`fnArgs`).
In case of an async method, the promise will be fulfilled before passing the result to the `dependencyKeys` function.
The `dependencyKeys` function will be called only if the cache adapter correctly sets the value in the cache (i.e. the `.set` method is fulfilled).
32 changes: 32 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,36 @@ test('CacheCandidatePlugin - CacheCandidate', async (t) => {
await sleep(EXECUTION_MARGIN);
}
);

await t.test(
'should correctly pass fnArgs to the dependencyKeys function',
async () => {
const step = stepper();
let capturedFnArgs: any = null;
let capturedResult: any = null;

const mockFn = (arg1: string, arg2: number, arg3: boolean) =>
new Promise((resolve) => {
resolve({ arg1, arg2, arg3 });
});

const wrappedMockFn = cacheCandidate(mockFn, {
requestsThreshold: 1,
ttl: 800,
...pluginsOptions((result: any, fnArgs: any[]) => {
capturedResult = result;
capturedFnArgs = fnArgs;
return ['test-key'];
})
});

await wrappedMockFn('hello', 42, true);
await sleep(EXECUTION_MARGIN);

assert.deepEqual(capturedFnArgs, ['hello', 42, true]);
assert.deepEqual(capturedResult, { arg1: 'hello', arg2: 42, arg3: true });
assert.equal(cacheCandidateDependencyManager.instances.size, 1);
assert.ok(cacheCandidateDependencyManager.instances.has('test-key'));
}
);
});
7 changes: 4 additions & 3 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const PluginDependencyKeys: CacheCandidatePlugin = {
let dependencyKeys: any = additionalParameters.dependencyKeys;
dependencyKeys = await remapDependencyKeys(
dependencyKeys,
payload.result
payload.result,
payload.fnArgs
);
cacheCandidateDependencyManager.register(
payload,
Expand All @@ -36,9 +37,9 @@ export const PluginDependencyKeys: CacheCandidatePlugin = {
]
};

async function remapDependencyKeys(dependencyKeys: any, result: unknown) {
async function remapDependencyKeys(dependencyKeys: any, result: unknown, fnArgs: unknown[]) {
if (typeof dependencyKeys === 'function') {
dependencyKeys = dependencyKeys(result);
dependencyKeys = dependencyKeys(result, fnArgs);
if (dependencyKeys instanceof Promise) {
dependencyKeys = await dependencyKeys;
}
Expand Down