Comparing version 1.0.4 to 1.1.0
export interface WeakResult { | ||
value: any; | ||
index: number; | ||
} | ||
@@ -9,5 +8,5 @@ export interface WeakStorage { | ||
} | ||
export interface WeakMappable { | ||
get(key: any): any | undefined; | ||
set(set: any, value: any): void; | ||
export interface WeakMappable<T = any> { | ||
get(key: any): T | undefined; | ||
set(set: any, value: T): void; | ||
} |
import { WeakMappable, WeakStorage } from "./types"; | ||
export declare const createWeakStorage: (indexId?: number, storage?: WeakMappable) => WeakStorage; | ||
export declare const breakdownArgs: (args: any[]) => any[]; | ||
declare type Test = { | ||
arguments?: any[]; | ||
storedValue?: any; | ||
storage?: WeakMappable<Test>; | ||
}; | ||
export declare const createWeakStorage: (storage?: WeakMappable<Test>) => WeakStorage; | ||
export {}; |
import { isWeakable } from "./utils"; | ||
export var createWeakStorage = function (indexId, storage) { | ||
if (indexId === void 0) { indexId = 0; } | ||
export var breakdownArgs = function (args) { | ||
var saveSlice = []; | ||
for (var i = 0; i < args.length; i++) { | ||
if (isWeakable(args[i])) { | ||
saveSlice.push(args[i]); | ||
} | ||
} | ||
return saveSlice; | ||
}; | ||
var testArgs = function (test, args) { | ||
var a = test.arguments; | ||
if (!a) { | ||
return undefined; | ||
} | ||
if (a.length === args.length) { | ||
for (var i = 0; i < a.length; ++i) { | ||
if (a[i] !== args[i]) { | ||
return undefined; | ||
} | ||
} | ||
return test; | ||
} | ||
return undefined; | ||
}; | ||
export var createWeakStorage = function (storage) { | ||
if (storage === void 0) { storage = new WeakMap(); } | ||
return ({ | ||
get: function (args) { | ||
if (!isWeakable(args[indexId])) { | ||
console.log('arguments given', args); | ||
throw new Error("Argument #" + indexId + " expected to be weak-mappable object, " + typeof args[indexId] + " given"); | ||
var slices = breakdownArgs(args); | ||
if (!slices.length) { | ||
throw new Error("No weak-mappable (object, function, symbol) arguments found."); | ||
} | ||
var test = storage.get(args[indexId]); | ||
var readFrom = storage; | ||
console.log('get breakdown', slices); | ||
for (var i = 0; i < slices.length; ++i) { | ||
var test_1 = readFrom.get(slices[i]); | ||
if (!test_1 || !test_1.storage) { | ||
console.log('get: no forward'); | ||
return undefined; | ||
} | ||
readFrom = test_1.storage; | ||
} | ||
if (!readFrom) { | ||
return undefined; | ||
} | ||
var test = readFrom.get(slices[0]); | ||
if (test) { | ||
var a = test.arguments; | ||
if (a.length === args.length) { | ||
for (var i = 0; i < a.length; ++i) { | ||
if (a[i] !== args[i]) { | ||
return undefined; | ||
} | ||
} | ||
var storedValue = testArgs(test, args); | ||
if (storedValue) { | ||
return { | ||
value: test.storedValue, | ||
index: indexId, | ||
}; | ||
} | ||
else { | ||
console.log('get: arg mismatch'); | ||
} | ||
} | ||
else { | ||
console.log('get: no key'); | ||
} | ||
return undefined; | ||
}, | ||
set: function (args, value) { | ||
storage.set(args[indexId], { | ||
var slices = breakdownArgs(args); | ||
console.log('set breakdown', slices); | ||
var writeTo = storage; | ||
for (var i = 0; i < slices.length; ++i) { | ||
var next = writeTo.get(slices[i]); | ||
if (!next || !next.storage) { | ||
next = { | ||
storage: new WeakMap() | ||
}; | ||
writeTo.set(slices[i], next); | ||
} | ||
writeTo = next.storage; | ||
} | ||
writeTo.set(slices[0], { | ||
storedValue: value, | ||
arguments: args, | ||
storage: undefined | ||
}); | ||
@@ -33,0 +83,0 @@ return value; |
export interface WeakResult { | ||
value: any; | ||
index: number; | ||
} | ||
@@ -9,5 +8,5 @@ export interface WeakStorage { | ||
} | ||
export interface WeakMappable { | ||
get(key: any): any | undefined; | ||
set(set: any, value: any): void; | ||
export interface WeakMappable<T = any> { | ||
get(key: any): T | undefined; | ||
set(set: any, value: T): void; | ||
} |
import { WeakMappable, WeakStorage } from "./types"; | ||
export declare const createWeakStorage: (indexId?: number, storage?: WeakMappable) => WeakStorage; | ||
export declare const breakdownArgs: (args: any[]) => any[]; | ||
declare type Test = { | ||
arguments?: any[]; | ||
storedValue?: any; | ||
storage?: WeakMappable<Test>; | ||
}; | ||
export declare const createWeakStorage: (storage?: WeakMappable<Test>) => WeakStorage; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createWeakStorage = void 0; | ||
exports.createWeakStorage = exports.breakdownArgs = void 0; | ||
var utils_1 = require("./utils"); | ||
exports.createWeakStorage = function (indexId, storage) { | ||
if (indexId === void 0) { indexId = 0; } | ||
exports.breakdownArgs = function (args) { | ||
var saveSlice = []; | ||
for (var i = 0; i < args.length; i++) { | ||
if (utils_1.isWeakable(args[i])) { | ||
saveSlice.push(args[i]); | ||
} | ||
} | ||
return saveSlice; | ||
}; | ||
var testArgs = function (test, args) { | ||
var a = test.arguments; | ||
if (!a) { | ||
return undefined; | ||
} | ||
if (a.length === args.length) { | ||
for (var i = 0; i < a.length; ++i) { | ||
if (a[i] !== args[i]) { | ||
return undefined; | ||
} | ||
} | ||
return test; | ||
} | ||
return undefined; | ||
}; | ||
exports.createWeakStorage = function (storage) { | ||
if (storage === void 0) { storage = new WeakMap(); } | ||
return ({ | ||
get: function (args) { | ||
if (!utils_1.isWeakable(args[indexId])) { | ||
console.log('arguments given', args); | ||
throw new Error("Argument #" + indexId + " expected to be weak-mappable object, " + typeof args[indexId] + " given"); | ||
var slices = exports.breakdownArgs(args); | ||
if (!slices.length) { | ||
throw new Error("No weak-mappable (object, function, symbol) arguments found."); | ||
} | ||
var test = storage.get(args[indexId]); | ||
var readFrom = storage; | ||
console.log('get breakdown', slices); | ||
for (var i = 0; i < slices.length; ++i) { | ||
var test_1 = readFrom.get(slices[i]); | ||
if (!test_1 || !test_1.storage) { | ||
console.log('get: no forward'); | ||
return undefined; | ||
} | ||
readFrom = test_1.storage; | ||
} | ||
if (!readFrom) { | ||
return undefined; | ||
} | ||
var test = readFrom.get(slices[0]); | ||
if (test) { | ||
var a = test.arguments; | ||
if (a.length === args.length) { | ||
for (var i = 0; i < a.length; ++i) { | ||
if (a[i] !== args[i]) { | ||
return undefined; | ||
} | ||
} | ||
var storedValue = testArgs(test, args); | ||
if (storedValue) { | ||
return { | ||
value: test.storedValue, | ||
index: indexId, | ||
}; | ||
} | ||
else { | ||
console.log('get: arg mismatch'); | ||
} | ||
} | ||
else { | ||
console.log('get: no key'); | ||
} | ||
return undefined; | ||
}, | ||
set: function (args, value) { | ||
storage.set(args[indexId], { | ||
var slices = exports.breakdownArgs(args); | ||
console.log('set breakdown', slices); | ||
var writeTo = storage; | ||
for (var i = 0; i < slices.length; ++i) { | ||
var next = writeTo.get(slices[i]); | ||
if (!next || !next.storage) { | ||
next = { | ||
storage: new WeakMap() | ||
}; | ||
writeTo.set(slices[i], next); | ||
} | ||
writeTo = next.storage; | ||
} | ||
writeTo.set(slices[0], { | ||
storedValue: value, | ||
arguments: args, | ||
storage: undefined | ||
}); | ||
@@ -36,0 +86,0 @@ return value; |
{ | ||
"name": "kashe", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "Stateless weak memoization replacement for reselect and memoize-one", | ||
@@ -5,0 +5,0 @@ "main": "dist/es5/index.js", |
@@ -26,3 +26,4 @@ <div align="center"> | ||
What about `reselect`, a tool powering up all the `redux` ecosystem? Still - __single cache item__. | ||
What about `reselect`, a tool powering up all the `redux` ecosystem? Still - __single cache item__. | ||
> Reselect 5.0 migrated to `weakMapMemoize` which effectively is a `kashe` | ||
@@ -39,2 +40,3 @@ - __Is it server-side friendly?__ Nope, server handles many requests from many clients, and memoized value is constantly got wiped. | ||
- kashe/weakKashe - memoization | ||
## Supporting API | ||
- box - prefixed memoization | ||
@@ -44,4 +46,4 @@ - inbox - nested prefixed memoization | ||
> TLDR: `kashe` uses passed arguments as a key to an internal WeakMap to store a result. It does not store anything anywhere - | ||
it's always _weak_. __Once argument is gone - data is gone__. | ||
> TLDR: `kashe` uses passed arguments as a key to an internal WeakMap to store a result. It does not store anything permanently - | ||
it's always _weak_. __Once argument used as a key is "gone" - data is "gone"__. | ||
@@ -62,2 +64,6 @@ ### kashe | ||
``` | ||
`kashe` uses nested memoization, creating a cascade of caches for every "weakmappable" argument found. | ||
This greatly increases cache size and hit rate. | ||
### weakKashe | ||
@@ -80,3 +86,7 @@ For the cases like selectors and mappers some times it's easier to use __not strict__ cache. | ||
- `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, buy adding a leading argument. | ||
Use `boxed` to make any function kashe-memoizable, buy adding a leading argument. | ||
__Literally "puts function in a box"__. | ||
> `boxed` effectively creates a "fork" in the cache letting you fine control execution | ||
```js | ||
@@ -100,3 +110,6 @@ import {boxed} from 'kashe'; | ||
> Diffence from `boxed` - `inboxed` "nests" all the cache below it. | ||
> Difference from `boxed` - `inboxed` "nests" all the cache below it. | ||
It creates a micro-universe giving you fine control over caching behavior and purging caches. Think concurrent server environment. | ||
`inboxed` will affect every other `kashe` call inside it. | ||
```js | ||
@@ -159,3 +172,3 @@ import {inboxed} from 'kashe'; | ||
### fork | ||
- `fork(function: T):T` - create a copy of a selector, with overiden internal cache. | ||
- `fork(function: T):T` - create a copy of a selector, with overidden internal cache. | ||
`fork` has the same effect `inbox` has, but not adding a leading argument. First argument still expected to be an object, array, or a function. | ||
@@ -162,0 +175,0 @@ ```js |
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
57607
1051
357