'use strict'; /*@ Ox.cache Memoize a function > Ox.test.fn(10) == Ox.test.fn(10); true > Ox.test.fn(10) == Ox.test.fn.clear()(10); false @*/ Ox.cache = function(fn, options) { options = Ox.extend({ async: false, key: JSON.stringify }, options || {}) var cache = {}, ret = function() { var args = Ox.makeArray(arguments), callback, key = options.key(args); function callback() { // cache all arguments passed to callback cache[key] = Ox.makeArray(arguments); // call the original callback Ox.last(args).apply(this, arguments); } if (options.async) { if (!(key in cache)) { // call function with patched callback fn.apply(this, Ox.merge(Ox.sub(args, 0, -1), callback)); } else { // call callback with cached arguments callback.apply(this, cache[key]) } } else { if (!(key in cache)) { cache[key] = fn.apply(this, args); } return cache[key]; } }; ret.clear = function() { if (arguments.length == 0) { cache = {}; } else { Ox.toArray(arguments).forEach(function(key) { delete cache[key]; }); } return ret; } return ret; }; /*@ Ox.void Returns nothing and calls options callback without arguments This can be useful to combine a synchronous and an asynchronous code path. @*/ Ox.void = function(callback) { Ox.isFunction(callback) && callback(); };