Comparing version 0.7.1 to 0.8.0
export declare class Cache<K = any, V = any> { | ||
private max; | ||
dispose: (value: V, key: K) => void; | ||
private map; | ||
private newest; | ||
private oldest; | ||
private max; | ||
constructor(options?: { | ||
max?: number; | ||
dispose?: (value: V, key: K) => void; | ||
}); | ||
constructor(max?: number, dispose?: (value: V, key: K) => void); | ||
has(key: K): boolean; | ||
@@ -16,3 +14,2 @@ get(key: K): void | V; | ||
delete(key: K): boolean; | ||
dispose(value: V, key: K): void; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function defaultDispose() { } | ||
var Cache = /** @class */ (function () { | ||
function Cache(options) { | ||
if (options === void 0) { options = {}; } | ||
function Cache(max, dispose) { | ||
if (max === void 0) { max = Infinity; } | ||
if (dispose === void 0) { dispose = defaultDispose; } | ||
this.max = max; | ||
this.dispose = dispose; | ||
this.map = new Map(); | ||
this.newest = null; | ||
this.oldest = null; | ||
this.max = Infinity; | ||
if (typeof options.max === "number") { | ||
this.max = options.max; | ||
} | ||
if (typeof options.dispose === "function") { | ||
this.dispose = options.dispose; | ||
} | ||
} | ||
@@ -89,5 +86,5 @@ Cache.prototype.has = function (key) { | ||
}; | ||
Cache.prototype.dispose = function (value, key) { }; | ||
return Cache; | ||
}()); | ||
exports.Cache = Cache; | ||
//# sourceMappingURL=cache.js.map |
import { OptimisticWrapOptions } from "./index"; | ||
declare type FnType = (...args: any[]) => any; | ||
export declare class Entry { | ||
fn: FnType; | ||
key: any; | ||
args: any[]; | ||
export declare type AnyEntry = Entry<any, any, any>; | ||
export declare class Entry<TArgs extends any[], TValue, TKey> { | ||
readonly fn: (...args: TArgs) => TValue; | ||
args: Readonly<TArgs>; | ||
readonly key: TKey; | ||
static count: number; | ||
static POOL_TARGET_SIZE: number; | ||
subscribe: OptimisticWrapOptions["subscribe"]; | ||
subscribe: OptimisticWrapOptions<TArgs>["subscribe"]; | ||
unsubscribe?: () => any; | ||
reportOrphan?: (entry: Entry) => any; | ||
reportOrphan?: (entry: Entry<TArgs, TValue, TKey>) => any; | ||
private parents; | ||
@@ -18,10 +18,7 @@ private childValues; | ||
private value; | ||
constructor(fn: FnType, key: any, args: any[]); | ||
private reset; | ||
static acquire(fn: FnType, key: any, args: any[]): Entry; | ||
recompute(): any; | ||
constructor(fn: (...args: TArgs) => TValue, args: Readonly<TArgs>, key: TKey); | ||
recompute(): TValue; | ||
isOrphan(): boolean; | ||
setDirty(): void; | ||
dispose(): void; | ||
private release; | ||
private rememberParent; | ||
@@ -43,2 +40,1 @@ private recomputeIfDirty; | ||
} | ||
export {}; |
@@ -6,3 +6,2 @@ "use strict"; | ||
var emptySetPool = []; | ||
var entryPool = []; | ||
var reusableEmptyArray = []; | ||
@@ -17,6 +16,6 @@ // Since this package might be used browsers, we should avoid using the | ||
var Entry = /** @class */ (function () { | ||
function Entry(fn, key, args) { | ||
function Entry(fn, args, key) { | ||
this.fn = fn; | ||
this.args = args; | ||
this.key = key; | ||
this.args = args; | ||
this.parents = new Set(); | ||
@@ -30,34 +29,11 @@ this.childValues = new Map(); | ||
this.recomputing = false; | ||
this.value = UNKNOWN_VALUE; | ||
++Entry.count; | ||
} | ||
Entry.prototype.reset = function (fn, key, args) { | ||
this.fn = fn; | ||
this.key = key; | ||
this.args = args; | ||
this.value = UNKNOWN_VALUE; | ||
this.dirty = true; | ||
this.subscribe = void 0; | ||
this.unsubscribe = void 0; | ||
this.recomputing = false; | ||
// Optional callback that will be invoked when entry.parents becomes | ||
// empty. The Entry object is given as the first parameter. If the | ||
// callback returns true, then this entry can be removed from the graph | ||
// and safely recycled into the entryPool. | ||
this.reportOrphan = void 0; | ||
}; | ||
Entry.acquire = function (fn, key, args) { | ||
var entry = entryPool.pop(); | ||
if (entry) { | ||
entry.reset(fn, key, args); | ||
return entry; | ||
} | ||
return new Entry(fn, key, args); | ||
}; | ||
Entry.prototype.recompute = function () { | ||
if (!this.rememberParent() && this.maybeReportOrphan()) { | ||
// The recipient of the entry.reportOrphan callback decided to dispose | ||
// of this orphan entry by calling entry.dispos(), which recycles it | ||
// into the entryPool, so we don't need to (and should not) proceed | ||
// with the recomputation. | ||
return; | ||
// of this orphan entry by calling entry.dispose(), so we don't need to | ||
// (and should not) proceed with the recomputation. | ||
return void 0; | ||
} | ||
@@ -99,15 +75,3 @@ return this.recomputeIfDirty(); | ||
}); | ||
// Since this entry has no parents and no children anymore, and the | ||
// caller of Entry#dispose has indicated that entry.value no longer | ||
// matters, we can safely recycle this Entry object for later use. | ||
this.release(); | ||
}; | ||
Entry.prototype.release = function () { | ||
assert(this.parents.size === 0); | ||
assert(this.childValues.size === 0); | ||
assert(this.dirtyChildren === null); | ||
if (entryPool.length < Entry.POOL_TARGET_SIZE) { | ||
entryPool.push(this); | ||
} | ||
}; | ||
Entry.prototype.rememberParent = function () { | ||
@@ -295,3 +259,3 @@ var local = local_1.get(); | ||
// After we forget all our children, this.dirtyChildren must be empty | ||
// and therefor must have been reset to null. | ||
// and therefore must have been reset to null. | ||
assert(this.dirtyChildren === null); | ||
@@ -336,1 +300,2 @@ return children; | ||
exports.Entry = Entry; | ||
//# sourceMappingURL=entry.js.map |
@@ -1,13 +0,12 @@ | ||
declare type AnyFn = (...args: any[]) => any; | ||
export declare const defaultMakeCacheKey: AnyFn; | ||
export declare type OptimisticWrapperFunction<T extends AnyFn> = T & { | ||
dirty: T; | ||
export declare type TCacheKey = any; | ||
export declare function defaultMakeCacheKey(...args: any[]): any; | ||
export declare type OptimisticWrapperFunction<TArgs extends any[], TResult> = ((...args: TArgs) => TResult) & { | ||
dirty: (...args: TArgs) => void; | ||
}; | ||
export declare type OptimisticWrapOptions = { | ||
export declare type OptimisticWrapOptions<TArgs extends any[]> = { | ||
max?: number; | ||
disposable?: boolean; | ||
makeCacheKey?: AnyFn; | ||
subscribe?: (...args: any[]) => (() => any) | undefined; | ||
makeCacheKey?: (...args: TArgs) => TCacheKey; | ||
subscribe?: (...args: TArgs) => (() => any) | undefined; | ||
}; | ||
export declare function wrap<T extends AnyFn>(originalFunction: T, { max, disposable, makeCacheKey, subscribe, }?: OptimisticWrapOptions): OptimisticWrapperFunction<T>; | ||
export {}; | ||
export declare function wrap<TArgs extends any[], TResult>(originalFunction: (...args: TArgs) => TResult, options?: OptimisticWrapOptions<TArgs>): OptimisticWrapperFunction<TArgs, TResult>; |
@@ -6,13 +6,24 @@ "use strict"; | ||
var local_1 = require("./local"); | ||
// Exported so that custom makeCacheKey functions can easily reuse the | ||
// default implementation (with different arguments). | ||
exports.defaultMakeCacheKey = require("immutable-tuple").tuple; | ||
function wrap(originalFunction, _a) { | ||
var _b = _a === void 0 ? Object.create(null) : _a, _c = _b.max, max = _c === void 0 ? Math.pow(2, 16) : _c, _d = _b.disposable, disposable = _d === void 0 ? false : _d, _e = _b.makeCacheKey, makeCacheKey = _e === void 0 ? exports.defaultMakeCacheKey : _e, subscribe = _b.subscribe; | ||
var cache = new cache_1.Cache({ | ||
max: max, | ||
dispose: function (entry) { | ||
entry.dispose(); | ||
}, | ||
}); | ||
var key_trie_1 = require("./key-trie"); | ||
// The defaultMakeCacheKey function is remarkably powerful, because it gives | ||
// a unique object for any shallow-identical list of arguments. If you need | ||
// to implement a custom makeCacheKey function, you may find it helpful to | ||
// delegate the final work to defaultMakeCacheKey, which is why we export it | ||
// here. However, you may want to avoid defaultMakeCacheKey if your runtime | ||
// does not support WeakMap, or you have the ability to return a string key. | ||
// In those cases, just write your own custom makeCacheKey functions. | ||
var keyTrie = new key_trie_1.KeyTrie(); | ||
function defaultMakeCacheKey() { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return keyTrie.lookup(args); | ||
} | ||
exports.defaultMakeCacheKey = defaultMakeCacheKey; | ||
function wrap(originalFunction, options) { | ||
if (options === void 0) { options = Object.create(null); } | ||
var cache = new cache_1.Cache(options.max || Math.pow(2, 16), function (entry) { return entry.dispose(); }); | ||
var disposable = !!options.disposable; | ||
var makeCacheKey = options.makeCacheKey || defaultMakeCacheKey; | ||
function reportOrphan(entry) { | ||
@@ -33,3 +44,3 @@ // Triggers the entry.dispose() call above. | ||
// the entry object without recomputing anything, anyway. | ||
return; | ||
return void 0; | ||
} | ||
@@ -45,4 +56,5 @@ var key = makeCacheKey.apply(null, args); | ||
else { | ||
cache.set(key, entry = entry_1.Entry.acquire(originalFunction, key, args)); | ||
entry.subscribe = subscribe; | ||
entry = new entry_1.Entry(originalFunction, args, key); | ||
cache.set(key, entry); | ||
entry.subscribe = options.subscribe; | ||
if (disposable) { | ||
@@ -65,5 +77,3 @@ entry.reportOrphan = reportOrphan; | ||
// avoid returning the value, so it won't be accidentally used. | ||
if (!disposable) { | ||
return value; | ||
} | ||
return disposable ? void 0 : value; | ||
} | ||
@@ -76,4 +86,5 @@ optimistic.dirty = function () { | ||
var key = makeCacheKey.apply(null, args); | ||
if (key && cache.has(key)) { | ||
cache.get(key).setDirty(); | ||
var child = key && cache.get(key); | ||
if (child) { | ||
child.setDirty(); | ||
} | ||
@@ -84,1 +95,2 @@ }; | ||
exports.wrap = wrap; | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,3 @@ | ||
import { Entry } from "./entry"; | ||
export declare function get(): { | ||
currentParentEntry: Entry; | ||
currentParentEntry: import("./entry").Entry<any, any, any>; | ||
}; |
@@ -26,1 +26,2 @@ "use strict"; | ||
exports.get = get; | ||
//# sourceMappingURL=local.js.map |
{ | ||
"name": "optimism", | ||
"version": "0.7.1", | ||
"version": "0.8.0", | ||
"author": "Ben Newman <ben@benjamn.com>", | ||
@@ -18,2 +18,3 @@ "description": "Composable reactive caching with efficient invalidation.", | ||
"main": "lib/index.js", | ||
"module": "lib/bundle.esm.js", | ||
"types": "lib/index.d.ts", | ||
@@ -30,16 +31,18 @@ "license": "MIT", | ||
"scripts": { | ||
"build": "tsc", | ||
"mocha": "mocha --reporter spec --full-trace test/tests.js", | ||
"build": "npm run clean && tsc && rollup -c", | ||
"clean": "rimraf lib", | ||
"mocha": "mocha --reporter spec --full-trace lib/tests/index", | ||
"prepublish": "npm run build", | ||
"test": "npm run build && npm run mocha" | ||
}, | ||
"dependencies": { | ||
"immutable-tuple": "^0.4.10" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^10.12.18", | ||
"@types/mocha": "^5.2.6", | ||
"@types/node": "^10.14.1", | ||
"fibers": "^3.0.0", | ||
"mocha": "^5.0.0", | ||
"typescript": "^3.2.4" | ||
"rimraf": "^2.6.3", | ||
"rollup": "^1.6.0", | ||
"rollup-plugin-typescript2": "^0.20.1", | ||
"typescript": "^3.3.3333" | ||
} | ||
} |
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
94099
0
20
1129
8
- Removedimmutable-tuple@^0.4.10
- Removedimmutable-tuple@0.4.10(transitive)