diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..18dd725 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +/plain.js +/profile.js +/weak-plain.js +/weak.js +/methods-plain.js +/methods.js +/lib/*.js +/ext/*.js +/normalizers/*.js diff --git a/.gitignore b/.gitignore index db18a21..3ac05a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,15 @@ /.nyc_output /coverage -/node_modules +node_modules/ npm-debug.log /package-lock.json + +/plain.js +/profile.js +/weak-plain.js +/weak.js +/methods-plain.js +/methods.js +/lib/*.js +/ext/*.js +/normalizers/*.js diff --git a/benchmark/fibonacci.js b/benchmark/fibonacci.mjs similarity index 61% rename from benchmark/fibonacci.js rename to benchmark/fibonacci.mjs index 655810f..aee1211 100644 --- a/benchmark/fibonacci.js +++ b/benchmark/fibonacci.mjs @@ -1,39 +1,38 @@ /* global console */ /* eslint no-console: 0, id-length: 0 */ -"use strict"; - // Simple benchmark for very simple memoization case (fibonacci series) // To run it, do following in memoizee package path: // -// $ npm install underscore lodash lru-cache secondary-cache -// $ node benchmark/fibonacci.js - -var forEach = require("es5-ext/object/for-each") - , pad = require("es5-ext/string/#/pad") - , memoizee = require("..") - , underscore = require("underscore").memoize - , lodash = require("lodash").memoize - , lruCache = require("lru-cache") - , lruSecondary = require("secondary-cache/lib/lru-cache"); - -var now = Date.now - , time - , getFib - , lru - , memo - , total - , index = 3000 - , count = 10 - , i - , lruMax = 1000 - , data = {} - , lruObj; - -getFib = function (memoize, opts) { - var fib = memoize(function (x) { return x < 2 ? 1 : fib(x - 1) + fib(x - 2); }, opts); +// $ cd benchmark && npm install && cd .. +// $ node benchmark/fibonacci.mjs + +import forEach from "es5-ext/object/for-each.js"; +import pad from "es5-ext/string/%23/pad.js"; +import memoizee from "../index.mjs"; +import { memoize as underscore } from "underscore"; +import lodash from "lodash/memoize.js"; +import * as lruCache from "lru-cache"; +import { Cache as lruSecondaryCache } from "secondary-cache"; + +var now = Date.now, + time, + lru, + memo, + total, + index = 3000, + count = 10, + i, + lruMax = 1000, + data = {}, + lruObj; + +async function getFib(memoize, opts) { + const fib = await memoize(function (x) { + return x < 2 ? 1 : fib(x - 1) + fib(x - 2); + }, opts); return fib; -}; +} lru = function (x) { var value = lruObj.get(x); @@ -48,8 +47,8 @@ console.log("Fibonacci", index, "x" + count + ":\n"); total = 0; i = count; +memo = await getFib(memoizee); while (i--) { - memo = getFib(memoizee); time = now(); memo(index); total += now() - time; @@ -58,8 +57,8 @@ data["Memoizee (object mode)"] = total; total = 0; i = count; +memo = await getFib(memoizee, { primitive: true }); while (i--) { - memo = getFib(memoizee, { primitive: true }); time = now(); memo(index); total += now() - time; @@ -68,8 +67,8 @@ data["Memoizee (primitive mode)"] = total; total = 0; i = count; +memo = await getFib(underscore); while (i--) { - memo = getFib(underscore); time = now(); memo(index); total += now() - time; @@ -78,8 +77,8 @@ data.Underscore = total; total = 0; i = count; +memo = await getFib(lodash); while (i--) { - memo = getFib(lodash); time = now(); memo(index); total += now() - time; @@ -88,8 +87,8 @@ data["Lo-dash"] = total; total = 0; i = count; +memo = await getFib(memoizee, { primitive: true, max: lruMax }); while (i--) { - memo = getFib(memoizee, { primitive: true, max: lruMax }); time = now(); memo(index); total += now() - time; @@ -98,8 +97,8 @@ data["Memoizee (primitive mode) LRU (max: 1000)"] = total; total = 0; i = count; +memo = await getFib(memoizee, { max: lruMax }); while (i--) { - memo = getFib(memoizee, { max: lruMax }); time = now(); memo(index); total += now() - time; @@ -108,8 +107,8 @@ data["Memoizee (object mode) LRU (max: 1000)"] = total; total = 0; i = count; +lruObj = new lruCache.LRUCache({ max: lruMax }); while (i--) { - lruObj = lruCache({ max: lruMax }); time = now(); lru(index); total += now() - time; @@ -118,8 +117,8 @@ data["lru-cache LRU (max: 1000)"] = total; total = 0; i = count; +lruObj = new lruSecondaryCache(lruMax); while (i--) { - lruObj = lruSecondary(lruMax); time = now(); lru(index); total += now() - time; @@ -131,6 +130,7 @@ forEach( function (value, name, obj, currentIndex) { console.log(currentIndex + 1 + ":", pad.call(value, " ", 5) + "ms ", name); }, - null, - function (a, b) { return this[a] - this[b]; } + function (a, b) { + return this[a] - this[b]; + }, ); diff --git a/benchmark/package.json b/benchmark/package.json new file mode 100644 index 0000000..0a9ca8c --- /dev/null +++ b/benchmark/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "lodash": "4.17.21", + "secondary-cache": "2.0.0", + "lru-cache": "11.0.0", + "underscore": "1.13.7" + } +} diff --git a/ext/async.js b/ext/async.mjs similarity index 92% rename from ext/async.js rename to ext/async.mjs index 94b2dbf..267ff76 100644 --- a/ext/async.js +++ b/ext/async.mjs @@ -2,17 +2,15 @@ // Support for asynchronous functions -"use strict"; - -var aFrom = require("es5-ext/array/from") - , objectMap = require("es5-ext/object/map") - , mixin = require("es5-ext/object/mixin") - , defineLength = require("es5-ext/function/_define-length") - , nextTick = require("next-tick"); +import aFrom from "es5-ext/array/from/index.js"; +import objectMap from "es5-ext/object/map.js"; +import mixin from "es5-ext/object/mixin.js"; +import defineLength from "es5-ext/function/_define-length.js"; +import nextTick from "next-tick"; var slice = Array.prototype.slice, apply = Function.prototype.apply, create = Object.create; -require("../lib/registered-extensions").async = function (tbi, conf) { +export default function asyncExtension(tbi, conf) { var waiting = create(null) , cache = create(null) , base = conf.memoized @@ -151,4 +149,4 @@ require("../lib/registered-extensions").async = function (tbi, conf) { "clearasync", objectMap(oldCache, function (data) { return slice.call(data.args, 1); }) ); }); -}; +} diff --git a/ext/dispose.js b/ext/dispose.mjs similarity index 57% rename from ext/dispose.js rename to ext/dispose.mjs index 4f79646..711863c 100644 --- a/ext/dispose.js +++ b/ext/dispose.mjs @@ -1,16 +1,16 @@ // Call dispose callback on each cache purge -"use strict"; +import callable from "es5-ext/object/valid-callable.js"; +import forEach from "es5-ext/object/for-each.js"; +import async from "./async.mjs"; +import promise from "./promise.mjs"; -var callable = require("es5-ext/object/valid-callable") - , forEach = require("es5-ext/object/for-each") - , extensions = require("../lib/registered-extensions") - , apply = Function.prototype.apply; +var apply = Function.prototype.apply; -extensions.dispose = function (dispose, conf, options) { +export default function disposeExtension(dispose, conf, options) { var del; callable(dispose); - if ((options.async && extensions.async) || (options.promise && extensions.promise)) { + if ((options.async && async) || (options.promise && promise)) { conf.on( "deleteasync", (del = function (id, resultArray) { apply.call(dispose, null, resultArray); }) @@ -24,4 +24,4 @@ extensions.dispose = function (dispose, conf, options) { conf.on("clear", function (cache) { forEach(cache, function (result, id) { del(id, result); }); }); -}; +} diff --git a/ext/max-age.js b/ext/max-age.mjs similarity index 81% rename from ext/max-age.js rename to ext/max-age.mjs index 1ec0b2f..671b7fb 100644 --- a/ext/max-age.js +++ b/ext/max-age.mjs @@ -2,28 +2,24 @@ // Timeout cached values -"use strict"; - -var aFrom = require("es5-ext/array/from") - , forEach = require("es5-ext/object/for-each") - , nextTick = require("next-tick") - , isPromise = require("is-promise") - , timeout = require("timers-ext/valid-timeout") - , extensions = require("../lib/registered-extensions"); +import aFrom from "es5-ext/array/from/index.js"; +import forEach from "es5-ext/object/for-each.js"; +import nextTick from "next-tick"; +import isPromise from "is-promise"; +import timeout from "timers-ext/valid-timeout.js"; +import async from "./async.mjs"; +import promise from "./promise.mjs"; var noop = Function.prototype, max = Math.max, min = Math.min, create = Object.create; -extensions.maxAge = function (maxAge, conf, options) { +export default function maxAgeExtension(maxAge, conf, options) { var timeouts, postfix, preFetchAge, preFetchTimeouts; maxAge = timeout(maxAge); if (!maxAge) return; timeouts = create(null); - postfix = - (options.async && extensions.async) || (options.promise && extensions.promise) - ? "async" - : ""; + postfix = (options.async && async) || (options.promise && promise) ? "async" : ""; conf.on("set" + postfix, function (id) { timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge); if (typeof timeouts[id].unref === "function") timeouts[id].unref(); @@ -55,7 +51,7 @@ extensions.maxAge = function (maxAge, conf, options) { preFetchAge = (1 - preFetchAge) * maxAge; conf.on("get" + postfix, function (id, args, context) { if (!preFetchTimeouts[id]) { - preFetchTimeouts[id] = "nextTick"; + preFetchTimeouts[id] = "nextTick.js"; nextTick(function () { var result; if (preFetchTimeouts[id] !== "nextTick") return; @@ -87,4 +83,4 @@ extensions.maxAge = function (maxAge, conf, options) { preFetchTimeouts = {}; } }); -}; +} diff --git a/ext/max.js b/ext/max.mjs similarity index 54% rename from ext/max.js rename to ext/max.mjs index 8f48adf..84de9a1 100644 --- a/ext/max.js +++ b/ext/max.mjs @@ -1,22 +1,18 @@ // Limit cache size, LRU (least recently used) algorithm. -"use strict"; +import toPosInteger from "es5-ext/number/to-pos-integer.js"; +import lruQueue from "lru-queue"; +import async from "./async.mjs"; +import promise from "./promise.mjs"; -var toPosInteger = require("es5-ext/number/to-pos-integer") - , lruQueue = require("lru-queue") - , extensions = require("../lib/registered-extensions"); - -extensions.max = function (max, conf, options) { +export default function maxExtension(max, conf, options) { var postfix, queue, hit; max = toPosInteger(max); if (!max) return; queue = lruQueue(max); - postfix = - (options.async && extensions.async) || (options.promise && extensions.promise) - ? "async" - : ""; + postfix = (options.async && async) || (options.promise && promise) ? "async" : ""; conf.on( "set" + postfix, @@ -29,4 +25,4 @@ extensions.max = function (max, conf, options) { conf.on("get" + postfix, hit); conf.on("delete" + postfix, queue.delete); conf.on("clear" + postfix, queue.clear); -}; +} diff --git a/ext/promise.js b/ext/promise.mjs similarity index 90% rename from ext/promise.js rename to ext/promise.mjs index 4b7163c..0c81c4f 100644 --- a/ext/promise.js +++ b/ext/promise.mjs @@ -2,19 +2,17 @@ // Support for functions returning promise -"use strict"; - -var objectMap = require("es5-ext/object/map") - , primitiveSet = require("es5-ext/object/primitive-set") - , ensureString = require("es5-ext/object/validate-stringifiable-value") - , toShortString = require("es5-ext/to-short-string-representation") - , isPromise = require("is-promise") - , nextTick = require("next-tick"); +import objectMap from "es5-ext/object/map.js"; +import primitiveSet from "es5-ext/object/primitive-set.js"; +import ensureString from "es5-ext/object/validate-stringifiable-value.js"; +import toShortString from "es5-ext/to-short-string-representation.js"; +import isPromise from "is-promise"; +import nextTick from "next-tick"; var create = Object.create , supportedModes = primitiveSet("then", "then:finally", "done", "done:finally"); -require("../lib/registered-extensions").promise = function (mode, conf) { +export default function promiseExtension(mode, conf) { var waiting = create(null), cache = create(null), promises = create(null); if (mode === true) { @@ -144,4 +142,4 @@ require("../lib/registered-extensions").promise = function (mode, conf) { promises = create(null); conf.emit("clearasync", objectMap(oldCache, function (data) { return [data]; })); }); -}; +} diff --git a/ext/ref-counter.js b/ext/ref-counter.mjs similarity index 67% rename from ext/ref-counter.js rename to ext/ref-counter.mjs index 396dae5..97c07f3 100644 --- a/ext/ref-counter.js +++ b/ext/ref-counter.mjs @@ -1,20 +1,16 @@ // Reference counter, useful for garbage collector like functionality -"use strict"; +import d from "d"; +import async from "./async.mjs"; +import promise from "./promise.mjs"; +var create = Object.create; +var defineProperties = Object.defineProperties; -var d = require("d") - , extensions = require("../lib/registered-extensions") - , create = Object.create - , defineProperties = Object.defineProperties; - -extensions.refCounter = function (ignore, conf, options) { +export default function refCounterExtension(ignore, conf, options) { var cache, postfix; cache = create(null); - postfix = - (options.async && extensions.async) || (options.promise && extensions.promise) - ? "async" - : ""; + postfix = (options.async && async) || (options.promise && promise) ? "async" : ""; conf.on("set" + postfix, function (id, length) { cache[id] = length || 1; }); conf.on("get" + postfix, function (id) { ++cache[id]; }); @@ -39,4 +35,4 @@ extensions.refCounter = function (ignore, conf, options) { return cache[id]; }), }); -}; +} diff --git a/index.js b/index.js index 7639ee3..b624991 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,8 @@ "use strict"; -var normalizeOpts = require("es5-ext/object/normalize-options") - , resolveLength = require("./lib/resolve-length") - , plain = require("./plain"); +var normalizeOpts = require("es5-ext/object/normalize-options"); +var resolveLength = require("./lib/resolve-length.js"); +var plain = require("./plain.js"); module.exports = function (fn/*, options*/) { var options = normalizeOpts(arguments[1]), length; @@ -12,23 +12,23 @@ module.exports = function (fn/*, options*/) { if (length !== 0) { if (options.primitive) { if (length === false) { - options.normalizer = require("./normalizers/primitive"); + options.normalizer = require("./normalizers/primitive.js"); } else if (length > 1) { - options.normalizer = require("./normalizers/get-primitive-fixed")(length); + options.normalizer = require("./normalizers/get-primitive-fixed.js")(length); } - } else if (length === false) options.normalizer = require("./normalizers/get")(); - else if (length === 1) options.normalizer = require("./normalizers/get-1")(); - else options.normalizer = require("./normalizers/get-fixed")(length); + } else if (length === false) options.normalizer = require("./normalizers/get.js")(); + else if (length === 1) options.normalizer = require("./normalizers/get-1.js")(); + else options.normalizer = require("./normalizers/get-fixed.js")(length); } } // Assure extensions - if (options.async) require("./ext/async"); - if (options.promise) require("./ext/promise"); - if (options.dispose) require("./ext/dispose"); - if (options.maxAge) require("./ext/max-age"); - if (options.max) require("./ext/max"); - if (options.refCounter) require("./ext/ref-counter"); + if (options.async) require("./ext/async.js"); + if (options.promise) require("./ext/promise.js"); + if (options.dispose) require("./ext/dispose.js"); + if (options.maxAge) require("./ext/max-age.js"); + if (options.max) require("./ext/max.js"); + if (options.refCounter) require("./ext/ref-counter.js"); return plain(fn, options); }; diff --git a/index.mjs b/index.mjs new file mode 100644 index 0000000..bd1de8c --- /dev/null +++ b/index.mjs @@ -0,0 +1,36 @@ +import normalizeOpts from "es5-ext/object/normalize-options.js"; +import resolveLength from "./lib/resolve-length.mjs"; +import plain from "./plain.mjs"; + +export default async function memoize(fn/*, options*/) { + var options = normalizeOpts(arguments[1]), length; + + if (!options.normalizer) { + length = options.length = resolveLength(options.length, fn.length, options.async); + if (length !== 0) { + if (options.primitive) { + if (length === false) { + options.normalizer = (await import("./normalizers/primitive.mjs")).default; + } else if (length > 1) { + options.normalizer = ( + await import("./normalizers/get-primitive-fixed.mjs") + ).default(length); + } + } else if (length === false) + options.normalizer = (await import("./normalizers/get.mjs")).default(); + else if (length === 1) + options.normalizer = (await import("./normalizers/get-1.mjs")).default(); + else options.normalizer = (await import("./normalizers/get-fixed.mjs")).default(length); + } + } + + // Assure extensions + if (options.async) (await import("./ext/async.mjs")).default; + if (options.promise) (await import("./ext/promise.mjs")).default; + if (options.dispose) (await import("./ext/dispose.mjs")).default; + if (options.maxAge) (await import("./ext/max-age.mjs")).default; + if (options.max) (await import("./ext/max.mjs")).default; + if (options.refCounter) (await import("./ext/ref-counter.mjs")).default; + + return plain(fn, options); +} diff --git a/lib/configure-map.js b/lib/configure-map.mjs similarity index 91% rename from lib/configure-map.js rename to lib/configure-map.mjs index e11aa34..c58c294 100644 --- a/lib/configure-map.js +++ b/lib/configure-map.mjs @@ -1,13 +1,11 @@ /* eslint no-eq-null: 0, eqeqeq: 0, no-unused-vars: 0 */ -"use strict"; - -var customError = require("es5-ext/error/custom") - , defineLength = require("es5-ext/function/_define-length") - , d = require("d") - , ee = require("event-emitter").methods - , resolveResolve = require("./resolve-resolve") - , resolveNormalize = require("./resolve-normalize"); +import customError from "es5-ext/error/custom.js"; +import defineLength from "es5-ext/function/_define-length.js"; +import d from "d"; +import { methods as ee } from "event-emitter"; +import resolveResolve from "./resolve-resolve.mjs"; +import resolveNormalize from "./resolve-normalize.mjs"; var apply = Function.prototype.apply , call = Function.prototype.call @@ -16,8 +14,8 @@ var apply = Function.prototype.apply , on = ee.on , emit = ee.emit; -module.exports = function (original, length, options) { - var cache = create(null) +export default function configureMap(original, length, options) { + let cache = create(null) , conf , memLength , get @@ -179,4 +177,4 @@ module.exports = function (original, length, options) { _has: d(extHas), }); return conf; -}; +} diff --git a/lib/methods.js b/lib/methods.js deleted file mode 100644 index d8cd8a7..0000000 --- a/lib/methods.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; - -var forEach = require("es5-ext/object/for-each") - , normalizeOpts = require("es5-ext/object/normalize-options") - , callable = require("es5-ext/object/valid-callable") - , lazy = require("d/lazy") - , resolveLength = require("./resolve-length") - , extensions = require("./registered-extensions"); - -module.exports = function (memoize) { - return function (props) { - forEach(props, function (desc) { - var fn = callable(desc.value), length; - desc.value = function (options) { - if (options.getNormalizer) { - options = normalizeOpts(options); - if (length === undefined) { - length = resolveLength( - options.length, fn.length, options.async && extensions.async - ); - } - options.normalizer = options.getNormalizer(length); - delete options.getNormalizer; - } - return memoize(fn.bind(this), options); - }; - }); - return lazy(props); - }; -}; diff --git a/lib/methods.mjs b/lib/methods.mjs new file mode 100644 index 0000000..ab66ac5 --- /dev/null +++ b/lib/methods.mjs @@ -0,0 +1,26 @@ +import forEach from "es5-ext/object/for-each.js"; +import normalizeOpts from "es5-ext/object/normalize-options.js"; +import callable from "es5-ext/object/valid-callable.js"; +import lazy from "d/lazy.js"; +import resolveLength from "./resolve-length.mjs"; +import { async } from "./registered-extensions.mjs"; + +export default function methods(memoize) { + return function (props) { + forEach(props, function (desc) { + var fn = callable(desc.value), length; + desc.value = function (options) { + if (options.getNormalizer) { + options = normalizeOpts(options); + if (length === undefined) { + length = resolveLength(options.length, fn.length, options.async && async); + } + options.normalizer = options.getNormalizer(length); + delete options.getNormalizer; + } + return memoize(fn.bind(this), options); + }; + }); + return lazy(props); + }; +} diff --git a/lib/registered-extensions.js b/lib/registered-extensions.js deleted file mode 100644 index 3918c74..0000000 --- a/lib/registered-extensions.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; diff --git a/lib/registered-extensions.mjs b/lib/registered-extensions.mjs new file mode 100644 index 0000000..5cfec67 --- /dev/null +++ b/lib/registered-extensions.mjs @@ -0,0 +1,6 @@ +export { default as async } from "../ext/async.mjs"; +export { default as dispose } from "../ext/dispose.mjs"; +export { default as maxAge } from "../ext/max-age.mjs"; +export { default as max } from "../ext/max.mjs"; +export { default as promise } from "../ext/promise.mjs"; +export { default as refCounter } from "../ext/ref-counter.mjs"; diff --git a/lib/resolve-length.js b/lib/resolve-length.mjs similarity index 62% rename from lib/resolve-length.js rename to lib/resolve-length.mjs index a02a8a9..ebbe665 100644 --- a/lib/resolve-length.js +++ b/lib/resolve-length.mjs @@ -1,8 +1,6 @@ -"use strict"; +import toPosInt from "es5-ext/number/to-pos-integer.js"; -var toPosInt = require("es5-ext/number/to-pos-integer"); - -module.exports = function (optsLength, fnLength, isAsync) { +export default function resolveLength(optsLength, fnLength, isAsync) { var length; if (isNaN(optsLength)) { length = fnLength; @@ -12,4 +10,4 @@ module.exports = function (optsLength, fnLength, isAsync) { } if (optsLength === false) return false; return toPosInt(optsLength); -}; +} diff --git a/lib/resolve-normalize.js b/lib/resolve-normalize.mjs similarity index 80% rename from lib/resolve-normalize.js rename to lib/resolve-normalize.mjs index f0bc719..af31029 100644 --- a/lib/resolve-normalize.js +++ b/lib/resolve-normalize.mjs @@ -1,8 +1,6 @@ -"use strict"; +import callable from "es5-ext/object/valid-callable.js"; -var callable = require("es5-ext/object/valid-callable"); - -module.exports = function (userNormalizer) { +export default function resolveNormalize(userNormalizer) { var normalizer; if (typeof userNormalizer === "function") return { set: userNormalizer, get: userNormalizer }; normalizer = { get: callable(userNormalizer.get) }; @@ -14,4 +12,4 @@ module.exports = function (userNormalizer) { } normalizer.set = normalizer.get; return normalizer; -}; +} diff --git a/lib/resolve-resolve.js b/lib/resolve-resolve.mjs similarity index 63% rename from lib/resolve-resolve.js rename to lib/resolve-resolve.mjs index 577d51d..e9fe5b3 100644 --- a/lib/resolve-resolve.js +++ b/lib/resolve-resolve.mjs @@ -1,8 +1,6 @@ -"use strict"; - -var toArray = require("es5-ext/array/to-array") - , isValue = require("es5-ext/object/is-value") - , callable = require("es5-ext/object/valid-callable"); +import toArray from "es5-ext/array/to-array.js"; +import isValue from "es5-ext/object/is-value.js"; +import callable from "es5-ext/object/valid-callable.js"; var slice = Array.prototype.slice, resolveArgs; @@ -12,8 +10,8 @@ resolveArgs = function (args) { ); }; -module.exports = function (resolvers) { +export default function resolveResolve(resolvers) { resolvers = toArray(resolvers); resolvers.forEach(function (resolve) { if (isValue(resolve)) callable(resolve); }); return resolveArgs.bind(resolvers); -}; +} diff --git a/lib/weak.js b/lib/weak.mjs similarity index 81% rename from lib/weak.js rename to lib/weak.mjs index a36e43d..9320e4b 100644 --- a/lib/weak.js +++ b/lib/weak.mjs @@ -1,21 +1,19 @@ -"use strict"; - -var customError = require("es5-ext/error/custom") - , defineLength = require("es5-ext/function/_define-length") - , partial = require("es5-ext/function/#/partial") - , copy = require("es5-ext/object/copy") - , normalizeOpts = require("es5-ext/object/normalize-options") - , callable = require("es5-ext/object/valid-callable") - , d = require("d") - , WeakMap = require("es6-weak-map") - , resolveLength = require("./resolve-length") - , extensions = require("./registered-extensions") - , resolveResolve = require("./resolve-resolve") - , resolveNormalize = require("./resolve-normalize"); +import customError from "es5-ext/error/custom.js"; +import defineLength from "es5-ext/function/_define-length.js"; +import partial from "es5-ext/function/%23/partial.js"; +import copy from "es5-ext/object/copy.js"; +import normalizeOpts from "es5-ext/object/normalize-options.js"; +import callable from "es5-ext/object/valid-callable.js"; +import d from "d"; +import WeakMap from "es6-weak-map.js"; +import resolveLength from "./resolve-length.mjs"; +import { async } from "./registered-extensions.mjs"; +import resolveResolve from "./resolve-resolve.mjs"; +import resolveNormalize from "./resolve-normalize.mjs"; var slice = Array.prototype.slice, defineProperties = Object.defineProperties; -module.exports = function (memoize) { +export default function weak(memoize) { return function (fn/*, options*/) { var map, length, options = normalizeOpts(arguments[1]), memoized, resolve, normalizer; @@ -24,7 +22,7 @@ module.exports = function (memoize) { // Do not memoize already memoized function if (hasOwnProperty.call(fn, "__memoized__") && !options.force) return fn; - length = resolveLength(options.length, fn.length, options.async && extensions.async); + length = resolveLength(options.length, fn.length, options.async && async); options.length = length ? length - 1 : 0; map = new WeakMap(); @@ -131,4 +129,4 @@ module.exports = function (memoize) { }); return memoized; }; -}; +} diff --git a/methods-plain.js b/methods-plain.js deleted file mode 100644 index 6b04250..0000000 --- a/methods-plain.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -module.exports = require("./lib/methods")(require("./plain")); diff --git a/methods-plain.mjs b/methods-plain.mjs new file mode 100644 index 0000000..a348f96 --- /dev/null +++ b/methods-plain.mjs @@ -0,0 +1,5 @@ +import memoize from "./index.mjs"; +import methods from "./methods.mjs"; + +const methodsPlainMemoize = methods(memoize); +export default methodsPlainMemoize; diff --git a/methods.js b/methods.js deleted file mode 100644 index 3ab1911..0000000 --- a/methods.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -module.exports = require("./lib/methods")(require("./")); diff --git a/methods.mjs b/methods.mjs new file mode 100644 index 0000000..962fee8 --- /dev/null +++ b/methods.mjs @@ -0,0 +1,5 @@ +import memoize from "./index.mjs"; +import methods from "./methods.mjs"; + +const methodsMemoize = methods(memoize); +export default methodsMemoize; diff --git a/normalizers/get-1.js b/normalizers/get-1.mjs similarity index 82% rename from normalizers/get-1.js rename to normalizers/get-1.mjs index 007c01a..1eeceb2 100644 --- a/normalizers/get-1.js +++ b/normalizers/get-1.mjs @@ -1,8 +1,6 @@ -"use strict"; +import indexOf from "es5-ext/array/%23/e-index-of.js"; -var indexOf = require("es5-ext/array/#/e-index-of"); - -module.exports = function () { +export default function get1() { var lastId = 0, argsMap = [], cache = []; return { get: function (args) { @@ -26,4 +24,4 @@ module.exports = function () { cache = []; }, }; -}; +} diff --git a/normalizers/get-fixed.js b/normalizers/get-fixed.mjs similarity index 88% rename from normalizers/get-fixed.js rename to normalizers/get-fixed.mjs index ee64f88..9ed1d96 100644 --- a/normalizers/get-fixed.js +++ b/normalizers/get-fixed.mjs @@ -1,9 +1,7 @@ -"use strict"; +import indexOf from "es5-ext/array/%23/e-index-of.js"; +var create = Object.create; -var indexOf = require("es5-ext/array/#/e-index-of") - , create = Object.create; - -module.exports = function (length) { +export default function getFixed(length) { var lastId = 0, map = [[], []], cache = create(null); return { get: function (args) { @@ -14,7 +12,7 @@ module.exports = function (length) { set = set[1][i]; ++index; } - i = indexOf.call(set[0], args[index]); + i = call(set[0], args[index]); if (i === -1) return null; return set[1][i] || null; }, @@ -68,4 +66,4 @@ module.exports = function (length) { cache = create(null); }, }; -}; +} diff --git a/normalizers/get-primitive-fixed.js b/normalizers/get-primitive-fixed.mjs similarity index 80% rename from normalizers/get-primitive-fixed.js rename to normalizers/get-primitive-fixed.mjs index c12d5be..23083f7 100644 --- a/normalizers/get-primitive-fixed.js +++ b/normalizers/get-primitive-fixed.mjs @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = function (length) { +export default function getPrimitiveFixed(length) { if (!length) { return function () { return ""; }; } @@ -11,4 +9,4 @@ module.exports = function (length) { } return id; }; -}; +} diff --git a/normalizers/get.js b/normalizers/get.mjs similarity index 95% rename from normalizers/get.js rename to normalizers/get.mjs index 8401d0f..028954b 100644 --- a/normalizers/get.js +++ b/normalizers/get.mjs @@ -1,12 +1,10 @@ /* eslint max-statements: 0 */ -"use strict"; - -var indexOf = require("es5-ext/array/#/e-index-of"); +import indexOf from "es5-ext/array/%23/e-index-of.js"; var create = Object.create; -module.exports = function () { +export default function get() { var lastId = 0, map = [], cache = create(null); return { get: function (args) { @@ -87,4 +85,4 @@ module.exports = function () { cache = create(null); }, }; -}; +} diff --git a/normalizers/primitive.js b/normalizers/primitive.mjs similarity index 74% rename from normalizers/primitive.js rename to normalizers/primitive.mjs index 9a520c2..aba5382 100644 --- a/normalizers/primitive.js +++ b/normalizers/primitive.mjs @@ -1,9 +1,7 @@ -"use strict"; - -module.exports = function (args) { +export default function primitive(args) { var id, i, length = args.length; if (!length) return "\u0002"; id = String(args[(i = 0)]); while (--length) id += "\u0001" + args[++i]; return id; -}; +} diff --git a/package.json b/package.json index 8e680c2..43b58b2 100644 --- a/package.json +++ b/package.json @@ -21,17 +21,28 @@ "async" ], "repository": "medikoo/memoizee", + "type": "commonjs", "dependencies": { "d": "^1.0.2", "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", + "lodash": "^4.17.21", + "lru-cache": "^11.0.0", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" + "secondary-cache": "^2.0.0", + "timers-ext": "^0.1.7", + "underscore": "^1.13.7" }, "devDependencies": { + "@babel/cli": "^7.25.6", + "@babel/core": "^7.25.2", + "@babel/preset-env": "^7.25.4", + "babel-plugin-add-module-exports": "^1.0.4", + "babel-plugin-transform-rewrite-imports": "1.2.0", + "babel-plugin-replace-import-extension": "^1.1.4", "bluebird": "^3.7.2", "eslint": "^8.57.0", "eslint-config-medikoo": "^4.2.0", @@ -98,6 +109,7 @@ ] }, "scripts": { + "build": "babel --out-file-extension .js -d ./ ./*.mjs --ignore ./index.mjs && babel --out-file-extension .js -d ./lib ./lib/*.mjs && babel --out-file-extension .js -d ./ext ./ext/*.mjs && babel --out-file-extension .js -d ./normalizers ./normalizers/*.mjs", "coverage": "nyc npm test", "lint": "eslint --ignore-path=.gitignore .", "lint:updated": "pipe-git-updated --base=main --ext=js -- eslint --ignore-pattern '!*'", @@ -105,10 +117,43 @@ "prettier-check:updated": "pipe-git-updated --base=main --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c", "prettify": "prettier --write --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", "prettify:updated": "pipe-git-updated ---base=main -ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier --write", - "test": "tad" + "test": "npm run build && tad" }, "engines": { "node": ">=0.12" }, + "babel": { + "presets": [ + [ + "@babel/env", + { + "targets": { + "node": "0.12" + } + } + ] + ], + "plugins": [ + "babel-plugin-add-module-exports", + [ + "babel-plugin-transform-rewrite-imports", + { + "replaceExtensions": { + "^es5-ext/array/%23/e-index-of.js$": "es5-ext/array/#/e-index-of.js", + "^es5-ext/string/%23/pad.js$": "es5-ext/string/#/pad.js", + "^es5-ext/function/%23/partial.js$": "es5-ext/function/#/partial.js" + } + } + ], + [ + "babel-plugin-replace-import-extension", + { + "extMapping": { + ".mjs": ".js" + } + } + ] + ] + }, "license": "ISC" } diff --git a/plain.js b/plain.mjs similarity index 65% rename from plain.js rename to plain.mjs index 4c770a8..e89f976 100644 --- a/plain.js +++ b/plain.mjs @@ -1,12 +1,11 @@ -"use strict"; - -var callable = require("es5-ext/object/valid-callable") - , forEach = require("es5-ext/object/for-each") - , extensions = require("./lib/registered-extensions") - , configure = require("./lib/configure-map") - , resolveLength = require("./lib/resolve-length"); - -module.exports = function self(fn/*, options */) { +import callable from "es5-ext/object/valid-callable.js"; +import forEach from "es5-ext/object/for-each.js"; +import async from "./ext/async.mjs"; +import * as extensions from "./lib/registered-extensions.mjs"; +import configure from "./lib/configure-map.mjs"; +import resolveLength from "./lib/resolve-length.mjs"; + +export default function self(fn/*, options */) { var options, length, conf; callable(fn); @@ -20,7 +19,7 @@ module.exports = function self(fn/*, options */) { if (hasOwnProperty.call(fn, "__memoized__") && !options.force) return fn; // Resolve length; - length = resolveLength(options.length, fn.length, options.async && extensions.async); + length = resolveLength(options.length, fn.length, options.async && async); // Configure cache map conf = configure(fn, length, options); @@ -34,4 +33,4 @@ module.exports = function self(fn/*, options */) { conf.updateEnv(); return conf.memoized; -}; +} diff --git a/profile.js b/profile.mjs similarity index 85% rename from profile.js rename to profile.mjs index 1c2ccb1..61a75a4 100644 --- a/profile.js +++ b/profile.mjs @@ -1,13 +1,11 @@ -// Gathers statistical data, and provides them in convinient form +// Gathers statistical data, and provides them in convenient form -"use strict"; - -var partial = require("es5-ext/function/#/partial") - , forEach = require("es5-ext/object/for-each") - , pad = require("es5-ext/string/#/pad") - , compact = require("es5-ext/array/#/compact") - , d = require("d") - , memoize = require("./plain"); +import partial from "es5-ext/function/%23/partial.js"; +import forEach from "es5-ext/object/for-each.js"; +import pad from "es5-ext/string/%23/pad.js"; +import compact from "es5-ext/array/%23/compact.js"; +import d from "d"; +import memoize from "./plain.mjs"; var max = Math.max, stats = (exports.statistics = {}); @@ -41,7 +39,7 @@ Object.defineProperty( }) ); -exports.log = function () { +export function log() { var initial, cached, ordered, ipad, cpad, ppad, toPrc, log; initial = cached = 0; @@ -106,4 +104,4 @@ exports.log = function () { }); log += "------------------------------------------------------------\n"; return log; -}; +} diff --git a/weak-plain.js b/weak-plain.js deleted file mode 100644 index 9897e6e..0000000 --- a/weak-plain.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -module.exports = require("./lib/weak")(require("./plain")); diff --git a/weak-plain.mjs b/weak-plain.mjs new file mode 100644 index 0000000..d854a7b --- /dev/null +++ b/weak-plain.mjs @@ -0,0 +1,5 @@ +import memoize from "./plain.mjs"; +import weak from "./weak.mjs"; + +const weakPlainMemoize = weak(memoize); +export default weakPlainMemoize; diff --git a/weak.js b/weak.js deleted file mode 100644 index 48e7b85..0000000 --- a/weak.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -module.exports = require("./lib/weak")(require("./")); diff --git a/weak.mjs b/weak.mjs new file mode 100644 index 0000000..7ade234 --- /dev/null +++ b/weak.mjs @@ -0,0 +1,5 @@ +import memoize from "./index.mjs"; +import weak from "./weak.mjs"; + +const weakMemoize = weak(memoize); +export default weakMemoize;