Skip to content

Commit ff09c3c

Browse files
authored
Merge pull request #67 from tabkram/feature/memoize
refactor(execution): memoize options
2 parents 42b78ef + 38a6773 commit ff09c3c

5 files changed

Lines changed: 24 additions & 32 deletions

File tree

src/common/models/executionMemoization.model.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { FunctionMetadata } from './executionFunction.model';
22

33
export const memoizationKey = Symbol('execution-engine/memoize');
44

5-
/** Default expiration that ensures multiple rapid calls can reuse the stored result */
6-
export const memoizationDefaultExpirationMs = 100;
7-
/** Maximum allowable expiration time Prevent excessive retention */
8-
export const memoizationMaxExpirationMs = 1000;
5+
/** Default expiration in milliseconds that ensures multiple rapid calls can reuse the stored result */
6+
export const memoizationDefaultTTL = 100;
7+
/** Maximum allowable expiration time in milliseconds to prevent excessive retention */
8+
export const memoizationMaxTTL = 1000;
99

1010
/**
1111
* Represents the context of a memoized function execution.
@@ -17,22 +17,17 @@ export interface MemoizationContext <O> {
1717
value?: Promise<O> | O;
1818
}
1919

20-
21-
/**
22-
* A handler function that processes the memoization context.
23-
*/
24-
export type MemoizationHandler<O> = (info: MemoizationContext<O>) => void;
25-
2620
export interface MemoizeOptions<O> {
2721
/** Unique identifier for the function being memoized */
2822
functionId: string;
2923

3024
/**
31-
* Optional expiration time in milliseconds for the cached result.
25+
* Optional small expiration time in milliseconds for the memoized result.
26+
* @remarks:
3227
* Default is 100ms, capped at 1000ms to prevent excessive retention.
3328
*/
34-
expirationMs?: number;
29+
ttl?: number;
3530

3631
/** Custom handler for memoization logic */
37-
memoizationHandler?: MemoizationHandler<O>;
32+
onMemoizeEvent?: (info: MemoizationContext<O>) => void;
3833
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { memoize } from './memoizeDecorator';
1+
import { memoize } from './memoize.decorator';
22
import { MemoizationContext } from '../common/models/executionMemoization.model';
33

44
describe('memoize decorator', () => {
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
import { executeMemoize } from './memoize';
22
import { FunctionMetadata } from '../common/models/executionFunction.model';
3-
import { MemoizationHandler } from '../common/models/executionMemoization.model';
3+
import { MemoizeOptions } from '../common/models/executionMemoization.model';
44
import { attachFunctionMetadata, extractClassMethodMetadata } from '../common/utils/functionMetadata';
55

66
/**
77
* Decorator to memoize method executions and prevent redundant calls.
88
*
9-
* @param memoizationHandler - Optional callback triggered after checking memory
10-
* @param expirationMs - Duration (in milliseconds) before clearing the stored result,
9+
* @param onMemoizeEvent - Optional callback triggered after checking memory
10+
* @param ttl - Small duration (in milliseconds) before clearing the stored result,
1111
* capped at 1000ms to prevent excessive retention.
1212
* @returns A method decorator for applying memoization.
1313
*
1414
* @remarks
1515
* Uses `executeMemoize` internally to store and reuse results.
1616
* A short delay (e.g., 100ms) ensures that multiple rapid calls can reuse the stored result.
1717
*/
18-
export function memoize<O>(memoizationHandler?: MemoizationHandler<O>, expirationMs?: number): MethodDecorator {
18+
export function memoize<O>(onMemoizeEvent?: MemoizeOptions<O>['onMemoizeEvent'], ttl?: number): MethodDecorator {
1919
return function <T extends Record<string, unknown>>(target: T, propertyKey: string, descriptor: PropertyDescriptor) {
2020
const originalMethod = descriptor.value;
2121
descriptor.value = function (...args: unknown[]): ReturnType<typeof originalMethod> {
2222
const thisMethodMetadata: FunctionMetadata = extractClassMethodMetadata(target.constructor.name, propertyKey, originalMethod);
2323
return (executeMemoize.bind(this) as typeof executeMemoize<O>)(originalMethod.bind(this), args, {
2424
functionId: thisMethodMetadata.methodSignature,
25-
memoizationHandler: attachFunctionMetadata.bind(this)(memoizationHandler, thisMethodMetadata),
26-
expirationMs
25+
onMemoizeEvent: attachFunctionMetadata.bind(this)(onMemoizeEvent, thisMethodMetadata),
26+
ttl
2727
});
2828
};
2929
};

src/execution/memoize.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { execute } from './execute';
22
import {
3-
memoizationDefaultExpirationMs,
3+
memoizationDefaultTTL,
44
memoizationKey,
5-
memoizationMaxExpirationMs,
5+
memoizationMaxTTL,
66
MemoizeOptions
77
} from '../common/models/executionMemoization.model';
88
import { generateHashId } from '../common/utils/crypto';
@@ -26,10 +26,7 @@ export function executeMemoize<O>(
2626
*
2727
* @param blockFunction - The function to execute and memoize.
2828
* @param inputs - Arguments used to generate a unique memoization key.
29-
* @param options - Additional options including a unique function identifier.
30-
* @param options.expirationMs - Duration (in milliseconds) before clearing the stored result,
31-
* capped at 1000ms to prevent excessive retention.
32-
* @param options.memoizationHandler - Optional callback triggered after checking memoization memory.
29+
* @param options - Additional options.
3330
* @returns The memoized result or a newly computed value.
3431
*
3532
* @remarks
@@ -42,7 +39,7 @@ export function executeMemoize<O>(
4239
inputs: Array<unknown> = [],
4340
options: MemoizeOptions<O>
4441
): Promise<O> | O {
45-
const expirationMs = Math.min(options.expirationMs ?? memoizationDefaultExpirationMs, memoizationMaxExpirationMs); // Default short delay and Prevent excessive retention
42+
const ttl = Math.min(options.ttl ?? memoizationDefaultTTL, memoizationMaxTTL); // Default short delay and Prevent excessive retention
4643
const memoizationFullStore: Map<string, Map<string, Promise<O> | O>> = (this[memoizationKey] ??= new Map<
4744
string,
4845
Map<string, Promise<O> | O>
@@ -51,9 +48,9 @@ export function executeMemoize<O>(
5148
const inputsHash = generateHashId(...inputs);
5249
const memoizedValue = memoizationStore.get(inputsHash);
5350

54-
if (typeof options.memoizationHandler === 'function') {
51+
if (typeof options.onMemoizeEvent === 'function') {
5552
const functionMetadata = extractFunctionMetadata(blockFunction);
56-
options.memoizationHandler({ metadata: functionMetadata, inputsHash, isMemoized: !!memoizedValue, value: memoizedValue });
53+
options.onMemoizeEvent({ metadata: functionMetadata, inputsHash, isMemoized: !!memoizedValue, value: memoizedValue });
5754
}
5855

5956
if (memoizedValue) {
@@ -72,9 +69,9 @@ export function executeMemoize<O>(
7269
this[memoizationKey].set(options.functionId, memoizationStore);
7370

7471
if (callResponseOrPromise instanceof Promise) {
75-
return callResponseOrPromise.finally(() => setTimeout(() => memoizationStore.delete(inputsHash), expirationMs));
72+
return callResponseOrPromise.finally(() => setTimeout(() => memoizationStore.delete(inputsHash), ttl));
7673
} else {
77-
setTimeout(() => memoizationStore.delete(inputsHash), expirationMs);
74+
setTimeout(() => memoizationStore.delete(inputsHash), ttl);
7875
return callResponseOrPromise;
7976
}
8077
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export * from './engine/traceableEngine';
1717
export * from './execution/cache.decorator';
1818
export * from './execution/cache';
1919
export * from './execution/execute';
20+
export * from './execution/memoize.decorator';
2021
export * from './execution/memoize';
21-
export * from './execution/memoizeDecorator';
2222
export * from './timer/executionTimer';
2323
export * from './trace/trace';
2424
export * from './trace/traceDecorator';

0 commit comments

Comments
 (0)