Comparing version 0.2.3 to 0.2.4
@@ -5,5 +5,5 @@ // To be used internally, memoize factory | ||
var callable = require('es5-ext/lib/Object/valid-callable') | ||
, forEach = require('es5-ext/lib/Object/for-each') | ||
, ee = require('event-emitter') | ||
var callable = require('es5-ext/lib/Object/valid-callable') | ||
, forEach = require('es5-ext/lib/Object/for-each') | ||
, ee = require('event-emitter/lib/core') | ||
@@ -10,0 +10,0 @@ , ext; |
@@ -20,7 +20,7 @@ // Call dispose callback on each cache purge | ||
delete conf.cache[id]; | ||
dispose.apply(null, slice.call(value, 1)); | ||
dispose.apply(conf.memoized['_memoize:context_'], slice.call(value, 1)); | ||
} : function (id) { | ||
var value = conf.cache[id]; | ||
delete conf.cache[id]; | ||
dispose(value); | ||
dispose.call(conf.memoized['_memoize:context_'], value); | ||
}); | ||
@@ -27,0 +27,0 @@ |
@@ -5,3 +5,4 @@ // Memoized methods factory | ||
var global = require('es5-ext/lib/global') | ||
var d = require('es5-ext/lib/Object/descriptor') | ||
, global = require('es5-ext/lib/global') | ||
, extend = require('es5-ext/lib/Object/extend') | ||
@@ -27,6 +28,9 @@ , isString = require('es5-ext/lib/String/is-string') | ||
conf.memoized = function () { | ||
var memoized; | ||
if (this && (this !== global)) { | ||
method.descriptor.value = conf.memoize(conf.fn.bind(this), options); | ||
memoized = method.descriptor.value = | ||
conf.memoize(conf.fn.bind(this), options); | ||
defineProperty(this, method.name, method.descriptor); | ||
return method.descriptor.value.apply(this, arguments); | ||
defineProperty(memoized, '_memoize:context_', d(this)); | ||
return memoized.apply(this, arguments); | ||
} | ||
@@ -33,0 +37,0 @@ return fn.apply(this, arguments); |
@@ -5,3 +5,4 @@ // Memoize working in primitive mode | ||
var hasListeners = require('event-emitter/lib/has-listeners') | ||
var CustomError = require('es5-ext/lib/Error/custom') | ||
, hasListeners = require('event-emitter/lib/has-listeners') | ||
@@ -53,2 +54,5 @@ , getId0 = function () { return ''; } | ||
} | ||
if (cache.hasOwnProperty(id)) { | ||
throw new CustomError("Circular invocation", 'CIRCULAR_INVOCATION'); | ||
} | ||
cache[id] = value; | ||
@@ -65,2 +69,5 @@ initListeners && conf.emit('init', id); | ||
value = apply.call(conf.fn, this, arguments); | ||
if (cache.hasOwnProperty(id)) { | ||
throw new CustomError("Circular invocation", 'CIRCULAR_INVOCATION'); | ||
} | ||
cache[id] = value; | ||
@@ -67,0 +74,0 @@ initListeners && conf.emit('init', id); |
@@ -5,15 +5,14 @@ // Memoize working in object mode (supports any type of arguments) | ||
var indexOf = require('es5-ext/lib/Array/prototype/e-index-of') | ||
var CustomError = require('es5-ext/lib/Error/custom') | ||
, indexOf = require('es5-ext/lib/Array/prototype/e-index-of') | ||
, hasListeners = require('event-emitter/lib/has-listeners') | ||
, apply = Function.prototype.apply | ||
, apply = Function.prototype.apply; | ||
, getId0 = function () { return ''; }; | ||
// Results are saved internally within array matrix: | ||
// [0] -> Result of calling function with no arguments | ||
// [1] -> Matrix that keeps results when function is called with one argument | ||
// [1][0] -> Array of arguments with which | ||
// [1][0] -> Array of arguments with which | ||
// function have been called | ||
// [1][1] -> Array of results that matches [1][0] array | ||
// [1][1] -> Array of results that matches [1][0] array | ||
// [2] -> Matrix that keeps results when function is called with two arguments | ||
@@ -26,3 +25,3 @@ // [2][0] -> Array of first (of two) arguments with which | ||
// function have been called. | ||
// [2][1][x][1] -> Array of results that matches [2][1][x][0] | ||
// [2][1][x][1] -> Array of results that matches [2][1][x][0] | ||
// arguments array | ||
@@ -36,4 +35,10 @@ // ...and so on | ||
if (length === 0) { | ||
get = set = clear = conf.get = getId0; | ||
conf.clearAll = function () { cache = conf.cache = {}; }; | ||
map = null; | ||
get = conf.get = function () { return map; }; | ||
set = function () { return ((map = 1)); }; | ||
clear = function () { map = null; }; | ||
conf.clearAll = function () { | ||
map = null; | ||
cache = conf.cache = {}; | ||
}; | ||
} else { | ||
@@ -45,3 +50,4 @@ count = 0; | ||
get = conf.get = function (args) { | ||
return map2[indexOf.call(map1, args[0])]; | ||
var index = indexOf.call(map1, args[0]); | ||
return (index === -1) ? null : map2[index]; | ||
}; | ||
@@ -71,9 +77,7 @@ set = function (args) { | ||
if (length === 0) { | ||
return set[length]; | ||
return set[length] || null; | ||
} else if ((set = set[length])) { | ||
while (index < (length - 1)) { | ||
i = indexOf.call(set[0], args[index]); | ||
if (i === -1) { | ||
return; | ||
} | ||
if (i === -1) return null; | ||
set = set[1][i]; | ||
@@ -83,8 +87,6 @@ ++index; | ||
i = indexOf.call(set[0], args[index]); | ||
if (i === -1) { | ||
return; | ||
} | ||
return set[1][i]; | ||
if (i === -1) return null; | ||
return set[1][i] || null; | ||
} | ||
return; | ||
return null; | ||
}; | ||
@@ -161,5 +163,3 @@ set = function (args) { | ||
i = indexOf.call(set[0], args[index]); | ||
if (i === -1) { | ||
return null; | ||
} | ||
if (i === -1) return null; | ||
set = set[1][i]; | ||
@@ -169,6 +169,4 @@ ++index; | ||
i = indexOf.call(set[0], args[index]); | ||
if (i === -1) { | ||
return null; | ||
} | ||
return set[1][i]; | ||
if (i === -1) return null; | ||
return set[1][i] || null; | ||
}; | ||
@@ -229,3 +227,3 @@ set = function (args) { | ||
var id = get(arguments), value; | ||
if (cache.hasOwnProperty(id)) { | ||
if (id != null) { | ||
hitListeners && conf.emit('hit', id, arguments, this); | ||
@@ -235,2 +233,6 @@ return cache[id]; | ||
value = apply.call(fn, this, arguments); | ||
id = get(arguments); | ||
if (id != null) { | ||
throw new CustomError("Circular invocation", 'CIRCULAR_INVOCATION'); | ||
} | ||
id = set(arguments); | ||
@@ -237,0 +239,0 @@ cache[id] = value; |
{ | ||
"name": "memoizee", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"description": "Complete memoize/cache solution. Works with any type and length of function arguments", | ||
@@ -37,3 +37,3 @@ "main": "lib", | ||
"dependencies": { | ||
"es5-ext": "0.9.x", | ||
"es5-ext": "~0.9.2", | ||
"event-emitter": "~0.2.1", | ||
@@ -43,3 +43,3 @@ "next-tick": "0.1.x" | ||
"devDependencies": { | ||
"tad": "0.1.x" | ||
"tad": "~0.1.15" | ||
}, | ||
@@ -46,0 +46,0 @@ "author": "Mariusz Nowak <medikoo+memoize@medikoo.com> (http://www.medikoo.com/)", |
@@ -40,8 +40,33 @@ # Memoize – Complete memoize/cache solution for JavaScript | ||
$ npm install memoizee | ||
``` | ||
$ npm install memoizee | ||
``` | ||
### Browser | ||
Browser bundle can be easily created with help of [modules-webmake](https://github.com/medikoo/modules-webmake). Mind that it relies on some EcmaScript5 features, so for older browsers you need as well [es5-shim](https://github.com/kriskowal/es5-shim) | ||
Browser bundle can be easily created with help of [modules-webmake](https://github.com/medikoo/modules-webmake). Assuming that you have latest [Node.js](http://nodejs.org/) and [Git](http://git-scm.com/) installed, following will work in command shell of any system (Linux/MacOS/Windows): | ||
``` | ||
$ npm install -g webmake | ||
$ git clone git://github.com/medikoo/memoize.git | ||
$ cd memoize | ||
$ npm install | ||
$ cd .. | ||
$ webmake --name=memoize memoize/lib/index.js memoize.js | ||
``` | ||
Last command bundles memoize with all it's functionalities, but you may need just a subset, you can have that by addressing specific modules directly, e.g. with following you will build just primitive mode with support for asynchronous functions: | ||
``` | ||
$ webmake --name=memoize --include=memoize/lib/ext/async.js memoize/lib/primitive.js memoize.js | ||
``` | ||
If you work with AMD modules, add _amd_ option, so generated bundle is one: | ||
``` | ||
$ webmake --name=memoize --amd memoize/lib/index.js memoize.js | ||
``` | ||
_Mind that memoize relies on some EcmaScript5 features, so for older browsers you need to load as well [es5-shim](https://github.com/kriskowal/es5-shim)_ | ||
## Configuration | ||
@@ -103,2 +128,6 @@ | ||
__Note. If your arguments are collections (arrays or hashes) that you want to memoize by content (not by self objects), you need to cast them to strings__, for that just use [primitive mode](#primitive-mode). Arrays have standard string representation and work with primitive mode out of a box, for hashes you need to define `toString` method, that will produce unique string descriptions. | ||
Similarly __if you want to memoize functions by their code representation not by their objects, you should use primitive mode__. | ||
### Memoizing asynchronous functions | ||
@@ -105,0 +134,0 @@ |
@@ -44,2 +44,28 @@ 'use strict'; | ||
}, | ||
"Method": function (a) { | ||
var fn, i = 0, value = []; | ||
fn = function (x, y) { | ||
++i; | ||
return x + y; | ||
}; | ||
Object.defineProperty(value, 'mfn', { value: memoize(fn, { | ||
method: 'mfn', | ||
dispose: function (val) { this.push(val); } | ||
}), configurable: true }); | ||
value.mfn(3, 7); | ||
value.mfn(5, 8); | ||
value.mfn(12, 4); | ||
a.deep(value, [], "Pre"); | ||
value.mfn.clear(5, 8); | ||
a.deep(value, [13], "#1"); | ||
value.length = 0; | ||
value.mfn.clear(12, 4); | ||
a.deep(value, [16], "#2"); | ||
value.length = 0; | ||
value.mfn(77, 11); | ||
value.mfn.clearAll(); | ||
a.deep(value, [10, 88], "Clear all"); | ||
}, | ||
"Ref counter": function (a) { | ||
@@ -46,0 +72,0 @@ var mfn, fn, i = 0, value = []; |
@@ -39,4 +39,21 @@ 'use strict'; | ||
a(i, 2, "Called twice"); | ||
}, | ||
"Circular": function (a) { | ||
var i = 0, fn; | ||
fn = t(function (x) { | ||
if (++i < 2) fn(x); | ||
}); | ||
a.throws(function () { | ||
fn('foo'); | ||
}, 'CIRCULAR_INVOCATION'); | ||
i = 0; | ||
fn = t(function (x, y) { | ||
if (++i < 2) fn(x, y); | ||
}); | ||
a.throws(function () { | ||
fn('foo', 'bar'); | ||
}, 'CIRCULAR_INVOCATION'); | ||
} | ||
}; | ||
}; |
@@ -125,3 +125,3 @@ 'use strict'; | ||
fn = function (a, b, c) { | ||
return a + ++i; | ||
return a + (++i); | ||
}; | ||
@@ -138,5 +138,5 @@ | ||
a(mfn(6, x, 1), 8, "Reinit"); | ||
a(i, 2, "Reinit count") | ||
a(i, 2, "Reinit count"); | ||
a(mfn(3, x, 1), 8, "Reinit Cached"); | ||
a(i, 2, "Reinit count") | ||
a(i, 2, "Reinit count"); | ||
}, | ||
@@ -155,5 +155,5 @@ "1": function (a) { | ||
a(mfn(3, x, 1), 6, "Reinit"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
a(mfn(3, x, 1), 6, "Reinit Cached"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
}, | ||
@@ -172,5 +172,5 @@ "3": function (a) { | ||
a(mfn(3, x, 1), 6, "Reinit"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
a(mfn(3, x, 1), 6, "Reinit Cached"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
}, | ||
@@ -189,9 +189,9 @@ "Any": function (a) { | ||
a(mfn(3, x, 1), 6, "Reinit"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
a(mfn(3, x, 1), 6, "Reinit Cached"); | ||
a(i, 3, "Reinit count") | ||
a(i, 3, "Reinit count"); | ||
} | ||
}; | ||
}, | ||
"All": function () { | ||
"All": function (a) { | ||
var i = 0, fn, x = {}; | ||
@@ -217,4 +217,13 @@ | ||
} | ||
}, | ||
"Circular": function (a) { | ||
var i = 0, fn; | ||
fn = t(function (x) { | ||
if (++i < 2) fn(x); | ||
}); | ||
a.throws(function () { | ||
fn(34); | ||
}, 'CIRCULAR_INVOCATION'); | ||
} | ||
}; | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
127908
3640
376
Updatedes5-ext@~0.9.2