diff --git a/packages/memoize/src/README.md b/packages/memoize/src/README.md index 64341d1..ad5a7c5 100644 --- a/packages/memoize/src/README.md +++ b/packages/memoize/src/README.md @@ -2,6 +2,21 @@ Fastest memoize library available. +## Table of contents + +- [@OSW/Memoize](#oswmemoize) + - [Table of contents](#table-of-contents) + - [Features:](#features) + - [Usage](#usage) + - [API](#api) + - [Options](#options) + - [Example](#example) + - [Building](#building) + - [Running unit tests](#running-unit-tests) +- [Roadmap](#roadmap) + - [Nice to have](#nice-to-have) +- [Limitations](#limitations) + ## Features: - Simple and fully typed API @@ -14,7 +29,57 @@ Fastest memoize library available. - 1 KB gzipped and minified with bundled dependencies - Compatible with all module systems available - ESM, CJS, AMD, System, UMD, etc. -## API +## Usage + +### API + +Memoizing a usual non recursive function: + +```ts +const memoizedFunction = memoize(yourFunction); +memoizedFunction(param1,param2,...); +``` +If the function you're trying to memoize proves to be more of a headache than anticipated there are more direct methods of accomplishing this task, and options that will be explained. + +For recursive functions: + +```ts +const memoizedFunction = memoize(yourFunction); +memoizedFunction(param1,param2,...); +``` + +### Options + +| Option | Description | Usage | +|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------| +| async : bool | Sets the type of function (sync/async) | | +| recursive : bool | Sets the type of function (recursive/non-recursive) | | +| thisArg : any | Sets the "this" argument of the function. Must be used for methods, inside the class. | memoizedMethod = memoize(this.yourMethod, { thisArg: this }); | +| stringify | No clue how this works | | +| store : IMemoizeStoreOptions | Custom store that can be used externally. Defaults to: Map | const yourStore = new Map();
memoizedFunction = memoize(yourFunction, { store: yourStore }); | +| size : IMemoizeStoreSize * | Size options - Defaults to: undefined - infinite size | memoizedFunction = memoize(yourFunction, { size: { max: 2, removeStrategy: 'clear' }); | +| time : IMemoizeStoreTime ** | Storage time options. Defaults to: undefined - infinite time span | const store = new MemoizeStore( time: { max: 3,period: 1, unit: 's' } );
memoizedFunction = memoize(yourFunction, store); | + +*For size there is: + +| Field | Description | Usage | +|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------| +| size.max : number | Maximum number of entries allowed in the store | const store = new MemoizeStore( size: { max: 2 }); | +| size.removeStrategy : IMemoizeStoreRemoveStrategy | Remove strategy if the storage is full. Defaults to: 'oldest' which enforces a LRU caching strategy. Available options 'clear' \| 'oldest' | const store = new MemoizeStore( size: { removeStrategy: 'clear' }); | + +**For time there is: + +| Field | Description | Usage | +|--------------------------------------|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------| +| time.max : number | Maximum time allowed. Defaults to: 'NaN' | const store = new MemoizeStore( time: { max: 3 } ); | +| time.period : number | Periodically clear the expired entries. Uses the same time unit as `max` - Defaults to undefined | const store = new MemoizeStore( time: { period: 1} ); | +| time.unit : IMemoizeStoreTimeUnits | Time unit - Defaults to: 'ms'. Available options 'ms', 's', 'm', 'h', 'd' | const store = new MemoizeStore( time: { unit: 's' } ); | + +## Example + +```ts + +``` ## Building diff --git a/packages/memoize/src/lib/memoize-store/memoize-store.interface.api.ts b/packages/memoize/src/lib/memoize-store/memoize-store.interface.api.ts index 576803c..7210959 100644 --- a/packages/memoize/src/lib/memoize-store/memoize-store.interface.api.ts +++ b/packages/memoize/src/lib/memoize-store/memoize-store.interface.api.ts @@ -8,11 +8,12 @@ export interface IMemoizeStore { /** Clears the entire store */ clear: () => void; } - export interface IMemoizeStoreMetadata { + /** Stores start date in unix time?? */ addedOn: number; } +/** User defined storage container */ export interface IMemoizeStoreOptions { /** Custom store that can be used externally. Defaults to: Map */ store?: IMemoizeStore; @@ -22,6 +23,7 @@ export interface IMemoizeStoreOptions { time?: IMemoizeStoreTime; } +/** User defined storage capacity */ export interface IMemoizeStoreSize { /** Maximum number of entries allowed in the store. Defaults to: 'NaN' */ max: number; @@ -29,6 +31,7 @@ export interface IMemoizeStoreSize { removeStrategy?: IMemoizeStoreRemoveStrategy; } +/** User defined storage lifespan */ export interface IMemoizeStoreTime { /** Maximum time allowed. Defaults to: 'NaN' */ max: number; diff --git a/packages/memoize/src/lib/memoize.api.spec.ts b/packages/memoize/src/lib/memoize.api.spec.ts index 748e1aa..9cfc03a 100644 --- a/packages/memoize/src/lib/memoize.api.spec.ts +++ b/packages/memoize/src/lib/memoize.api.spec.ts @@ -295,4 +295,44 @@ describe('Memoize - all default APIs should work as expected', () => { expect(memoizedTime).toBeGreaterThan(memoizedAsyncRecursiveTime); } }); + it('Example Test', () => { + let actualCalls = 0; + function testFunction(a: number, b: number) { + actualCalls++; + return a + b; + } + const a = 10; + console.log('Theoretical no. of function calls with no memoization: ' + a * a * a); + const memoizedTestFunction = memoize(testFunction); + for (let k = 0; k < a; k++) { + for (let i = 0; i < a; i++) { + for (let j = 0; j < a; j++) { + memoizedTestFunction(i, j); + } + } + } + + console.log('No. of function calls with memoization: ' + actualCalls); + }); + + it('Example Test 2', () => { + let actualCalls = 0; + const fib = memoize(async (num: number): Promise => { + actualCalls++; + if (num < 2) { + return Promise.resolve(num); + } else { + return (await fib(num - 1)) + (await fib(num - 2)); + } + }); + const a = 10; + + for (let k = 0; k < a; k++) { + for (let j = 0; j < a; j++) { + fib(j); + } + } + + console.log('No. of function calls with memoization: ' + actualCalls); + }); }); diff --git a/packages/memoize/src/lib/memoize.api.ts b/packages/memoize/src/lib/memoize.api.ts index 930107a..68b6690 100644 --- a/packages/memoize/src/lib/memoize.api.ts +++ b/packages/memoize/src/lib/memoize.api.ts @@ -18,6 +18,8 @@ export function memoizeLast( ) { return memoize(callback, { ...options, size: { max: 1 } }); } + +/** All in one memoization function, selects the correct function for the options given */ export function memoize< T extends MemoizeCallback | MemoizeAsyncCallback, R extends MemoizedFunction | MemoizedAsyncFunction = T extends MemoizeCallback diff --git a/packages/memoize/src/lib/memoize.interface.api.ts b/packages/memoize/src/lib/memoize.interface.api.ts index 22bd96f..c7b8d21 100644 --- a/packages/memoize/src/lib/memoize.interface.api.ts +++ b/packages/memoize/src/lib/memoize.interface.api.ts @@ -2,10 +2,12 @@ import { IMemoizeStoreOptions } from './memoize-store/memoize-store.interface.ap import { MemoizeStringify } from './memoize/memoize.interface'; export interface MemoizeBaseOptions extends IMemoizeStoreOptions { +/** Sets the "this" argument of the function. Must be used for methods, inside the class. */ thisArg?: any; stringify?: MemoizeStringify; } +/** Type of the function to be memoized */ export interface MemoizeOptions extends MemoizeBaseOptions { async?: boolean; recursive?: boolean; diff --git a/packages/memoize/src/lib/shared.ts b/packages/memoize/src/lib/shared.ts index def6083..5e146a6 100644 --- a/packages/memoize/src/lib/shared.ts +++ b/packages/memoize/src/lib/shared.ts @@ -58,3 +58,9 @@ export function isAsyncFunction