@data-client/normalizr
Version:
Normalizes and denormalizes JSON according to schema for Redux and Flux applications
68 lines (66 loc) • 8.09 kB
JavaScript
import { UNDEF } from '../denormalize/UNDEF.js';
/** Maps a (ordered) list of dependencies to a value.
*
* Useful as a memoization cache for flat/normalized stores.
*
* All dependencies are only weakly referenced, allowing automatic garbage collection
* when any dependencies are no longer used.
*/
export default class WeakDependencyMap {
constructor() {
this.next = new WeakMap();
this.nextPath = undefined;
}
get(entity, getDependency) {
let curLink = this.next.get(entity);
if (!curLink) return EMPTY;
while (curLink.nextPath) {
var _getDependency;
// we cannot perform lookups with `undefined`, so we use a special object to represent undefined
const nextEntity = (_getDependency = getDependency(curLink.nextPath)) != null ? _getDependency : UNDEF;
curLink = curLink.next.get(nextEntity);
if (!curLink) return EMPTY;
}
// curLink exists, but has no path - so must have a value
return [curLink.value, curLink.journey];
}
set(dependencies, value) {
if (dependencies.length < 1) throw new KeySize();
let curLink = this;
for (const {
entity,
path
} of dependencies) {
let nextLink = curLink.next.get(entity);
if (!nextLink) {
nextLink = new Link();
// void members are represented as a symbol so we can lookup
curLink.next.set(entity != null ? entity : UNDEF, nextLink);
}
curLink.nextPath = path;
curLink = nextLink;
}
// in case there used to be more
curLink.nextPath = undefined;
curLink.value = value;
// we could recompute this on get, but it would have a cost and we optimize for `get`
curLink.journey = dependencies.map(dep => dep.path);
}
}
const EMPTY = [undefined, undefined];
/** Link in a chain */
class Link {
constructor() {
this.next = new WeakMap();
this.value = undefined;
this.journey = [];
this.nextPath = undefined;
}
}
class KeySize extends Error {
constructor(...args) {
super(...args);
this.message = 'Keys must include at least one member';
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJVTkRFRiIsIldlYWtEZXBlbmRlbmN5TWFwIiwiY29uc3RydWN0b3IiLCJuZXh0IiwiV2Vha01hcCIsIm5leHRQYXRoIiwidW5kZWZpbmVkIiwiZ2V0IiwiZW50aXR5IiwiZ2V0RGVwZW5kZW5jeSIsImN1ckxpbmsiLCJFTVBUWSIsIl9nZXREZXBlbmRlbmN5IiwibmV4dEVudGl0eSIsInZhbHVlIiwiam91cm5leSIsInNldCIsImRlcGVuZGVuY2llcyIsImxlbmd0aCIsIktleVNpemUiLCJwYXRoIiwibmV4dExpbmsiLCJMaW5rIiwibWFwIiwiZGVwIiwiRXJyb3IiLCJhcmdzIiwibWVzc2FnZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tZW1vL1dlYWtEZXBlbmRlbmN5TWFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFVOREVGIH0gZnJvbSAnLi4vZGVub3JtYWxpemUvVU5ERUYuanMnO1xuXG4vKiogTWFwcyBhIChvcmRlcmVkKSBsaXN0IG9mIGRlcGVuZGVuY2llcyB0byBhIHZhbHVlLlxuICpcbiAqIFVzZWZ1bCBhcyBhIG1lbW9pemF0aW9uIGNhY2hlIGZvciBmbGF0L25vcm1hbGl6ZWQgc3RvcmVzLlxuICpcbiAqIEFsbCBkZXBlbmRlbmNpZXMgYXJlIG9ubHkgd2Vha2x5IHJlZmVyZW5jZWQsIGFsbG93aW5nIGF1dG9tYXRpYyBnYXJiYWdlIGNvbGxlY3Rpb25cbiAqIHdoZW4gYW55IGRlcGVuZGVuY2llcyBhcmUgbm8gbG9uZ2VyIHVzZWQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdlYWtEZXBlbmRlbmN5TWFwPFxuICBQYXRoLFxuICBLIGV4dGVuZHMgb2JqZWN0ID0gb2JqZWN0LFxuICBWID0gYW55LFxuPiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmV4dCA9IG5ldyBXZWFrTWFwPEssIExpbms8UGF0aCwgSywgVj4+KCk7XG4gIHByaXZhdGUgbmV4dFBhdGg6IFBhdGggfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZ2V0KGVudGl0eTogSywgZ2V0RGVwZW5kZW5jeTogR2V0RGVwZW5kZW5jeTxQYXRoLCBLIHwgc3ltYm9sPikge1xuICAgIGxldCBjdXJMaW5rID0gdGhpcy5uZXh0LmdldChlbnRpdHkpO1xuICAgIGlmICghY3VyTGluaykgcmV0dXJuIEVNUFRZO1xuICAgIHdoaWxlIChjdXJMaW5rLm5leHRQYXRoKSB7XG4gICAgICAvLyB3ZSBjYW5ub3QgcGVyZm9ybSBsb29rdXBzIHdpdGggYHVuZGVmaW5lZGAsIHNvIHdlIHVzZSBhIHNwZWNpYWwgb2JqZWN0IHRvIHJlcHJlc2VudCB1bmRlZmluZWRcbiAgICAgIGNvbnN0IG5leHRFbnRpdHkgPSBnZXREZXBlbmRlbmN5KGN1ckxpbmsubmV4dFBhdGgpID8/IFVOREVGO1xuICAgICAgY3VyTGluayA9IGN1ckxpbmsubmV4dC5nZXQobmV4dEVudGl0eSBhcyBhbnkpO1xuICAgICAgaWYgKCFjdXJMaW5rKSByZXR1cm4gRU1QVFk7XG4gICAgfVxuICAgIC8vIGN1ckxpbmsgZXhpc3RzLCBidXQgaGFzIG5vIHBhdGggLSBzbyBtdXN0IGhhdmUgYSB2YWx1ZVxuICAgIHJldHVybiBbY3VyTGluay52YWx1ZSwgY3VyTGluay5qb3VybmV5XSBhcyByZWFkb25seSBbViwgUGF0aFtdXTtcbiAgfVxuXG4gIHNldChkZXBlbmRlbmNpZXM6IERlcDxQYXRoLCBLPltdLCB2YWx1ZTogVikge1xuICAgIGlmIChkZXBlbmRlbmNpZXMubGVuZ3RoIDwgMSkgdGhyb3cgbmV3IEtleVNpemUoKTtcbiAgICBsZXQgY3VyTGluazogTGluazxQYXRoLCBLLCBWPiA9IHRoaXMgYXMgYW55O1xuICAgIGZvciAoY29uc3QgeyBlbnRpdHksIHBhdGggfSBvZiBkZXBlbmRlbmNpZXMpIHtcbiAgICAgIGxldCBuZXh0TGluayA9IGN1ckxpbmsubmV4dC5nZXQoZW50aXR5KTtcbiAgICAgIGlmICghbmV4dExpbmspIHtcbiAgICAgICAgbmV4dExpbmsgPSBuZXcgTGluazxQYXRoLCBLLCBWPigpO1xuICAgICAgICAvLyB2b2lkIG1lbWJlcnMgYXJlIHJlcHJlc2VudGVkIGFzIGEgc3ltYm9sIHNvIHdlIGNhbiBsb29rdXBcbiAgICAgICAgY3VyTGluay5uZXh0LnNldChlbnRpdHkgPz8gVU5ERUYsIG5leHRMaW5rKTtcbiAgICAgIH1cbiAgICAgIGN1ckxpbmsubmV4dFBhdGggPSBwYXRoO1xuICAgICAgY3VyTGluayA9IG5leHRMaW5rO1xuICAgIH1cbiAgICAvLyBpbiBjYXNlIHRoZXJlIHVzZWQgdG8gYmUgbW9yZVxuICAgIGN1ckxpbmsubmV4dFBhdGggPSB1bmRlZmluZWQ7XG4gICAgY3VyTGluay52YWx1ZSA9IHZhbHVlO1xuICAgIC8vIHdlIGNvdWxkIHJlY29tcHV0ZSB0aGlzIG9uIGdldCwgYnV0IGl0IHdvdWxkIGhhdmUgYSBjb3N0IGFuZCB3ZSBvcHRpbWl6ZSBmb3IgYGdldGBcbiAgICBjdXJMaW5rLmpvdXJuZXkgPSBkZXBlbmRlbmNpZXMubWFwKGRlcCA9PiBkZXAucGF0aCk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgR2V0RGVwZW5kZW5jeTxQYXRoLCBLID0gb2JqZWN0IHwgc3ltYm9sPiA9IChsb29rdXA6IFBhdGgpID0+IEs7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwPFBhdGgsIEsgPSBvYmplY3Q+IHtcbiAgcGF0aDogUGF0aDtcbiAgZW50aXR5OiBLO1xufVxuXG5jb25zdCBFTVBUWSA9IFt1bmRlZmluZWQsIHVuZGVmaW5lZF0gYXMgY29uc3Q7XG5cbi8qKiBMaW5rIGluIGEgY2hhaW4gKi9cbmNsYXNzIExpbms8UGF0aCwgSyBleHRlbmRzIG9iamVjdCwgVj4ge1xuICBuZXh0ID0gbmV3IFdlYWtNYXA8SywgTGluazxQYXRoLCBLLCBWPj4oKTtcbiAgdmFsdWU6IFYgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIGpvdXJuZXk6IFBhdGhbXSA9IFtdO1xuICBuZXh0UGF0aDogUGF0aCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbn1cblxuY2xhc3MgS2V5U2l6ZSBleHRlbmRzIEVycm9yIHtcbiAgbWVzc2FnZSA9ICdLZXlzIG11c3QgaW5jbHVkZSBhdCBsZWFzdCBvbmUgbWVtYmVyJztcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBSyxRQUFRLHlCQUF5Qjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE1BQU1DLGlCQUFpQixDQUlwQztFQUFBQyxZQUFBO0lBQUEsS0FDaUJDLElBQUksR0FBRyxJQUFJQyxPQUFPLENBQXNCLENBQUM7SUFBQSxLQUNsREMsUUFBUSxHQUFxQkMsU0FBUztFQUFBO0VBRTlDQyxHQUFHQSxDQUFDQyxNQUFTLEVBQUVDLGFBQThDLEVBQUU7SUFDN0QsSUFBSUMsT0FBTyxHQUFHLElBQUksQ0FBQ1AsSUFBSSxDQUFDSSxHQUFHLENBQUNDLE1BQU0sQ0FBQztJQUNuQyxJQUFJLENBQUNFLE9BQU8sRUFBRSxPQUFPQyxLQUFLO0lBQzFCLE9BQU9ELE9BQU8sQ0FBQ0wsUUFBUSxFQUFFO01BQUEsSUFBQU8sY0FBQTtNQUN2QjtNQUNBLE1BQU1DLFVBQVUsSUFBQUQsY0FBQSxHQUFHSCxhQUFhLENBQUNDLE9BQU8sQ0FBQ0wsUUFBUSxDQUFDLFlBQUFPLGNBQUEsR0FBSVosS0FBSztNQUMzRFUsT0FBTyxHQUFHQSxPQUFPLENBQUNQLElBQUksQ0FBQ0ksR0FBRyxDQUFDTSxVQUFpQixDQUFDO01BQzdDLElBQUksQ0FBQ0gsT0FBTyxFQUFFLE9BQU9DLEtBQUs7SUFDNUI7SUFDQTtJQUNBLE9BQU8sQ0FBQ0QsT0FBTyxDQUFDSSxLQUFLLEVBQUVKLE9BQU8sQ0FBQ0ssT0FBTyxDQUFDO0VBQ3pDO0VBRUFDLEdBQUdBLENBQUNDLFlBQTRCLEVBQUVILEtBQVEsRUFBRTtJQUMxQyxJQUFJRyxZQUFZLENBQUNDLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxJQUFJQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxJQUFJVCxPQUF5QixHQUFHLElBQVc7SUFDM0MsS0FBSyxNQUFNO01BQUVGLE1BQU07TUFBRVk7SUFBSyxDQUFDLElBQUlILFlBQVksRUFBRTtNQUMzQyxJQUFJSSxRQUFRLEdBQUdYLE9BQU8sQ0FBQ1AsSUFBSSxDQUFDSSxHQUFHLENBQUNDLE1BQU0sQ0FBQztNQUN2QyxJQUFJLENBQUNhLFFBQVEsRUFBRTtRQUNiQSxRQUFRLEdBQUcsSUFBSUMsSUFBSSxDQUFhLENBQUM7UUFDakM7UUFDQVosT0FBTyxDQUFDUCxJQUFJLENBQUNhLEdBQUcsQ0FBQ1IsTUFBTSxXQUFOQSxNQUFNLEdBQUlSLEtBQUssRUFBRXFCLFFBQVEsQ0FBQztNQUM3QztNQUNBWCxPQUFPLENBQUNMLFFBQVEsR0FBR2UsSUFBSTtNQUN2QlYsT0FBTyxHQUFHVyxRQUFRO0lBQ3BCO0lBQ0E7SUFDQVgsT0FBTyxDQUFDTCxRQUFRLEdBQUdDLFNBQVM7SUFDNUJJLE9BQU8sQ0FBQ0ksS0FBSyxHQUFHQSxLQUFLO0lBQ3JCO0lBQ0FKLE9BQU8sQ0FBQ0ssT0FBTyxHQUFHRSxZQUFZLENBQUNNLEdBQUcsQ0FBQ0MsR0FBRyxJQUFJQSxHQUFHLENBQUNKLElBQUksQ0FBQztFQUNyRDtBQUNGO0FBU0EsTUFBTVQsS0FBSyxHQUFHLENBQUNMLFNBQVMsRUFBRUEsU0FBUyxDQUFVOztBQUU3QztBQUNBLE1BQU1nQixJQUFJLENBQTRCO0VBQUFwQixZQUFBO0lBQUEsS0FDcENDLElBQUksR0FBRyxJQUFJQyxPQUFPLENBQXNCLENBQUM7SUFBQSxLQUN6Q1UsS0FBSyxHQUFrQlIsU0FBUztJQUFBLEtBQ2hDUyxPQUFPLEdBQVcsRUFBRTtJQUFBLEtBQ3BCVixRQUFRLEdBQXFCQyxTQUFTO0VBQUE7QUFDeEM7QUFFQSxNQUFNYSxPQUFPLFNBQVNNLEtBQUssQ0FBQztFQUFBdkIsWUFBQSxHQUFBd0IsSUFBQTtJQUFBLFNBQUFBLElBQUE7SUFBQSxLQUMxQkMsT0FBTyxHQUFHLHVDQUF1QztFQUFBO0FBQ25EIiwiaWdub3JlTGlzdCI6W119