Comparing version 1.0.1 to 1.0.2
@@ -13,8 +13,8 @@ import { isWeakable } from "./utils"; | ||
reads++; | ||
var test_1 = storage.get(args[i]); | ||
if (test_1) { | ||
if (test_1.arguments.length === max && | ||
test_1.arguments.every(function (v, index) { return v === args[index]; })) { | ||
var test = storage.get(args[i]); | ||
if (test) { | ||
if (test.arguments.length === max && | ||
test.arguments.every(function (v, index) { return v === args[index]; })) { | ||
return { | ||
value: test_1.storedValue, | ||
value: test.storedValue, | ||
index: i, | ||
@@ -21,0 +21,0 @@ }; |
@@ -1,1 +0,3 @@ | ||
export var isWeakable = function (value) { return (value && (typeof value === 'object')); }; | ||
export var isWeakable = function (value) { return (value && (typeof value === 'object') | ||
// || typeof value === 'function' // not using function to prevent leaks | ||
); }; |
import { WeakStorage } from "./types"; | ||
declare type WeakStorageCreator = () => WeakStorage; | ||
export declare function weakMemoizeCreator(cacheCreator?: WeakStorageCreator, mapper?: (x: any, index: number) => any): <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
/** | ||
* weak memoization helper. | ||
* Uses the __first__ given argument to store result. | ||
* | ||
* `kache`'s API is equal to any other single-line memoization library except the requirement for | ||
* the first argument to be an object. | ||
* | ||
* π‘ hint: sometimes it worth to move some arguments, put pick the "best one" to be the first | ||
* | ||
* @param {Object} argument0 - first argument has to be {object}, {array} or {function} | ||
* @param argument1 - any other, as well we any number or arguments | ||
* | ||
* @see https://github.com/theKashey/kashe#kashe | ||
* @example | ||
* // create a selector, which returns a new array using `array.filter` every time | ||
* const badSelector = (array) => array.filter(somehow) | ||
* // make it return the same object for the same array called. | ||
* const goodSelector = kashe(badSelector); | ||
*/ | ||
export declare const kashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
/** | ||
* a special version of {@link kashe} which does not strictly checks arg1+. | ||
* Could be used to bypass equality check, however use with caution | ||
* | ||
* @see https://github.com/theKashey/kashe#weakkashe | ||
* @example | ||
* const weakMap = weakKashe((data, iterator, ...deps) => data.map(iterator)); | ||
* const derived = weakMap(data, line => ({...line, somethingElse}), localVariable1); | ||
* // π second argument is changing every time, but as long as it's __String representation__ is the same - result is unchanged. | ||
*/ | ||
export declare const weakKashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
export declare function swap<T, K, R>(fn: (t: T, k: K) => R): (k: K, T: T) => R; | ||
declare type BoxedCall<T extends any[], K> = (state: object, ...rest: T) => K; | ||
/** | ||
* Prepends a single function with an additional argument, which would be used as a "box" key layer. | ||
* Literally "puts function in a box" | ||
* | ||
* @param {Function} fn - function to "box" | ||
* | ||
* @see https://github.com/theKashey/kashe#boxed | ||
* @see {@link inboxed} - for nested caches. | ||
* | ||
* @example | ||
* const addTwo = (a,b) => a+b; // could not be "kashe" memoized | ||
* const bAddTwo = boxed(addTwo); // "box" it | ||
* const cacheKey = {}; // any object | ||
* // π not function takes 3 arguments | ||
* bAddTwo(cacheKey, 1, 2) === bAddTwo(cacheKey, 1, 2) === 3 | ||
* // result is "stored in a first argument" - using another key equivalent to cache clear. | ||
* bAddTwo(otherCacheKey, 1, 2) // -> a new call | ||
*/ | ||
export declare function boxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Prepends with additional cache-key, which will be used for any other {@link kashe} call made inside. | ||
* inboxed scopes all the nested caches behind a first argument, creating a "sub cache". | ||
* | ||
* inboxed is about __isolation__. | ||
* | ||
* @param {Function} fn function to "box" | ||
* | ||
* @see {@link boxed} for non-nested caches. | ||
* @see https://github.com/theKashey/kashe#inboxed | ||
* @example | ||
* const kashedSelector = kashe((state) => ({state, counter: counter++})); // returns unique object every all | ||
* const inboxedSelector = inboxed(kashedSelector); | ||
* | ||
* β kashedSelector(state) === kashedSelector(state) | ||
* const cacheKey = {}; // any object | ||
* π inboxedSelector(cacheKey, state) === inboxedSelector(cacheKey, state) | ||
* β inboxedSelector({}, state) !== inboxedSelector({}, state) | ||
*/ | ||
export declare function inboxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Creates a clone of a kash-ed function with another internal cache. | ||
* Useful for isolation one kashe call from another | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for all internal cache calls | ||
* | ||
* @see {@link inboxed} | ||
* @see https://github.com/theKashey/kashe#fork | ||
*/ | ||
export declare function fork<T extends any[], K>(fn: (...args: T) => K, options?: { | ||
@@ -11,0 +87,0 @@ singleton?: boolean; |
@@ -34,2 +34,5 @@ import functionDouble from "function-double"; | ||
if (cacheCreator === void 0) { cacheCreator = createWeakStorage; } | ||
/** | ||
* memoizes a function | ||
*/ | ||
return function kashe(func, cache) { | ||
@@ -49,7 +52,38 @@ if (cache === void 0) { cache = cacheCreator(); } | ||
} | ||
return localCache.set(usedArgs, func.apply(void 0, args)); | ||
return localCache.set(usedArgs, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
}, func, { name: addKashePrefix }); | ||
}; | ||
} | ||
/** | ||
* weak memoization helper. | ||
* Uses the __first__ given argument to store result. | ||
* | ||
* `kache`'s API is equal to any other single-line memoization library except the requirement for | ||
* the first argument to be an object. | ||
* | ||
* π‘ hint: sometimes it worth to move some arguments, put pick the "best one" to be the first | ||
* | ||
* @param {Object} argument0 - first argument has to be {object}, {array} or {function} | ||
* @param argument1 - any other, as well we any number or arguments | ||
* | ||
* @see https://github.com/theKashey/kashe#kashe | ||
* @example | ||
* // create a selector, which returns a new array using `array.filter` every time | ||
* const badSelector = (array) => array.filter(somehow) | ||
* // make it return the same object for the same array called. | ||
* const goodSelector = kashe(badSelector); | ||
*/ | ||
export var kashe = weakMemoizeCreator(createWeakStorage); | ||
/** | ||
* a special version of {@link kashe} which does not strictly checks arg1+. | ||
* Could be used to bypass equality check, however use with caution | ||
* | ||
* @see https://github.com/theKashey/kashe#weakkashe | ||
* @example | ||
* const weakMap = weakKashe((data, iterator, ...deps) => data.map(iterator)); | ||
* const derived = weakMap(data, line => ({...line, somethingElse}), localVariable1); | ||
* // π second argument is changing every time, but as long as it's __String representation__ is the same - result is unchanged. | ||
*/ | ||
export var weakKashe = weakMemoizeCreator(createWeakStorage, function (arg, i) { return i > 0 ? String(arg) : arg; }); | ||
@@ -70,3 +104,5 @@ function weakKasheFactory(func, indexId) { | ||
} | ||
return localCache.set(cacheArg, func.apply(void 0, args)); | ||
return localCache.set(cacheArg, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
}; | ||
@@ -77,2 +113,20 @@ } | ||
} | ||
/** | ||
* Prepends a single function with an additional argument, which would be used as a "box" key layer. | ||
* Literally "puts function in a box" | ||
* | ||
* @param {Function} fn - function to "box" | ||
* | ||
* @see https://github.com/theKashey/kashe#boxed | ||
* @see {@link inboxed} - for nested caches. | ||
* | ||
* @example | ||
* const addTwo = (a,b) => a+b; // could not be "kashe" memoized | ||
* const bAddTwo = boxed(addTwo); // "box" it | ||
* const cacheKey = {}; // any object | ||
* // π not function takes 3 arguments | ||
* bAddTwo(cacheKey, 1, 2) === bAddTwo(cacheKey, 1, 2) === 3 | ||
* // result is "stored in a first argument" - using another key equivalent to cache clear. | ||
* bAddTwo(otherCacheKey, 1, 2) // -> a new call | ||
*/ | ||
export function boxed(fn) { | ||
@@ -88,2 +142,21 @@ return kashe(function (_) { | ||
var localCacheCreator = kashe(function (_) { return createWeakStorage(); }); | ||
/** | ||
* Prepends with additional cache-key, which will be used for any other {@link kashe} call made inside. | ||
* inboxed scopes all the nested caches behind a first argument, creating a "sub cache". | ||
* | ||
* inboxed is about __isolation__. | ||
* | ||
* @param {Function} fn function to "box" | ||
* | ||
* @see {@link boxed} for non-nested caches. | ||
* @see https://github.com/theKashey/kashe#inboxed | ||
* @example | ||
* const kashedSelector = kashe((state) => ({state, counter: counter++})); // returns unique object every all | ||
* const inboxedSelector = inboxed(kashedSelector); | ||
* | ||
* β kashedSelector(state) === kashedSelector(state) | ||
* const cacheKey = {}; // any object | ||
* π inboxedSelector(cacheKey, state) === inboxedSelector(cacheKey, state) | ||
* β inboxedSelector({}, state) !== inboxedSelector({}, state) | ||
*/ | ||
export function inboxed(fn) { | ||
@@ -114,2 +187,12 @@ var factory = weakKasheFactory(function (cacheVariation) { | ||
} | ||
/** | ||
* Creates a clone of a kash-ed function with another internal cache. | ||
* Useful for isolation one kashe call from another | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for all internal cache calls | ||
* | ||
* @see {@link inboxed} | ||
* @see https://github.com/theKashey/kashe#fork | ||
*/ | ||
export function fork(fn, options) { | ||
@@ -116,0 +199,0 @@ var cache = localCacheCreator({}); |
@@ -15,8 +15,8 @@ "use strict"; | ||
reads++; | ||
var test_1 = storage.get(args[i]); | ||
if (test_1) { | ||
if (test_1.arguments.length === max && | ||
test_1.arguments.every(function (v, index) { return v === args[index]; })) { | ||
var test = storage.get(args[i]); | ||
if (test) { | ||
if (test.arguments.length === max && | ||
test.arguments.every(function (v, index) { return v === args[index]; })) { | ||
return { | ||
value: test_1.storedValue, | ||
value: test.storedValue, | ||
index: i, | ||
@@ -23,0 +23,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isWeakable = function (value) { return (value && (typeof value === 'object')); }; | ||
exports.isWeakable = function (value) { return (value && (typeof value === 'object') | ||
// || typeof value === 'function' // not using function to prevent leaks | ||
); }; |
import { WeakStorage } from "./types"; | ||
declare type WeakStorageCreator = () => WeakStorage; | ||
export declare function weakMemoizeCreator(cacheCreator?: WeakStorageCreator, mapper?: (x: any, index: number) => any): <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
/** | ||
* weak memoization helper. | ||
* Uses the __first__ given argument to store result. | ||
* | ||
* `kache`'s API is equal to any other single-line memoization library except the requirement for | ||
* the first argument to be an object. | ||
* | ||
* π‘ hint: sometimes it worth to move some arguments, put pick the "best one" to be the first | ||
* | ||
* @param {Object} argument0 - first argument has to be {object}, {array} or {function} | ||
* @param argument1 - any other, as well we any number or arguments | ||
* | ||
* @see https://github.com/theKashey/kashe#kashe | ||
* @example | ||
* // create a selector, which returns a new array using `array.filter` every time | ||
* const badSelector = (array) => array.filter(somehow) | ||
* // make it return the same object for the same array called. | ||
* const goodSelector = kashe(badSelector); | ||
*/ | ||
export declare const kashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
/** | ||
* a special version of {@link kashe} which does not strictly checks arg1+. | ||
* Could be used to bypass equality check, however use with caution | ||
* | ||
* @see https://github.com/theKashey/kashe#weakkashe | ||
* @example | ||
* const weakMap = weakKashe((data, iterator, ...deps) => data.map(iterator)); | ||
* const derived = weakMap(data, line => ({...line, somethingElse}), localVariable1); | ||
* // π second argument is changing every time, but as long as it's __String representation__ is the same - result is unchanged. | ||
*/ | ||
export declare const weakKashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
export declare function swap<T, K, R>(fn: (t: T, k: K) => R): (k: K, T: T) => R; | ||
declare type BoxedCall<T extends any[], K> = (state: object, ...rest: T) => K; | ||
/** | ||
* Prepends a single function with an additional argument, which would be used as a "box" key layer. | ||
* Literally "puts function in a box" | ||
* | ||
* @param {Function} fn - function to "box" | ||
* | ||
* @see https://github.com/theKashey/kashe#boxed | ||
* @see {@link inboxed} - for nested caches. | ||
* | ||
* @example | ||
* const addTwo = (a,b) => a+b; // could not be "kashe" memoized | ||
* const bAddTwo = boxed(addTwo); // "box" it | ||
* const cacheKey = {}; // any object | ||
* // π not function takes 3 arguments | ||
* bAddTwo(cacheKey, 1, 2) === bAddTwo(cacheKey, 1, 2) === 3 | ||
* // result is "stored in a first argument" - using another key equivalent to cache clear. | ||
* bAddTwo(otherCacheKey, 1, 2) // -> a new call | ||
*/ | ||
export declare function boxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Prepends with additional cache-key, which will be used for any other {@link kashe} call made inside. | ||
* inboxed scopes all the nested caches behind a first argument, creating a "sub cache". | ||
* | ||
* inboxed is about __isolation__. | ||
* | ||
* @param {Function} fn function to "box" | ||
* | ||
* @see {@link boxed} for non-nested caches. | ||
* @see https://github.com/theKashey/kashe#inboxed | ||
* @example | ||
* const kashedSelector = kashe((state) => ({state, counter: counter++})); // returns unique object every all | ||
* const inboxedSelector = inboxed(kashedSelector); | ||
* | ||
* β kashedSelector(state) === kashedSelector(state) | ||
* const cacheKey = {}; // any object | ||
* π inboxedSelector(cacheKey, state) === inboxedSelector(cacheKey, state) | ||
* β inboxedSelector({}, state) !== inboxedSelector({}, state) | ||
*/ | ||
export declare function inboxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Creates a clone of a kash-ed function with another internal cache. | ||
* Useful for isolation one kashe call from another | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for all internal cache calls | ||
* | ||
* @see {@link inboxed} | ||
* @see https://github.com/theKashey/kashe#fork | ||
*/ | ||
export declare function fork<T extends any[], K>(fn: (...args: T) => K, options?: { | ||
@@ -11,0 +87,0 @@ singleton?: boolean; |
@@ -36,2 +36,5 @@ "use strict"; | ||
if (cacheCreator === void 0) { cacheCreator = weakStorage_1.createWeakStorage; } | ||
/** | ||
* memoizes a function | ||
*/ | ||
return function kashe(func, cache) { | ||
@@ -51,3 +54,5 @@ if (cache === void 0) { cache = cacheCreator(); } | ||
} | ||
return localCache.set(usedArgs, func.apply(void 0, args)); | ||
return localCache.set(usedArgs, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
}, func, { name: addKashePrefix }); | ||
@@ -57,3 +62,32 @@ }; | ||
exports.weakMemoizeCreator = weakMemoizeCreator; | ||
/** | ||
* weak memoization helper. | ||
* Uses the __first__ given argument to store result. | ||
* | ||
* `kache`'s API is equal to any other single-line memoization library except the requirement for | ||
* the first argument to be an object. | ||
* | ||
* π‘ hint: sometimes it worth to move some arguments, put pick the "best one" to be the first | ||
* | ||
* @param {Object} argument0 - first argument has to be {object}, {array} or {function} | ||
* @param argument1 - any other, as well we any number or arguments | ||
* | ||
* @see https://github.com/theKashey/kashe#kashe | ||
* @example | ||
* // create a selector, which returns a new array using `array.filter` every time | ||
* const badSelector = (array) => array.filter(somehow) | ||
* // make it return the same object for the same array called. | ||
* const goodSelector = kashe(badSelector); | ||
*/ | ||
exports.kashe = weakMemoizeCreator(weakStorage_1.createWeakStorage); | ||
/** | ||
* a special version of {@link kashe} which does not strictly checks arg1+. | ||
* Could be used to bypass equality check, however use with caution | ||
* | ||
* @see https://github.com/theKashey/kashe#weakkashe | ||
* @example | ||
* const weakMap = weakKashe((data, iterator, ...deps) => data.map(iterator)); | ||
* const derived = weakMap(data, line => ({...line, somethingElse}), localVariable1); | ||
* // π second argument is changing every time, but as long as it's __String representation__ is the same - result is unchanged. | ||
*/ | ||
exports.weakKashe = weakMemoizeCreator(weakStorage_1.createWeakStorage, function (arg, i) { return i > 0 ? String(arg) : arg; }); | ||
@@ -74,3 +108,5 @@ function weakKasheFactory(func, indexId) { | ||
} | ||
return localCache.set(cacheArg, func.apply(void 0, args)); | ||
return localCache.set(cacheArg, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
}; | ||
@@ -82,2 +118,20 @@ } | ||
exports.swap = swap; | ||
/** | ||
* Prepends a single function with an additional argument, which would be used as a "box" key layer. | ||
* Literally "puts function in a box" | ||
* | ||
* @param {Function} fn - function to "box" | ||
* | ||
* @see https://github.com/theKashey/kashe#boxed | ||
* @see {@link inboxed} - for nested caches. | ||
* | ||
* @example | ||
* const addTwo = (a,b) => a+b; // could not be "kashe" memoized | ||
* const bAddTwo = boxed(addTwo); // "box" it | ||
* const cacheKey = {}; // any object | ||
* // π not function takes 3 arguments | ||
* bAddTwo(cacheKey, 1, 2) === bAddTwo(cacheKey, 1, 2) === 3 | ||
* // result is "stored in a first argument" - using another key equivalent to cache clear. | ||
* bAddTwo(otherCacheKey, 1, 2) // -> a new call | ||
*/ | ||
function boxed(fn) { | ||
@@ -94,2 +148,21 @@ return exports.kashe(function (_) { | ||
var localCacheCreator = exports.kashe(function (_) { return weakStorage_1.createWeakStorage(); }); | ||
/** | ||
* Prepends with additional cache-key, which will be used for any other {@link kashe} call made inside. | ||
* inboxed scopes all the nested caches behind a first argument, creating a "sub cache". | ||
* | ||
* inboxed is about __isolation__. | ||
* | ||
* @param {Function} fn function to "box" | ||
* | ||
* @see {@link boxed} for non-nested caches. | ||
* @see https://github.com/theKashey/kashe#inboxed | ||
* @example | ||
* const kashedSelector = kashe((state) => ({state, counter: counter++})); // returns unique object every all | ||
* const inboxedSelector = inboxed(kashedSelector); | ||
* | ||
* β kashedSelector(state) === kashedSelector(state) | ||
* const cacheKey = {}; // any object | ||
* π inboxedSelector(cacheKey, state) === inboxedSelector(cacheKey, state) | ||
* β inboxedSelector({}, state) !== inboxedSelector({}, state) | ||
*/ | ||
function inboxed(fn) { | ||
@@ -121,2 +194,12 @@ var factory = weakKasheFactory(function (cacheVariation) { | ||
exports.inboxed = inboxed; | ||
/** | ||
* Creates a clone of a kash-ed function with another internal cache. | ||
* Useful for isolation one kashe call from another | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for all internal cache calls | ||
* | ||
* @see {@link inboxed} | ||
* @see https://github.com/theKashey/kashe#fork | ||
*/ | ||
function fork(fn, options) { | ||
@@ -123,0 +206,0 @@ var cache = localCacheCreator({}); |
{ | ||
"name": "kashe", | ||
"version": "1.0.1", | ||
"description": "Stateless memoization replacement for reselect and memoize-one", | ||
"version": "1.0.2", | ||
"description": "Stateless weak memoization replacement for reselect and memoize-one", | ||
"main": "dist/es5/index.js", | ||
@@ -25,3 +25,3 @@ "scripts": { | ||
"ts-jest": "^24.0.0", | ||
"ts-react-toolbox": "^0.2.2", | ||
"ts-react-toolbox": "^0.2.20", | ||
"typescript": "^3.3.3333" | ||
@@ -46,6 +46,2 @@ }, | ||
], | ||
"resolutions": { | ||
"typescript": "^3.0.0", | ||
"ts-react-toolbox/typescript": "^3.0.0" | ||
}, | ||
"dependencies": { | ||
@@ -52,0 +48,0 @@ "function-double": "^1.0.4", |
@@ -37,3 +37,3 @@ <div align="center"> | ||
# API | ||
- kashe/weaKashe - memoization | ||
- kashe/weakKashe - memoization | ||
- box - prefixed memoization | ||
@@ -77,3 +77,3 @@ - inbox - nested prefixed memoization | ||
- `boxed(function(...args)=>T):(_, ...args)=>T` - "prefixes" a call to function with "weakmappable" argument. __All arguments__ shall be equal to return a cached result. | ||
Use `boxed` to make any function kashe-memoizable, but adding a leading argument. | ||
Use `boxed` to make any function kashe-memoizable, buy adding a leading argument. | ||
```js | ||
@@ -95,3 +95,3 @@ import {boxed} from 'kashe'; | ||
- `inboxed(function(...args)=>T):(_, ...args)=>T` - "nest" a call to a function with "weakmappable" argument. | ||
Use `inboxed` to make any function kashe-memoizable, but adding a leading argument. | ||
Use `inboxed` to make any function kashe-memoizable, buy adding a leading argument. | ||
@@ -98,0 +98,0 @@ > Diffence from `boxed` - `inboxed` "nests" all the cache below it. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
52674
935