nano-memoize
Advanced tools
Comparing version 0.1.2 to 1.0.0
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
(function() { | ||
"use strict"; | ||
const hasVargs = f => { | ||
const hasVargs = (f) => { | ||
const s = f+"", | ||
@@ -10,2 +10,31 @@ i = s.indexOf("..."); | ||
function nanomemoize (fn, options={}) { | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) { key = key.slice(0,max); } | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) { break; } // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) { change(i); } | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
const { | ||
@@ -27,3 +56,3 @@ serializer = (value) => JSON.stringify(value), | ||
timeout = (change) => { // deletes timed-out keys | ||
if(t[change.key]) clearTimeout(t[change.key]); | ||
if(t[change.key]) { clearTimeout(t[change.key]); } | ||
t[change.key] = setTimeout(() => { | ||
@@ -36,3 +65,3 @@ delete change.cache[change.key]; | ||
for(let p in c) { | ||
if(maxAge) timeout(c[p]); | ||
if(maxAge) { timeout(c[p]); } | ||
delete c[p]; | ||
@@ -65,3 +94,3 @@ } | ||
f.clear = () => { | ||
Object.keys(s).forEach(k => delete s[k]); | ||
Object.keys(s).forEach((k) => delete s[k]); | ||
k.length = 0; //k.splice(0,k.length); | ||
@@ -71,3 +100,3 @@ v.length = 0; //v.splice(0,v.length); | ||
Object.keys(t).forEach(k => { clearTimeout(t[k]); delete t[k]; }); | ||
} | ||
}; | ||
f.keys = () => (!unary ? k.slice() : null); | ||
@@ -78,33 +107,2 @@ f.values = () => (!unary ? v.slice() : null); | ||
} | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) key = key.slice(0,max); | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) break; // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) change(i); | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
@@ -111,0 +109,0 @@ if(typeof(module)!=="undefined") module.exports = nanomemoize; |
@@ -1,1 +0,1 @@ | ||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){(function(){"use strict";const hasVargs=f=>{const s=f+"",i=s.indexOf("...");return i>=0&&i<s.indexOf(")"||s.indexOf("arguments")>=0)};function nanomemoize(fn,options={}){const{serializer:serializer=(value=>JSON.stringify(value)),equals:equals,maxAge:maxAge,maxArgs:maxArgs,vargs:vargs=hasVargs(fn)}=options,s={},k=[],v=[],c={},change=(cache,key)=>{c[key]={key:key,cache:cache}},t={},timeout=change=>{if(t[change.key])clearTimeout(t[change.key]);t[change.key]=setTimeout(()=>{delete change.cache[change.key];delete t[change.key]},maxAge)};setInterval(()=>{for(let p in c){if(maxAge)timeout(c[p]);delete c[p]}},1);let f,unary=fn.length===1&&!equals&&!vargs;if(unary){f=single.bind(this,fn,s,maxAge?change.bind(this,s):null,serializer)}else{f=multiple.bind(this,fn,k,v,equals||((a,b)=>a===b),maxAge?change.bind(this,v):null,maxArgs)}f.clear=(()=>{Object.keys(s).forEach(k=>delete s[k]);k.length=0;v.length=0;Object.keys(c).forEach(k=>delete c[k]);Object.keys(t).forEach(k=>{clearTimeout(t[k]);delete t[k]})});f.keys=(()=>!unary?k.slice():null);f.values=(()=>!unary?v.slice():null);f.keyValues=(()=>unary?Object.assign({},s):null);return f}function single(f,s,change,serializer,arg){const key=!arg||typeof arg==="number"||typeof arg==="boolean"?arg:serializer(arg);if(change)change(key);return s[key]||(s[key]=f.call(this,arg))}function multiple(f,k,v,eq,change,max=0,...args){const rslt={};for(let i=0;i<k.length;i++){let key=k[i];if(max)key=key.slice(0,max);if(key.length===args.length||max&&key.length<args.length){const max=key.length-1;for(let j=0;j<=max;j++){if(!eq(key[j],args[j]))break;if(j===max){rslt.i=i;rslt.v=v[i]}}}}const i=rslt.i>=0?rslt.i:v.length;if(change)change(i);return typeof rslt.v==="undefined"?v[i]=f.call(this,...k[i]=args):rslt.v}if(typeof module!=="undefined")module.exports=nanomemoize;if(typeof window!=="undefined")window.nanomemoize=nanomemoize}).call(this)},{}]},{},[1]); | ||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){(function(){"use strict";const hasVargs=f=>{const s=f+"",i=s.indexOf("...");return i>=0&&i<s.indexOf(")"||s.indexOf("arguments")>=0)};function nanomemoize(fn,options={}){function single(f,s,change,serializer,arg){const key=!arg||typeof arg==="number"||typeof arg==="boolean"?arg:serializer(arg);if(change)change(key);return s[key]||(s[key]=f.call(this,arg))}function multiple(f,k,v,eq,change,max=0,...args){const rslt={};for(let i=0;i<k.length;i++){let key=k[i];if(max){key=key.slice(0,max)}if(key.length===args.length||max&&key.length<args.length){const max=key.length-1;for(let j=0;j<=max;j++){if(!eq(key[j],args[j])){break}if(j===max){rslt.i=i;rslt.v=v[i]}}}}const i=rslt.i>=0?rslt.i:v.length;if(change){change(i)}return typeof rslt.v==="undefined"?v[i]=f.call(this,...k[i]=args):rslt.v}const{serializer:serializer=(value=>JSON.stringify(value)),equals:equals,maxAge:maxAge,maxArgs:maxArgs,vargs:vargs=hasVargs(fn)}=options,s={},k=[],v=[],c={},change=(cache,key)=>{c[key]={key:key,cache:cache}},t={},timeout=change=>{if(t[change.key]){clearTimeout(t[change.key])}t[change.key]=setTimeout(()=>{delete change.cache[change.key];delete t[change.key]},maxAge)};setInterval(()=>{for(let p in c){if(maxAge){timeout(c[p])}delete c[p]}},1);let f,unary=fn.length===1&&!equals&&!vargs;if(unary){f=single.bind(this,fn,s,maxAge?change.bind(this,s):null,serializer)}else{f=multiple.bind(this,fn,k,v,equals||((a,b)=>a===b),maxAge?change.bind(this,v):null,maxArgs)}f.clear=(()=>{Object.keys(s).forEach(k=>delete s[k]);k.length=0;v.length=0;Object.keys(c).forEach(k=>delete c[k]);Object.keys(t).forEach(k=>{clearTimeout(t[k]);delete t[k]})});f.keys=(()=>!unary?k.slice():null);f.values=(()=>!unary?v.slice():null);f.keyValues=(()=>unary?Object.assign({},s):null);return f}if(typeof module!=="undefined")module.exports=nanomemoize;if(typeof window!=="undefined")window.nanomemoize=nanomemoize}).call(this)},{}]},{},[1]); |
(function() { | ||
"use strict"; | ||
const hasVargs = f => { | ||
const hasVargs = (f) => { | ||
const s = f+"", | ||
@@ -9,2 +9,31 @@ i = s.indexOf("..."); | ||
function nanomemoize (fn, options={}) { | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) { key = key.slice(0,max); } | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) { break; } // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) { change(i); } | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
const { | ||
@@ -26,3 +55,3 @@ serializer = (value) => JSON.stringify(value), | ||
timeout = (change) => { // deletes timed-out keys | ||
if(t[change.key]) clearTimeout(t[change.key]); | ||
if(t[change.key]) { clearTimeout(t[change.key]); } | ||
t[change.key] = setTimeout(() => { | ||
@@ -35,3 +64,3 @@ delete change.cache[change.key]; | ||
for(let p in c) { | ||
if(maxAge) timeout(c[p]); | ||
if(maxAge) { timeout(c[p]); } | ||
delete c[p]; | ||
@@ -64,3 +93,3 @@ } | ||
f.clear = () => { | ||
Object.keys(s).forEach(k => delete s[k]); | ||
Object.keys(s).forEach((k) => delete s[k]); | ||
k.length = 0; //k.splice(0,k.length); | ||
@@ -70,3 +99,3 @@ v.length = 0; //v.splice(0,v.length); | ||
Object.keys(t).forEach(k => { clearTimeout(t[k]); delete t[k]; }); | ||
} | ||
}; | ||
f.keys = () => (!unary ? k.slice() : null); | ||
@@ -77,33 +106,2 @@ f.values = () => (!unary ? v.slice() : null); | ||
} | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) key = key.slice(0,max); | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) break; // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) change(i); | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
@@ -110,0 +108,0 @@ if(typeof(module)!=="undefined") module.exports = nanomemoize; |
@@ -1,1 +0,1 @@ | ||
(function(){"use strict";const hasVargs=f=>{const s=f+"",i=s.indexOf("...");return i>=0&&i<s.indexOf(")"||s.indexOf("arguments")>=0)};function nanomemoize(fn,options={}){const{serializer:serializer=(value=>JSON.stringify(value)),equals:equals,maxAge:maxAge,maxArgs:maxArgs,vargs:vargs=hasVargs(fn)}=options,s={},k=[],v=[],c={},change=(cache,key)=>{c[key]={key:key,cache:cache}},t={},timeout=change=>{if(t[change.key])clearTimeout(t[change.key]);t[change.key]=setTimeout(()=>{delete change.cache[change.key];delete t[change.key]},maxAge)};setInterval(()=>{for(let p in c){if(maxAge)timeout(c[p]);delete c[p]}},1);let f,unary=fn.length===1&&!equals&&!vargs;if(unary){f=single.bind(this,fn,s,maxAge?change.bind(this,s):null,serializer)}else{f=multiple.bind(this,fn,k,v,equals||((a,b)=>a===b),maxAge?change.bind(this,v):null,maxArgs)}f.clear=(()=>{Object.keys(s).forEach(k=>delete s[k]);k.length=0;v.length=0;Object.keys(c).forEach(k=>delete c[k]);Object.keys(t).forEach(k=>{clearTimeout(t[k]);delete t[k]})});f.keys=(()=>!unary?k.slice():null);f.values=(()=>!unary?v.slice():null);f.keyValues=(()=>unary?Object.assign({},s):null);return f}function single(f,s,change,serializer,arg){const key=!arg||typeof arg==="number"||typeof arg==="boolean"?arg:serializer(arg);if(change)change(key);return s[key]||(s[key]=f.call(this,arg))}function multiple(f,k,v,eq,change,max=0,...args){const rslt={};for(let i=0;i<k.length;i++){let key=k[i];if(max)key=key.slice(0,max);if(key.length===args.length||max&&key.length<args.length){const max=key.length-1;for(let j=0;j<=max;j++){if(!eq(key[j],args[j]))break;if(j===max){rslt.i=i;rslt.v=v[i]}}}}const i=rslt.i>=0?rslt.i:v.length;if(change)change(i);return typeof rslt.v==="undefined"?v[i]=f.call(this,...k[i]=args):rslt.v}if(typeof module!=="undefined")module.exports=nanomemoize;if(typeof window!=="undefined")window.nanomemoize=nanomemoize}).call(this); | ||
(function(){"use strict";const hasVargs=f=>{const s=f+"",i=s.indexOf("...");return i>=0&&i<s.indexOf(")"||s.indexOf("arguments")>=0)};function nanomemoize(fn,options={}){function single(f,s,change,serializer,arg){const key=!arg||typeof arg==="number"||typeof arg==="boolean"?arg:serializer(arg);if(change)change(key);return s[key]||(s[key]=f.call(this,arg))}function multiple(f,k,v,eq,change,max=0,...args){const rslt={};for(let i=0;i<k.length;i++){let key=k[i];if(max){key=key.slice(0,max)}if(key.length===args.length||max&&key.length<args.length){const max=key.length-1;for(let j=0;j<=max;j++){if(!eq(key[j],args[j])){break}if(j===max){rslt.i=i;rslt.v=v[i]}}}}const i=rslt.i>=0?rslt.i:v.length;if(change){change(i)}return typeof rslt.v==="undefined"?v[i]=f.call(this,...k[i]=args):rslt.v}const{serializer:serializer=(value=>JSON.stringify(value)),equals:equals,maxAge:maxAge,maxArgs:maxArgs,vargs:vargs=hasVargs(fn)}=options,s={},k=[],v=[],c={},change=(cache,key)=>{c[key]={key:key,cache:cache}},t={},timeout=change=>{if(t[change.key]){clearTimeout(t[change.key])}t[change.key]=setTimeout(()=>{delete change.cache[change.key];delete t[change.key]},maxAge)};setInterval(()=>{for(let p in c){if(maxAge){timeout(c[p])}delete c[p]}},1);let f,unary=fn.length===1&&!equals&&!vargs;if(unary){f=single.bind(this,fn,s,maxAge?change.bind(this,s):null,serializer)}else{f=multiple.bind(this,fn,k,v,equals||((a,b)=>a===b),maxAge?change.bind(this,v):null,maxArgs)}f.clear=(()=>{Object.keys(s).forEach(k=>delete s[k]);k.length=0;v.length=0;Object.keys(c).forEach(k=>delete c[k]);Object.keys(t).forEach(k=>{clearTimeout(t[k]);delete t[k]})});f.keys=(()=>!unary?k.slice():null);f.values=(()=>!unary?v.slice():null);f.keyValues=(()=>unary?Object.assign({},s):null);return f}if(typeof module!=="undefined")module.exports=nanomemoize;if(typeof window!=="undefined")window.nanomemoize=nanomemoize}).call(this); |
70
index.js
(function() { | ||
"use strict"; | ||
const hasVargs = f => { | ||
const hasVargs = (f) => { | ||
const s = f+"", | ||
@@ -9,2 +9,31 @@ i = s.indexOf("..."); | ||
function nanomemoize (fn, options={}) { | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) { key = key.slice(0,max); } | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) { break; } // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) { change(i); } | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
const { | ||
@@ -26,3 +55,3 @@ serializer = (value) => JSON.stringify(value), | ||
timeout = (change) => { // deletes timed-out keys | ||
if(t[change.key]) clearTimeout(t[change.key]); | ||
if(t[change.key]) { clearTimeout(t[change.key]); } | ||
t[change.key] = setTimeout(() => { | ||
@@ -35,3 +64,3 @@ delete change.cache[change.key]; | ||
for(let p in c) { | ||
if(maxAge) timeout(c[p]); | ||
if(maxAge) { timeout(c[p]); } | ||
delete c[p]; | ||
@@ -64,3 +93,3 @@ } | ||
f.clear = () => { | ||
Object.keys(s).forEach(k => delete s[k]); | ||
Object.keys(s).forEach((k) => delete s[k]); | ||
k.length = 0; //k.splice(0,k.length); | ||
@@ -70,3 +99,3 @@ v.length = 0; //v.splice(0,v.length); | ||
Object.keys(t).forEach(k => { clearTimeout(t[k]); delete t[k]; }); | ||
} | ||
}; | ||
f.keys = () => (!unary ? k.slice() : null); | ||
@@ -77,33 +106,2 @@ f.values = () => (!unary ? v.slice() : null); | ||
} | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) key = key.slice(0,max); | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) break; // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) change(i); | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
@@ -110,0 +108,0 @@ if(typeof(module)!=="undefined") module.exports = nanomemoize; |
{ | ||
"name": "nano-memoize", | ||
"version": "v0.1.2", | ||
"version": "v1.0.0", | ||
"description": "Faster than fast, smaller than micro ... a nano speed and nano size memoizer.", | ||
@@ -5,0 +5,0 @@ "engines": {}, |
@@ -0,1 +1,2 @@ | ||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/30ce201484754fa5b0a6c6046abb842d)](https://www.codacy.com/app/syblackwell/nano-memoize?utm_source=github.com&utm_medium=referral&utm_content=anywhichway/nano-memoize&utm_campaign=Badge_Grade) | ||
# Faster than fast, smaller than micro ... nano-memoizer. | ||
@@ -7,3 +8,3 @@ | ||
The minified/gzipped size is 872 bytes for `nano-memoize` vs 959 bytes for `micro-memoize`. And, `nano-memoize` has slightly more functionality. | ||
The minified/gzipped size is 887 bytes for `nano-memoize` vs 959 bytes for `micro-memoize`. And, `nano-memoize` has slightly more functionality. | ||
@@ -133,4 +134,6 @@ The speed tests are below. `nano-memoize` is the fastest in all cases. For single argument functions is it comparable to, but slightly and probably un-importantly faster than, `fast-memoize`. For multiple argument functions it is comparable to, but slightly and probably un-importantly faster than, `micro-memoize`. | ||
2018-02-07 v0.0.2 Documentation updates | ||
2018-04-13 v1.0.0 Code style improvements. | ||
2018-02-07 v0.1.2 Documentation updates | ||
2018-02-07 v0.1.1 Documentationand benchmark updates | ||
@@ -137,0 +140,0 @@ |
(function() { | ||
"use strict"; | ||
const hasVargs = f => { | ||
const hasVargs = (f) => { | ||
const s = f+"", | ||
@@ -9,2 +9,31 @@ i = s.indexOf("..."); | ||
function nanomemoize (fn, options={}) { | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) { key = key.slice(0,max); } | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) { break; } // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) { change(i); } | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
const { | ||
@@ -26,3 +55,3 @@ serializer = (value) => JSON.stringify(value), | ||
timeout = (change) => { // deletes timed-out keys | ||
if(t[change.key]) clearTimeout(t[change.key]); | ||
if(t[change.key]) { clearTimeout(t[change.key]); } | ||
t[change.key] = setTimeout(() => { | ||
@@ -35,3 +64,3 @@ delete change.cache[change.key]; | ||
for(let p in c) { | ||
if(maxAge) timeout(c[p]); | ||
if(maxAge) { timeout(c[p]); } | ||
delete c[p]; | ||
@@ -64,3 +93,3 @@ } | ||
f.clear = () => { | ||
Object.keys(s).forEach(k => delete s[k]); | ||
Object.keys(s).forEach((k) => delete s[k]); | ||
k.length = 0; //k.splice(0,k.length); | ||
@@ -70,3 +99,3 @@ v.length = 0; //v.splice(0,v.length); | ||
Object.keys(t).forEach(k => { clearTimeout(t[k]); delete t[k]; }); | ||
} | ||
}; | ||
f.keys = () => (!unary ? k.slice() : null); | ||
@@ -77,33 +106,2 @@ f.values = () => (!unary ? v.slice() : null); | ||
} | ||
// for single argument functions, just use a JS object key look-up | ||
function single (f,s,change,serializer,arg) { | ||
// strings must be stringified because cache[1] should not equal or overwrite cache["1"] for value = 1 and value = "1" | ||
const key = (!arg || typeof arg === "number" || typeof arg ==="boolean" ? arg : serializer(arg)); | ||
if(change) change(key); | ||
return s[key] || ( s[key] = f.call(this, arg)); | ||
} | ||
// for multiple arg functions, loop through a cache of all the args | ||
// looking at each arg separately so a test can abort as soon as possible | ||
function multiple(f,k,v,eq,change,max=0,...args) { | ||
const rslt = {}; | ||
for(let i=0;i<k.length;i++) { // an array of arrays of args | ||
let key = k[i]; | ||
if(max) key = key.slice(0,max); | ||
if(key.length===args.length || (max && key.length<args.length)) { | ||
const max = key.length - 1; | ||
for(let j=0;j<=max;j++) { | ||
if(!eq(key[j],args[j])) break; // go to next key if args don't match | ||
if(j===max) { // the args matched | ||
rslt.i = i; | ||
rslt.v = v[i]; // get the cached value | ||
} | ||
} | ||
} | ||
} | ||
const i = rslt.i>=0 ? rslt.i : v.length; | ||
if(change) change(i); | ||
return typeof rslt.v === "undefined" ? v[i] = f.call(this,...(k[i] = args)) : rslt.v; | ||
} | ||
@@ -110,0 +108,0 @@ if(typeof(module)!=="undefined") module.exports = nanomemoize; |
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
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
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
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
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
49029
1
153