Comparing version 0.2.0 to 1.0.0
@@ -1,2 +0,2 @@ | ||
import { kashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, boxed, inboxed, fork, }; | ||
import { kashe, weakKashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, weakKashe, boxed, inboxed, fork, }; |
@@ -1,2 +0,2 @@ | ||
import { kashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, boxed, inboxed, fork, }; | ||
import { kashe, weakKashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, weakKashe, boxed, inboxed, fork, }; |
@@ -1,3 +0,1 @@ | ||
export var isWeakable = function (value) { return (value && (typeof value === 'object') | ||
// || typeof value === 'function' // not using function to prevent leaks | ||
); }; | ||
export var isWeakable = function (value) { return (value && (typeof value === 'object')); }; |
import { WeakStorage } from "./types"; | ||
declare type WeakStorageCreator = () => WeakStorage; | ||
export declare function weakMemoizeCreator(cacheCreator?: WeakStorageCreator): <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
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; | ||
export declare const kashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
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 function with an additional argument, which would be used as a "box" key layer | ||
* @param fn | ||
*/ | ||
export declare function boxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Prepends function with an additional argument, which would be used as "cache-dimension" key later | ||
* @param fn | ||
*/ | ||
export declare function inboxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Forks internal cache, creating another cache dimension | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for an internal cache | ||
*/ | ||
export declare function fork<T extends any[], K>(fn: (...args: T) => K, options?: { | ||
@@ -24,0 +11,0 @@ singleton?: boolean; |
@@ -10,3 +10,9 @@ import functionDouble from "function-double"; | ||
var popCache = function (cache) { | ||
if (cache !== cacheStack.pop()) { | ||
var popped = cacheStack.pop(); | ||
if (cache !== popped) { | ||
console.error({ | ||
expected: cache, | ||
given: popped, | ||
stack: cacheStack, | ||
}); | ||
throw new Error('kashe synchronization failed'); | ||
@@ -27,7 +33,4 @@ } | ||
}; | ||
export function weakMemoizeCreator(cacheCreator) { | ||
export function weakMemoizeCreator(cacheCreator, mapper) { | ||
if (cacheCreator === void 0) { cacheCreator = createWeakStorage; } | ||
/** | ||
* memoizes a function | ||
*/ | ||
return function kashe(func, cache) { | ||
@@ -42,9 +45,8 @@ if (cache === void 0) { cache = cacheCreator(); } | ||
var localCache = getCacheFor(_this_, cacheCreator) || cache; | ||
var test = localCache.get(args); | ||
var usedArgs = mapper ? args.map(mapper) : args; | ||
var test = localCache.get(usedArgs); | ||
if (test) { | ||
return test.value; | ||
} | ||
return localCache.set(args, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
return localCache.set(usedArgs, func.apply(void 0, args)); | ||
}, func, { name: addKashePrefix }); | ||
@@ -54,2 +56,3 @@ }; | ||
export var kashe = weakMemoizeCreator(createWeakStorage); | ||
export var weakKashe = weakMemoizeCreator(createWeakStorage, function (arg, i) { return i > 0 ? String(arg) : arg; }); | ||
function weakKasheFactory(func, indexId) { | ||
@@ -69,5 +72,3 @@ if (indexId === void 0) { indexId = 0; } | ||
} | ||
return localCache.set(cacheArg, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
return localCache.set(cacheArg, func.apply(void 0, args)); | ||
}; | ||
@@ -78,6 +79,2 @@ } | ||
} | ||
/** | ||
* Prepends function with an additional argument, which would be used as a "box" key layer | ||
* @param fn | ||
*/ | ||
export function boxed(fn) { | ||
@@ -93,6 +90,2 @@ return kashe(function (_) { | ||
var localCacheCreator = kashe(function (_) { return createWeakStorage(); }); | ||
/** | ||
* Prepends function with an additional argument, which would be used as "cache-dimension" key later | ||
* @param fn | ||
*/ | ||
export function inboxed(fn) { | ||
@@ -123,8 +116,2 @@ var factory = weakKasheFactory(function (cacheVariation) { | ||
} | ||
/** | ||
* Forks internal cache, creating another cache dimension | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for an internal cache | ||
*/ | ||
export function fork(fn, options) { | ||
@@ -138,10 +125,11 @@ var cache = localCacheCreator({}); | ||
} | ||
var cacheOverride = ((!options || !options.singleton) ? getCacheFor(cache, genLocalCache) : null) || cache; | ||
try { | ||
pushCache((!options || !options.singleton && getCacheFor(cache, genLocalCache)) || cache); | ||
pushCache(cacheOverride); | ||
return fn.apply(void 0, rest); | ||
} | ||
finally { | ||
popCache(cache); | ||
popCache(cacheOverride); | ||
} | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { kashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, boxed, inboxed, fork, }; | ||
import { kashe, weakKashe, boxed, inboxed, fork } from "./weak"; | ||
export { kashe, weakKashe, boxed, inboxed, fork, }; |
@@ -5,4 +5,5 @@ "use strict"; | ||
exports.kashe = weak_1.kashe; | ||
exports.weakKashe = weak_1.weakKashe; | ||
exports.boxed = weak_1.boxed; | ||
exports.inboxed = weak_1.inboxed; | ||
exports.fork = weak_1.fork; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isWeakable = function (value) { return (value && (typeof value === 'object') | ||
// || typeof value === 'function' // not using function to prevent leaks | ||
); }; | ||
exports.isWeakable = function (value) { return (value && (typeof value === 'object')); }; |
import { WeakStorage } from "./types"; | ||
declare type WeakStorageCreator = () => WeakStorage; | ||
export declare function weakMemoizeCreator(cacheCreator?: WeakStorageCreator): <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
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; | ||
export declare const kashe: <Arg extends object, T extends any[], Return>(func: (x: Arg, ...rest: T) => Return, cache?: WeakStorage) => (x: Arg, ...rest: T) => Return; | ||
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 function with an additional argument, which would be used as a "box" key layer | ||
* @param fn | ||
*/ | ||
export declare function boxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Prepends function with an additional argument, which would be used as "cache-dimension" key later | ||
* @param fn | ||
*/ | ||
export declare function inboxed<T extends any[], K>(fn: (...args: T) => K): BoxedCall<T, K>; | ||
/** | ||
* Forks internal cache, creating another cache dimension | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for an internal cache | ||
*/ | ||
export declare function fork<T extends any[], K>(fn: (...args: T) => K, options?: { | ||
@@ -24,0 +11,0 @@ singleton?: boolean; |
@@ -12,3 +12,9 @@ "use strict"; | ||
var popCache = function (cache) { | ||
if (cache !== cacheStack.pop()) { | ||
var popped = cacheStack.pop(); | ||
if (cache !== popped) { | ||
console.error({ | ||
expected: cache, | ||
given: popped, | ||
stack: cacheStack, | ||
}); | ||
throw new Error('kashe synchronization failed'); | ||
@@ -29,7 +35,4 @@ } | ||
}; | ||
function weakMemoizeCreator(cacheCreator) { | ||
function weakMemoizeCreator(cacheCreator, mapper) { | ||
if (cacheCreator === void 0) { cacheCreator = weakStorage_1.createWeakStorage; } | ||
/** | ||
* memoizes a function | ||
*/ | ||
return function kashe(func, cache) { | ||
@@ -44,9 +47,8 @@ if (cache === void 0) { cache = cacheCreator(); } | ||
var localCache = getCacheFor(_this_, cacheCreator) || cache; | ||
var test = localCache.get(args); | ||
var usedArgs = mapper ? args.map(mapper) : args; | ||
var test = localCache.get(usedArgs); | ||
if (test) { | ||
return test.value; | ||
} | ||
return localCache.set(args, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
return localCache.set(usedArgs, func.apply(void 0, args)); | ||
}, func, { name: addKashePrefix }); | ||
@@ -57,2 +59,3 @@ }; | ||
exports.kashe = weakMemoizeCreator(weakStorage_1.createWeakStorage); | ||
exports.weakKashe = weakMemoizeCreator(weakStorage_1.createWeakStorage, function (arg, i) { return i > 0 ? String(arg) : arg; }); | ||
function weakKasheFactory(func, indexId) { | ||
@@ -72,5 +75,3 @@ if (indexId === void 0) { indexId = 0; } | ||
} | ||
return localCache.set(cacheArg, | ||
// @ts-ignore | ||
func.apply(void 0, args)); | ||
return localCache.set(cacheArg, func.apply(void 0, args)); | ||
}; | ||
@@ -82,6 +83,2 @@ } | ||
exports.swap = swap; | ||
/** | ||
* Prepends function with an additional argument, which would be used as a "box" key layer | ||
* @param fn | ||
*/ | ||
function boxed(fn) { | ||
@@ -98,6 +95,2 @@ return exports.kashe(function (_) { | ||
var localCacheCreator = exports.kashe(function (_) { return weakStorage_1.createWeakStorage(); }); | ||
/** | ||
* Prepends function with an additional argument, which would be used as "cache-dimension" key later | ||
* @param fn | ||
*/ | ||
function inboxed(fn) { | ||
@@ -129,8 +122,2 @@ var factory = weakKasheFactory(function (cacheVariation) { | ||
exports.inboxed = inboxed; | ||
/** | ||
* Forks internal cache, creating another cache dimension | ||
* @param fn - function to memoize | ||
* @param [options] | ||
* @param [options.singleton=false] force single variant for an internal cache | ||
*/ | ||
function fork(fn, options) { | ||
@@ -144,8 +131,9 @@ var cache = localCacheCreator({}); | ||
} | ||
var cacheOverride = ((!options || !options.singleton) ? getCacheFor(cache, genLocalCache) : null) || cache; | ||
try { | ||
pushCache((!options || !options.singleton && getCacheFor(cache, genLocalCache)) || cache); | ||
pushCache(cacheOverride); | ||
return fn.apply(void 0, rest); | ||
} | ||
finally { | ||
popCache(cache); | ||
popCache(cacheOverride); | ||
} | ||
@@ -152,0 +140,0 @@ }; |
{ | ||
"name": "kashe", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "Stateless memoization replacement for reselect and memoize-one", | ||
@@ -5,0 +5,0 @@ "main": "dist/es5/index.js", |
@@ -37,3 +37,3 @@ <div align="center"> | ||
# API | ||
- kashe - memoization | ||
- kashe/weaKashe - memoization | ||
- box - prefixed memoization | ||
@@ -60,3 +60,17 @@ - inbox - nested prefixed memoization | ||
``` | ||
### weakKashe | ||
For the cases like selectors and mappers some times it's easier to use __not strict__ cache. | ||
```js | ||
const {weakKashe} from 'kashe'; | ||
const weakMap = weakKashe((data, iterator, ...deps) => data.map(iterator)); | ||
const derived = weakMap(data, line => ({...line, somethingElse}), localVariable1); | ||
``` | ||
In this case: | ||
- cache would be stored in the `data` | ||
- arguments would be matched not by "strict" equality, but by the "toString" equality. | ||
- as a result, the second `kashe` argument, always the new function, would not _destroy_ cache | ||
- keep in mind - this is not 100% safe operation. Consider adding _local scope_ variables to control cache precision. | ||
### boxed | ||
@@ -63,0 +77,0 @@ - `boxed(function(...args)=>T):(_, ...args)=>T` - "prefixes" a call to function with "weakmappable" argument. __All arguments__ shall be equal to return a cached result. |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1
330
38758
607