Skip to content

Commit

Permalink
Merge caf93bd into 0918522
Browse files Browse the repository at this point in the history
  • Loading branch information
akmjenkins committed Nov 10, 2021
2 parents 0918522 + caf93bd commit 7f17a5c
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 53 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.0.4",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.172",
Expand All @@ -47,6 +48,7 @@
"babel-eslint": "^10.1.0",
"babel-jest": "^27.1.0",
"babel-plugin-add-module-exports": "^1.0.4",
"benchmark": "^2.1.4",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.4.0",
Expand All @@ -63,5 +65,8 @@
"rollup-plugin-terser": "^7.0.2",
"ts-jest": "^27.0.5",
"typescript": "^4.4.2"
},
"dependencies": {
"interpolatable": "^1.0.0"
}
}
8 changes: 7 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { terser } from 'rollup-plugin-terser';
import sourcemaps from 'rollup-plugin-sourcemaps';
import bundlesize from 'rollup-plugin-bundle-size';
import { babel } from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';

export default {
input: 'src/index.js',
Expand All @@ -15,5 +16,10 @@ export default {
plugins: [bundlesize(), terser()],
},
],
plugins: [nodeResolve(), babel({ babelHelpers: 'bundled' }), sourcemaps()],
plugins: [
commonjs(),
nodeResolve(),
babel({ babelHelpers: 'bundled' }),
sourcemaps(),
],
};
59 changes: 36 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { interpolate } from './interpolate';
import defaults from './options';
import { compareSets, memoRules } from './utils';

export default (
descriptor,
rules,
rules = [],
{ context, ...opts } = {},
subscribers = new Map(),
modified,
Expand All @@ -12,25 +12,43 @@ export default (

if (!validator) throw new Error(`A validator is required`);

rules = memoRules(rules, { pattern, resolver });

modified = descriptor;
const cache = new Map();
const cachedRules = new Set();
const emit = (eventType, thing) => {
const set = subscribers.get(eventType);
set && set.forEach((s) => s(thing));
};

const notify = (next, cacheKey) => {
const evaluate = (ops) =>
ops.reduce((acc, ops) => {
try {
return patch(acc, ops);
} catch (err) {
emit('error', { type: 'PatchError', err });
return acc;
}
}, descriptor);

const getCached = (ops) => {
for (const [key, value] of cache) if (compareSets(key, ops)) return value;
};

const notify = (next, key) => {
if (modified === next) return;
cache.set(key, next);
modified = next;
cache.set(cacheKey, next);
emit('modified', modified);
};

const run = () => {
let isCached;
const rulesToApply = rules
.map(
({ when, then, otherwise }) =>
(interpolate(when, context, pattern, resolver).some((rule) =>
(when(context).some((rule) =>
Object.entries(rule).every(([key, schema]) => {
try {
return validator(schema, resolver(context, key));
Expand All @@ -42,24 +60,19 @@ export default (
? then
: otherwise) || [],
)
.map((ops) => interpolate(ops, context, pattern, resolver));

const cacheKey = JSON.stringify(rulesToApply);
const cached = cache.get(cacheKey);
.map((ops) => {
const result = ops(context);
if (!cachedRules.has(result)) {
isCached = false;
cachedRules.add(result);
} else {
isCached = isCached ?? true;
}
return result;
});

notify(
cached
? cached
: rulesToApply.reduce((acc, ops) => {
try {
return patch(acc, ops);
} catch (err) {
emit('error', { type: 'PatchError', err });
return acc;
}
}, descriptor),
cacheKey,
);
const ops = new Set(rulesToApply);
notify(getCached(ops) || evaluate(rulesToApply), ops);
};

// run immediately
Expand All @@ -79,7 +92,7 @@ export default (
subscribe: (subscriber) => on('modified', subscriber),
get: () => modified,
set: (d) => descriptor === d || run((descriptor = d), cache.clear()),
setRules: (r) => rules === r || run((rules = r)),
setRules: (r) => run((rules = memoRules(rules, { pattern, resolver }))),
setContext: (ctx) => context === ctx || run((context = ctx)),
};
};
28 changes: 0 additions & 28 deletions src/interpolate.js

This file was deleted.

14 changes: 14 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import interpolatable from 'interpolatable';

export const compareSets = (a, b) => {
if (a.size !== b.size) return false;
for (const value of a) if (!b.has(value)) return false;
return true;
};

export const memoRules = (rules, opts) =>
rules.map(({ when, then = {}, otherwise = {} }) => ({
when: interpolatable(when, opts),
then: interpolatable(then, opts),
otherwise: interpolatable(otherwise, opts),
}));
67 changes: 66 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,19 @@
"@babel/helper-module-imports" "^7.10.4"
"@rollup/pluginutils" "^3.1.0"

"@rollup/plugin-commonjs@^21.0.1":
version "21.0.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz#1e57c81ae1518e4df0954d681c642e7d94588fee"
integrity sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==
dependencies:
"@rollup/pluginutils" "^3.1.0"
commondir "^1.0.1"
estree-walker "^2.0.1"
glob "^7.1.6"
is-reference "^1.2.1"
magic-string "^0.25.7"
resolve "^1.17.0"

"@rollup/plugin-node-resolve@^13.0.4":
version "13.0.4"
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0"
Expand Down Expand Up @@ -1250,6 +1263,11 @@
dependencies:
"@babel/types" "^7.3.0"

"@types/estree@*":
version "0.0.50"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==

"@types/estree@0.0.39":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
Expand Down Expand Up @@ -1733,6 +1751,14 @@ base@^0.11.1:
mixin-deep "^1.2.0"
pascalcase "^0.1.1"

benchmark@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629"
integrity sha1-CfPeMckWQl1JjMLuVloOvzwqVik=
dependencies:
lodash "^4.17.4"
platform "^1.3.3"

binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
Expand Down Expand Up @@ -1998,6 +2024,11 @@ commander@^4.0.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==

commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=

component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
Expand Down Expand Up @@ -2473,6 +2504,11 @@ estree-walker@^1.0.1:
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==

estree-walker@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==

esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
Expand Down Expand Up @@ -2976,6 +3012,11 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"

interpolatable@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/interpolatable/-/interpolatable-1.0.0.tgz#6a875fd613d0773bd3eed5c33d43d5a7cf54c963"
integrity sha512-usu1tF+Vf6sTHTe5XG0ETIBe+LZR41pYd9Ah98RB6Vt2/enpsUm/8eWemZVzknhHpwOkwyvs4Ym0lNCW7/MJjw==

is-accessor-descriptor@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
Expand Down Expand Up @@ -3162,6 +3203,13 @@ is-potential-custom-element-name@^1.0.1:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==

is-reference@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
dependencies:
"@types/estree" "*"

is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
Expand Down Expand Up @@ -3867,7 +3915,7 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=

lodash@4.x, lodash@^4.7.0:
lodash@4.x, lodash@^4.17.4, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
Expand All @@ -3879,6 +3927,13 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"

magic-string@^0.25.7:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
dependencies:
sourcemap-codec "^1.4.4"

make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
Expand Down Expand Up @@ -4336,6 +4391,11 @@ pkg-up@^2.0.0:
dependencies:
find-up "^2.1.0"

platform@^1.3.3:
version "1.3.6"
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==

posix-character-classes@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
Expand Down Expand Up @@ -4839,6 +4899,11 @@ source-map@^0.7.3, source-map@~0.7.2:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==

sourcemap-codec@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==

spdx-correct@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
Expand Down

0 comments on commit 7f17a5c

Please sign in to comment.