micro-memoize
Advanced tools
Comparing version 3.0.1 to 3.1.0-beta.0
@@ -5,4 +5,24 @@ // external dependencies | ||
import memoize from '../src'; | ||
import Cache from '../src/Cache'; | ||
import { isSameValueZero } from '../src/utils'; | ||
const DEFAULT_OPTIONS = { | ||
isEqual: isSameValueZero, | ||
isPromise: false, | ||
maxSize: 1, | ||
}; | ||
function getExpectedCache( | ||
keys: (any[])[], | ||
values: any[], | ||
options: MicroMemoize.Options, | ||
) { | ||
const cache = new Cache(options); | ||
cache.keys = keys; | ||
cache.values = values; | ||
return cache; | ||
} | ||
describe('memoize', () => { | ||
@@ -33,7 +53,3 @@ it('will return the function if already memoized', () => { | ||
expect(memoized.cache).toEqual({ | ||
keys: [], | ||
size: 0, | ||
values: [], | ||
}); | ||
expect(memoized.cache).toEqual(new Cache(DEFAULT_OPTIONS)); | ||
expect(memoized.cacheSnapshot).toEqual({ | ||
@@ -66,12 +82,13 @@ keys: [], | ||
expect(memoized.cache).toEqual({ | ||
keys: [['one', 'two']], | ||
size: 1, | ||
values: [ | ||
{ | ||
one: 'one', | ||
two: 'two', | ||
}, | ||
], | ||
}); | ||
const expectedCache = new Cache(memoized.options); | ||
expectedCache.keys = [['one', 'two']]; | ||
expectedCache.values = [ | ||
{ | ||
one: 'one', | ||
two: 'two', | ||
}, | ||
]; | ||
expect(memoized.cache).toEqual(expectedCache); | ||
}); | ||
@@ -94,7 +111,3 @@ | ||
expect(memoized.cache).toEqual({ | ||
keys: [], | ||
size: 0, | ||
values: [], | ||
}); | ||
expect(memoized.cache).toEqual(new Cache({ ...DEFAULT_OPTIONS, maxSize })); | ||
@@ -138,6 +151,5 @@ expect(memoized.cacheSnapshot).toEqual({ | ||
expect(memoized.cache).toEqual({ | ||
keys: [['three', 'four'], ['two', 'three'], ['four', 'five']], | ||
size: 3, | ||
values: [ | ||
const expectedCache = getExpectedCache( | ||
[['three', 'four'], ['two', 'three'], ['four', 'five']], | ||
[ | ||
{ | ||
@@ -156,3 +168,6 @@ one: 'three', | ||
], | ||
}); | ||
memoized.options, | ||
); | ||
expect(memoized.cache).toEqual(expectedCache); | ||
}); | ||
@@ -198,8 +213,5 @@ | ||
expect(memoized.cache).toEqual({ | ||
keys: [ | ||
[{ deep: { value: 'value' } }, { other: { deep: { value: 'value' } } }], | ||
], | ||
size: 1, | ||
values: [ | ||
const expectedCache = getExpectedCache( | ||
[[{ deep: { value: 'value' } }, { other: { deep: { value: 'value' } } }]], | ||
[ | ||
{ | ||
@@ -210,3 +222,6 @@ one: { deep: { value: 'value' } }, | ||
], | ||
}); | ||
memoized.options, | ||
); | ||
expect(memoized.cache).toEqual(expectedCache); | ||
}); | ||
@@ -254,6 +269,5 @@ | ||
expect(memoized.cache).toEqual({ | ||
keys: [['[{"one":"one"},null]']], | ||
size: 1, | ||
values: [ | ||
const expectedCache = getExpectedCache( | ||
[['[{"one":"one"},null]']], | ||
[ | ||
{ | ||
@@ -264,3 +278,6 @@ one: { one: 'one' }, | ||
], | ||
}); | ||
memoized.options, | ||
); | ||
expect(memoized.cache).toEqual(expectedCache); | ||
}); | ||
@@ -317,4 +334,4 @@ | ||
expect(memoized.cache).toEqual({ | ||
keys: [ | ||
const expectedCache = getExpectedCache( | ||
[ | ||
[ | ||
@@ -326,4 +343,3 @@ { | ||
], | ||
size: 1, | ||
values: [ | ||
[ | ||
{ | ||
@@ -334,3 +350,6 @@ one: { one: 'one' }, | ||
], | ||
}); | ||
memoized.options, | ||
); | ||
expect(memoized.cache).toEqual(expectedCache); | ||
}); | ||
@@ -422,15 +441,17 @@ | ||
let expectedCache = getExpectedCache( | ||
[['foo', 'bar']], | ||
[ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheChange).toHaveBeenCalledTimes(1); | ||
expect(onCacheChange).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['foo', 'bar']], | ||
size: 1, | ||
values: [ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -450,19 +471,21 @@ onCacheChange, | ||
expectedCache = getExpectedCache( | ||
[['bar', 'foo'], ['foo', 'bar']], | ||
[ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheChange).toHaveBeenCalledTimes(1); | ||
expect(onCacheChange).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['bar', 'foo'], ['foo', 'bar']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -488,19 +511,21 @@ onCacheChange, | ||
expectedCache = getExpectedCache( | ||
[['foo', 'bar'], ['bar', 'foo']], | ||
[ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheChange).toHaveBeenCalledTimes(1); | ||
expect(onCacheChange).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['foo', 'bar'], ['bar', 'foo']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -564,19 +589,21 @@ onCacheChange, | ||
let expectedCache = getExpectedCache( | ||
[['bar', 'foo'], ['foo', 'bar']], | ||
[ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheHit).toHaveBeenCalledTimes(1); | ||
expect(onCacheHit).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['bar', 'foo'], ['foo', 'bar']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -596,19 +623,21 @@ onCacheHit, | ||
expectedCache = getExpectedCache( | ||
[['foo', 'bar'], ['bar', 'foo']], | ||
[ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheHit).toHaveBeenCalledTimes(1); | ||
expect(onCacheHit).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['foo', 'bar'], ['bar', 'foo']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -630,17 +659,4 @@ onCacheHit, | ||
expect(onCacheHit).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['foo', 'bar'], ['bar', 'foo']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -694,15 +710,17 @@ onCacheHit, | ||
let expectedCache = getExpectedCache( | ||
[['foo', 'bar']], | ||
[ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheAdd).toHaveBeenCalledTimes(1); | ||
expect(onCacheAdd).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['foo', 'bar']], | ||
size: 1, | ||
values: [ | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -722,19 +740,21 @@ onCacheAdd, | ||
expectedCache = getExpectedCache( | ||
[['bar', 'foo'], ['foo', 'bar']], | ||
[ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
memoized.options, | ||
); | ||
expect(onCacheAdd).toHaveBeenCalledTimes(1); | ||
expect(onCacheAdd).toHaveBeenCalledWith( | ||
expectedCache, | ||
{ | ||
keys: [['bar', 'foo'], ['foo', 'bar']], | ||
size: 2, | ||
values: [ | ||
{ | ||
one: 'bar', | ||
two: 'foo', | ||
}, | ||
{ | ||
one: 'foo', | ||
two: 'bar', | ||
}, | ||
], | ||
}, | ||
{ | ||
maxSize, | ||
@@ -741,0 +761,0 @@ onCacheAdd, |
import { | ||
// createAreKeysEqual, | ||
createGetKeyIndex, | ||
createUpdateAsyncCache, | ||
copyArray, | ||
getCustomOptions, | ||
isSameValueZero, | ||
mergeOptions, | ||
orderByLru, | ||
} from '../src/utils'; | ||
describe('getKeyIndex', () => { | ||
it('will return the index of the match found', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
describe('copyArray', () => {}); | ||
const getKeyIndex = createGetKeyIndex({ isEqual }); | ||
const allKeys = [['key']]; | ||
const keyToMatch = ['key']; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(0); | ||
}); | ||
it('will return -1 if the key length is different', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const getKeyIndex = createGetKeyIndex({ isEqual }); | ||
const allKeys = [['key']]; | ||
const keyToMatch = ['some', 'other key']; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(-1); | ||
}); | ||
it('will return -1 if no match found', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const getKeyIndex = createGetKeyIndex({ isEqual }); | ||
const allKeys = [['key']]; | ||
const keyToMatch = ['other key']; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(-1); | ||
}); | ||
it('will return the index of the match found with larger maxSize', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const getKeyIndex = createGetKeyIndex({ isEqual, maxSize: 2 }); | ||
const allKeys = [['key'], ['other key']]; | ||
const keyToMatch = ['other key']; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(1); | ||
}); | ||
it('will return -1 if no match found and maxSize is larger', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const getKeyIndex = createGetKeyIndex({ isEqual, maxSize: 2 }); | ||
const allKeys = [['key'], ['other key']]; | ||
const keyToMatch = ['not present key']; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(-1); | ||
}); | ||
it('will use the isMatchingKey method is passed', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const isMatchingKey = (o1: any, o2: any) => { | ||
const existingKey = o1[0]; | ||
const key = o2[0]; | ||
return ( | ||
existingKey.hasOwnProperty('foo') && | ||
key.hasOwnProperty('foo') && | ||
(existingKey.bar === 'bar' || key.bar === 'baz') | ||
); | ||
}; | ||
const getKeyIndex = createGetKeyIndex({ isEqual, isMatchingKey }); | ||
const allKeys = [ | ||
[ | ||
{ | ||
bar: 'bar', | ||
foo: 'foo', | ||
}, | ||
], | ||
]; | ||
const keyToMatch = [ | ||
{ | ||
bar: 'baz', | ||
foo: 'bar', | ||
}, | ||
]; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(0); | ||
}); | ||
it('will use the isMatchingKey method is passed and maxSize is greater than 1', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const isMatchingKey = (o1: any, o2: any) => { | ||
const existingKey = o1[0]; | ||
const key = o2[0]; | ||
return ( | ||
existingKey.hasOwnProperty('foo') && | ||
key.hasOwnProperty('foo') && | ||
(existingKey.bar === 'bar' || key.bar === 'baz') | ||
); | ||
}; | ||
const getKeyIndex = createGetKeyIndex({ | ||
isEqual, | ||
isMatchingKey, | ||
maxSize: 2, | ||
}); | ||
const allKeys = [ | ||
[ | ||
{ | ||
bar: 'baz', | ||
baz: 'quz', | ||
}, | ||
], | ||
[ | ||
{ | ||
bar: 'bar', | ||
foo: 'foo', | ||
}, | ||
], | ||
]; | ||
const keyToMatch = [ | ||
{ | ||
bar: 'baz', | ||
foo: 'bar', | ||
}, | ||
]; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(1); | ||
}); | ||
it('will return -1 if the isMatchingKey method is passed and no match is found', () => { | ||
const isEqual = (o1: any, o2: any) => o1 === o2; | ||
const isMatchingKey = (o1: any, o2: any) => { | ||
const existingKey = o1[0]; | ||
const key = o2[0]; | ||
return ( | ||
existingKey.hasOwnProperty('foo') && | ||
key.hasOwnProperty('foo') && | ||
(existingKey.bar === 'bar' || key.bar === 'baz') | ||
); | ||
}; | ||
const getKeyIndex = createGetKeyIndex({ | ||
isEqual, | ||
isMatchingKey, | ||
maxSize: 2, | ||
}); | ||
const allKeys = [ | ||
[ | ||
{ | ||
bar: 'baz', | ||
baz: 'quz', | ||
}, | ||
], | ||
]; | ||
const keyToMatch = [ | ||
{ | ||
bar: 'baz', | ||
foo: 'bar', | ||
}, | ||
]; | ||
const result = getKeyIndex(allKeys, keyToMatch); | ||
expect(result).toEqual(-1); | ||
}); | ||
}); | ||
describe('getCustomOptions', () => { | ||
@@ -249,221 +62,1 @@ it('will return the custom options and no default options', () => { | ||
}); | ||
describe('orderByLru', () => { | ||
it('will do nothing if the itemIndex is 0', () => { | ||
const cache = { | ||
keys: [['first'], ['second'], ['third']], | ||
size: 3, | ||
values: ['first', 'second', 'third'], | ||
}; | ||
const itemIndex = 0; | ||
const key = cache.keys[itemIndex]; | ||
const value = cache.values[itemIndex]; | ||
const maxSize = 3; | ||
orderByLru(cache, key, value, itemIndex, maxSize); | ||
expect(cache).toEqual({ | ||
...cache, | ||
keys: [['first'], ['second'], ['third']], | ||
values: ['first', 'second', 'third'], | ||
}); | ||
}); | ||
it('will place the itemIndex first in order when non-zero', () => { | ||
const cache = { | ||
keys: [['first'], ['second'], ['third']], | ||
size: 3, | ||
values: ['first', 'second', 'third'], | ||
}; | ||
const itemIndex = 1; | ||
const key = cache.keys[itemIndex]; | ||
const value = cache.values[itemIndex]; | ||
const maxSize = 3; | ||
orderByLru(cache, key, value, itemIndex, maxSize); | ||
expect(cache).toEqual({ | ||
...cache, | ||
keys: [['second'], ['first'], ['third']], | ||
values: ['second', 'first', 'third'], | ||
}); | ||
}); | ||
it('will add the new item to the array when the itemIndex is the array length', () => { | ||
const cache = { | ||
keys: [['first'], ['second'], ['third']], | ||
size: 3, | ||
values: ['first', 'second', 'third'], | ||
}; | ||
const itemIndex = cache.keys.length; | ||
const key = ['key']; | ||
const value = 'new'; | ||
const maxSize = 4; | ||
orderByLru(cache, key, value, itemIndex, maxSize); | ||
expect(cache).toEqual({ | ||
...cache, | ||
keys: [key, ['first'], ['second'], ['third']], | ||
values: [value, 'first', 'second', 'third'], | ||
}); | ||
}); | ||
}); | ||
describe('updateAsyncCache', () => { | ||
it('will fire cache callbacks if resolved', async () => { | ||
const timeout = 200; | ||
const fn = async () => { | ||
await new Promise((resolve: Function) => { | ||
setTimeout(resolve, timeout); | ||
}); | ||
return 'resolved'; | ||
}; | ||
const key = ['foo']; | ||
const memoized = () => {}; | ||
const value = fn(); | ||
const cache = { | ||
keys: [key], | ||
size: 1, | ||
values: [value], | ||
}; | ||
const options = { | ||
isEqual: isSameValueZero, | ||
onCacheChange: jest.fn(), | ||
onCacheHit: jest.fn(), | ||
}; | ||
createUpdateAsyncCache(options)(cache, memoized); | ||
// this is just to prevent the unhandled rejection noise | ||
cache.values[0].catch(() => {}); | ||
expect(cache.keys.length).toEqual(1); | ||
expect(cache.values.length).toEqual(1); | ||
expect(cache.values[0]).toEqual(value); | ||
await new Promise((resolve: Function) => { | ||
setTimeout(resolve, timeout + 50); | ||
}); | ||
expect(cache.keys.length).toEqual(1); | ||
expect(cache.values.length).toEqual(1); | ||
expect(cache.values[0]).toEqual(value); | ||
expect(options.onCacheHit).toHaveBeenCalledTimes(1); | ||
expect(options.onCacheHit).toHaveBeenCalledWith(cache, options, memoized); | ||
expect(options.onCacheChange).toHaveBeenCalledTimes(1); | ||
expect(options.onCacheChange).toHaveBeenCalledWith( | ||
cache, | ||
options, | ||
memoized, | ||
); | ||
}); | ||
it('will remove the key from cache when the promise is rejected', async () => { | ||
const timeout = 200; | ||
const fn = async () => { | ||
await new Promise((resolve: Function, reject: Function) => { | ||
setTimeout(() => reject(new Error('boom')), timeout); | ||
}); | ||
}; | ||
const key = ['foo']; | ||
const value = fn(); | ||
const cache = { | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
keys: [key], | ||
values: [value], | ||
}; | ||
const options = { | ||
isEqual: isSameValueZero, | ||
onCacheChange: jest.fn(), | ||
onCacheHit: jest.fn(), | ||
}; | ||
const memoized = () => {}; | ||
createUpdateAsyncCache(options)(cache, memoized); | ||
const catcher = jest.fn(); | ||
cache.values[0].catch(catcher); | ||
expect(cache.keys.length).toEqual(1); | ||
expect(cache.values.length).toEqual(1); | ||
expect(cache.values[0]).toEqual(value); | ||
await new Promise((resolve: Function) => { | ||
setTimeout(resolve, timeout + 50); | ||
}); | ||
expect(catcher).toHaveBeenCalledTimes(1); | ||
expect(cache).toEqual({ | ||
keys: [], | ||
size: 0, | ||
values: [], | ||
}); | ||
expect(options.onCacheHit).toHaveBeenCalledTimes(0); | ||
expect(options.onCacheChange).toHaveBeenCalledTimes(0); | ||
}); | ||
it('will not remove the key from cache when the promise is rejected but the key no longer exists', async () => { | ||
const timeout = 200; | ||
const fn = async () => { | ||
await new Promise((resolve: Function, reject: Function) => { | ||
setTimeout(() => reject(new Error('boom')), timeout); | ||
}); | ||
}; | ||
const key = ['foo']; | ||
const value = fn(); | ||
const cache = { | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
keys: [key], | ||
values: [value], | ||
}; | ||
const options = { | ||
isEqual: isSameValueZero, | ||
onCacheChange: jest.fn(), | ||
onCacheHit: jest.fn(), | ||
}; | ||
const memoized = () => {}; | ||
createUpdateAsyncCache(options)(cache, memoized); | ||
const newValue = cache.values[0]; | ||
const catcher = jest.fn(); | ||
newValue.catch(catcher); | ||
expect(cache.keys.length).toEqual(1); | ||
expect(cache.values.length).toEqual(1); | ||
expect(cache.values[0]).toEqual(value); | ||
cache.keys = [['bar']]; | ||
// @ts-ignore | ||
cache.values = [Promise.resolve('baz')]; | ||
await new Promise((resolve: Function) => { | ||
setTimeout(resolve, timeout + 50); | ||
}); | ||
expect(catcher).toHaveBeenCalledTimes(1); | ||
expect(options.onCacheHit).toHaveBeenCalledTimes(0); | ||
expect(options.onCacheChange).toHaveBeenCalledTimes(0); | ||
}); | ||
}); |
@@ -10,18 +10,21 @@ /* | ||
module.exports = function memoize(fn) { | ||
return function(...args) { | ||
let index = args.length, | ||
hash = '', | ||
currentArg = null; | ||
fn.cache || (fn.cache = {}); | ||
currentArg = null; | ||
return function() { | ||
let index = arguments.length; | ||
let hash = ''; | ||
let currentArg = null; | ||
while (index--) { | ||
currentArg = args[index]; | ||
hash += currentArg === Object(currentArg) ? JSON.stringify(currentArg) : currentArg; | ||
fn.memoize || (fn.memoize = {}); | ||
currentArg = arguments[index]; | ||
hash += | ||
currentArg === Object(currentArg) | ||
? JSON.stringify(currentArg) | ||
: currentArg; | ||
} | ||
return hash in fn.memoize ? fn.memoize[hash] : (fn.memoize[hash] = fn.apply(this, args)); | ||
return hash in fn.cache | ||
? fn.cache[hash] | ||
: (fn.cache[hash] = fn.apply(this, arguments)); | ||
}; | ||
}; |
const _ = require('lodash'); | ||
// const fs = require("fs"); | ||
const React = require('react'); | ||
const { createSuite } = require('benchee'); | ||
@@ -233,3 +230,3 @@ const Table = require('cli-table2'); | ||
...stats, | ||
ops: stats.iterations / stats.elapsed, | ||
ops: ~~((stats.iterations / stats.elapsed) * 1000), | ||
}, | ||
@@ -236,0 +233,0 @@ })) |
'use strict'; | ||
var Cache = /** @class */ (function () { | ||
function Cache(options) { | ||
this.keys = []; | ||
this.values = []; | ||
this.options = options; | ||
this.getKeyIndex = | ||
typeof options.isMatchingKey === 'function' | ||
? this._getKeyIndexByMatchingKey | ||
: options.maxSize > 1 | ||
? this._getKeyIndexForMultipleCache | ||
: this._getKeyIndexForSingleCache; | ||
} | ||
Object.defineProperty(Cache.prototype, "size", { | ||
get: function () { | ||
return this.keys.length; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Cache.prototype._getKeyIndexByMatchingKey = function (key) { | ||
if (this.options.isMatchingKey(this.keys[0], key)) { | ||
return 0; | ||
} | ||
if (this.options.maxSize > 1) { | ||
var keys = this.keys; | ||
var isMatchingKey = this.options.isMatchingKey; | ||
var keysLength = keys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(keys[index], key)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForMultipleCache = function (key) { | ||
var _a = this, keys = _a.keys, size = _a.size; | ||
var isEqual = this.options.isEqual; | ||
var keyLength = key.length; | ||
var existingKey; | ||
for (var index = 0; index < size; index++) { | ||
existingKey = keys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], key[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForSingleCache = function (key) { | ||
var existingKey = this.keys[0]; | ||
var keyLength = existingKey.length; | ||
if (key.length !== keyLength) { | ||
return -1; | ||
} | ||
var isEqual = this.options.isEqual; | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], key[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
/** | ||
* @instance | ||
* @function updateAsync | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param memoized the memoized function | ||
*/ | ||
Cache.prototype._updateAsync = function (memoized) { | ||
var _this = this; | ||
var key = this.keys[0]; | ||
this.values[0] = this.values[0] | ||
.then(function (value) { | ||
if (typeof _this.options.onCacheHit === 'function') { | ||
_this.options.onCacheHit(_this, _this.options, memoized); | ||
} | ||
if (typeof _this.options.onCacheChange === 'function') { | ||
_this.options.onCacheChange(_this, _this.options, memoized); | ||
} | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = _this.getKeyIndex(key); | ||
if (keyIndex !== -1) { | ||
_this.keys.splice(keyIndex, 1); | ||
_this.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
/** | ||
* @instance | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param key the new key to move to the front | ||
* @param value the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
Cache.prototype.orderByLru = function (key, value, startingIndex) { | ||
var _a = this, keys = _a.keys, values = _a.values; | ||
var maxSize = this.options.maxSize; | ||
var index = startingIndex; | ||
while (index--) { | ||
keys[index + 1] = keys[index]; | ||
values[index + 1] = values[index]; | ||
} | ||
keys[0] = key; | ||
values[0] = value; | ||
if (startingIndex >= maxSize) { | ||
keys.length = maxSize; | ||
values.length = maxSize; | ||
} | ||
}; | ||
return Cache; | ||
}()); | ||
var DEFAULT_OPTIONS_KEYS = { | ||
@@ -14,63 +145,17 @@ isEqual: true, | ||
/** | ||
* @function createGetKeyIndex | ||
* @function copyArray | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* copy an array-like object to a new array | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
* @param arrayLike the array-like object to copy | ||
* @returns the copied array | ||
*/ | ||
function createGetKeyIndex(_a) { | ||
var isEqual = _a.isEqual, isMatchingKey = _a.isMatchingKey, maxSize = _a.maxSize; | ||
if (typeof isMatchingKey === 'function') { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
if (isMatchingKey(allKeys[0], keyToMatch)) { | ||
return 0; | ||
} | ||
if (maxSize > 1) { | ||
var keysLength = allKeys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(allKeys[index], keyToMatch)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
function copyArray(arrayLike) { | ||
var length = arrayLike.length; | ||
var array = new Array(length); | ||
for (var index = 0; index < length; index++) { | ||
array[index] = arrayLike[index]; | ||
} | ||
if (maxSize > 1) { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var keysLength = allKeys.length; | ||
var keyLength = keyToMatch.length; | ||
var existingKey; | ||
for (var index = 0; index < keysLength; index++) { | ||
existingKey = allKeys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], keyToMatch[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var existingKey = allKeys[0]; | ||
var keyLength = existingKey.length; | ||
if (keyToMatch.length !== keyLength) { | ||
return -1; | ||
} | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], keyToMatch[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
return array; | ||
} | ||
@@ -129,64 +214,4 @@ /** | ||
} | ||
/** | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param keys the keys to order | ||
* @param newKey the new key to move to the front | ||
* @param values the values to order | ||
* @param newValue the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
function orderByLru(cache, newKey, newValue, startingIndex, maxSize) { | ||
var index = startingIndex; | ||
while (index--) { | ||
cache.keys[index + 1] = cache.keys[index]; | ||
cache.values[index + 1] = cache.values[index]; | ||
} | ||
cache.keys[0] = newKey; | ||
cache.values[0] = newValue; | ||
if (startingIndex >= maxSize) { | ||
cache.keys.length = maxSize; | ||
cache.values.length = maxSize; | ||
} | ||
} | ||
function createUpdateAsyncCache(options) { | ||
var getKeyIndex = createGetKeyIndex(options); | ||
var onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
/** | ||
* @function updateAsyncCache | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param cache the memoized function's cache | ||
* @param memoized the memoized function | ||
*/ | ||
return function (cache, memoized) { | ||
var key = cache.keys[0]; | ||
cache.values[0] = cache.values[0] | ||
.then(function (value) { | ||
shouldUpdateOnHit && onCacheHit(cache, options, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, options, memoized); | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = getKeyIndex(cache.keys, key); | ||
if (keyIndex !== -1) { | ||
cache.keys.splice(keyIndex, 1); | ||
cache.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
} | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
// cache | ||
function createMemoizedFunction(fn, options) { | ||
@@ -209,30 +234,16 @@ if (options === void 0) { options = {}; } | ||
}); | ||
var getKeyIndex = createGetKeyIndex(normalizedOptions); | ||
var updateAsyncCache = createUpdateAsyncCache(normalizedOptions); | ||
var keys = []; | ||
var values = []; | ||
var cache = { | ||
keys: keys, | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
values: values, | ||
}; | ||
var cache = new Cache(normalizedOptions); | ||
var canTransformKey = typeof transformKey === 'function'; | ||
var shouldCloneArguments = !!(transformKey || isMatchingKey); | ||
var shouldUpdateOnAdd = typeof onCacheAdd === 'function'; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
var shouldCloneArguments = canTransformKey || !!isMatchingKey; | ||
function memoized() { | ||
var normalizedArgs = shouldCloneArguments | ||
? slice.call(arguments, 0) | ||
? copyArray(arguments) | ||
: arguments; | ||
var key = canTransformKey ? transformKey(normalizedArgs) : normalizedArgs; | ||
var keyIndex = keys.length ? getKeyIndex(keys, key) : -1; | ||
var keyIndex = cache.size ? cache.getKeyIndex(key) : -1; | ||
if (keyIndex !== -1) { | ||
shouldUpdateOnHit && onCacheHit(cache, normalizedOptions, memoized); | ||
onCacheHit && onCacheHit(cache, normalizedOptions, memoized); | ||
if (keyIndex) { | ||
orderByLru(cache, keys[keyIndex], values[keyIndex], keyIndex, maxSize); | ||
shouldUpdateOnChange && | ||
onCacheChange(cache, normalizedOptions, memoized); | ||
cache.orderByLru(cache.keys[keyIndex], cache.values[keyIndex], keyIndex); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
@@ -242,14 +253,16 @@ } | ||
var newValue = fn.apply(this, arguments); | ||
var newKey = shouldCloneArguments ? key : slice.call(arguments, 0); | ||
orderByLru(cache, newKey, newValue, keys.length, maxSize); | ||
isPromise && updateAsyncCache(cache, memoized); | ||
shouldUpdateOnAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, normalizedOptions, memoized); | ||
var newKey = shouldCloneArguments ? key : copyArray(normalizedArgs); | ||
cache.orderByLru(newKey, newValue, cache.size); | ||
isPromise && cache._updateAsync(memoized); | ||
onCacheAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
return values[0]; | ||
return cache.values[0]; | ||
} | ||
defineProperties(memoized, { | ||
Object.defineProperties(memoized, { | ||
cache: { | ||
configurable: true, | ||
enumerable: false, | ||
value: cache, | ||
writable: true, | ||
}, | ||
@@ -260,5 +273,5 @@ cacheSnapshot: { | ||
return { | ||
keys: slice.call(cache.keys, 0), | ||
keys: copyArray(cache.keys), | ||
size: cache.size, | ||
values: slice.call(cache.values, 0), | ||
values: copyArray(cache.values), | ||
}; | ||
@@ -269,7 +282,11 @@ }, | ||
configurable: true, | ||
enumerable: false, | ||
value: true, | ||
writable: true, | ||
}, | ||
options: { | ||
configurable: true, | ||
enumerable: false, | ||
value: normalizedOptions, | ||
writable: true, | ||
}, | ||
@@ -276,0 +293,0 @@ }); |
@@ -0,1 +1,132 @@ | ||
var Cache = /** @class */ (function () { | ||
function Cache(options) { | ||
this.keys = []; | ||
this.values = []; | ||
this.options = options; | ||
this.getKeyIndex = | ||
typeof options.isMatchingKey === 'function' | ||
? this._getKeyIndexByMatchingKey | ||
: options.maxSize > 1 | ||
? this._getKeyIndexForMultipleCache | ||
: this._getKeyIndexForSingleCache; | ||
} | ||
Object.defineProperty(Cache.prototype, "size", { | ||
get: function () { | ||
return this.keys.length; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Cache.prototype._getKeyIndexByMatchingKey = function (key) { | ||
if (this.options.isMatchingKey(this.keys[0], key)) { | ||
return 0; | ||
} | ||
if (this.options.maxSize > 1) { | ||
var keys = this.keys; | ||
var isMatchingKey = this.options.isMatchingKey; | ||
var keysLength = keys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(keys[index], key)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForMultipleCache = function (key) { | ||
var _a = this, keys = _a.keys, size = _a.size; | ||
var isEqual = this.options.isEqual; | ||
var keyLength = key.length; | ||
var existingKey; | ||
for (var index = 0; index < size; index++) { | ||
existingKey = keys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], key[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForSingleCache = function (key) { | ||
var existingKey = this.keys[0]; | ||
var keyLength = existingKey.length; | ||
if (key.length !== keyLength) { | ||
return -1; | ||
} | ||
var isEqual = this.options.isEqual; | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], key[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
/** | ||
* @instance | ||
* @function updateAsync | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param memoized the memoized function | ||
*/ | ||
Cache.prototype._updateAsync = function (memoized) { | ||
var _this = this; | ||
var key = this.keys[0]; | ||
this.values[0] = this.values[0] | ||
.then(function (value) { | ||
if (typeof _this.options.onCacheHit === 'function') { | ||
_this.options.onCacheHit(_this, _this.options, memoized); | ||
} | ||
if (typeof _this.options.onCacheChange === 'function') { | ||
_this.options.onCacheChange(_this, _this.options, memoized); | ||
} | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = _this.getKeyIndex(key); | ||
if (keyIndex !== -1) { | ||
_this.keys.splice(keyIndex, 1); | ||
_this.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
/** | ||
* @instance | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param key the new key to move to the front | ||
* @param value the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
Cache.prototype.orderByLru = function (key, value, startingIndex) { | ||
var _a = this, keys = _a.keys, values = _a.values; | ||
var maxSize = this.options.maxSize; | ||
var index = startingIndex; | ||
while (index--) { | ||
keys[index + 1] = keys[index]; | ||
values[index + 1] = values[index]; | ||
} | ||
keys[0] = key; | ||
values[0] = value; | ||
if (startingIndex >= maxSize) { | ||
keys.length = maxSize; | ||
values.length = maxSize; | ||
} | ||
}; | ||
return Cache; | ||
}()); | ||
var DEFAULT_OPTIONS_KEYS = { | ||
@@ -12,63 +143,17 @@ isEqual: true, | ||
/** | ||
* @function createGetKeyIndex | ||
* @function copyArray | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* copy an array-like object to a new array | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
* @param arrayLike the array-like object to copy | ||
* @returns the copied array | ||
*/ | ||
function createGetKeyIndex(_a) { | ||
var isEqual = _a.isEqual, isMatchingKey = _a.isMatchingKey, maxSize = _a.maxSize; | ||
if (typeof isMatchingKey === 'function') { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
if (isMatchingKey(allKeys[0], keyToMatch)) { | ||
return 0; | ||
} | ||
if (maxSize > 1) { | ||
var keysLength = allKeys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(allKeys[index], keyToMatch)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
function copyArray(arrayLike) { | ||
var length = arrayLike.length; | ||
var array = new Array(length); | ||
for (var index = 0; index < length; index++) { | ||
array[index] = arrayLike[index]; | ||
} | ||
if (maxSize > 1) { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var keysLength = allKeys.length; | ||
var keyLength = keyToMatch.length; | ||
var existingKey; | ||
for (var index = 0; index < keysLength; index++) { | ||
existingKey = allKeys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], keyToMatch[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var existingKey = allKeys[0]; | ||
var keyLength = existingKey.length; | ||
if (keyToMatch.length !== keyLength) { | ||
return -1; | ||
} | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], keyToMatch[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
return array; | ||
} | ||
@@ -127,64 +212,4 @@ /** | ||
} | ||
/** | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param keys the keys to order | ||
* @param newKey the new key to move to the front | ||
* @param values the values to order | ||
* @param newValue the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
function orderByLru(cache, newKey, newValue, startingIndex, maxSize) { | ||
var index = startingIndex; | ||
while (index--) { | ||
cache.keys[index + 1] = cache.keys[index]; | ||
cache.values[index + 1] = cache.values[index]; | ||
} | ||
cache.keys[0] = newKey; | ||
cache.values[0] = newValue; | ||
if (startingIndex >= maxSize) { | ||
cache.keys.length = maxSize; | ||
cache.values.length = maxSize; | ||
} | ||
} | ||
function createUpdateAsyncCache(options) { | ||
var getKeyIndex = createGetKeyIndex(options); | ||
var onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
/** | ||
* @function updateAsyncCache | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param cache the memoized function's cache | ||
* @param memoized the memoized function | ||
*/ | ||
return function (cache, memoized) { | ||
var key = cache.keys[0]; | ||
cache.values[0] = cache.values[0] | ||
.then(function (value) { | ||
shouldUpdateOnHit && onCacheHit(cache, options, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, options, memoized); | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = getKeyIndex(cache.keys, key); | ||
if (keyIndex !== -1) { | ||
cache.keys.splice(keyIndex, 1); | ||
cache.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
} | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
// cache | ||
function createMemoizedFunction(fn, options) { | ||
@@ -207,30 +232,16 @@ if (options === void 0) { options = {}; } | ||
}); | ||
var getKeyIndex = createGetKeyIndex(normalizedOptions); | ||
var updateAsyncCache = createUpdateAsyncCache(normalizedOptions); | ||
var keys = []; | ||
var values = []; | ||
var cache = { | ||
keys: keys, | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
values: values, | ||
}; | ||
var cache = new Cache(normalizedOptions); | ||
var canTransformKey = typeof transformKey === 'function'; | ||
var shouldCloneArguments = !!(transformKey || isMatchingKey); | ||
var shouldUpdateOnAdd = typeof onCacheAdd === 'function'; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
var shouldCloneArguments = canTransformKey || !!isMatchingKey; | ||
function memoized() { | ||
var normalizedArgs = shouldCloneArguments | ||
? slice.call(arguments, 0) | ||
? copyArray(arguments) | ||
: arguments; | ||
var key = canTransformKey ? transformKey(normalizedArgs) : normalizedArgs; | ||
var keyIndex = keys.length ? getKeyIndex(keys, key) : -1; | ||
var keyIndex = cache.size ? cache.getKeyIndex(key) : -1; | ||
if (keyIndex !== -1) { | ||
shouldUpdateOnHit && onCacheHit(cache, normalizedOptions, memoized); | ||
onCacheHit && onCacheHit(cache, normalizedOptions, memoized); | ||
if (keyIndex) { | ||
orderByLru(cache, keys[keyIndex], values[keyIndex], keyIndex, maxSize); | ||
shouldUpdateOnChange && | ||
onCacheChange(cache, normalizedOptions, memoized); | ||
cache.orderByLru(cache.keys[keyIndex], cache.values[keyIndex], keyIndex); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
@@ -240,14 +251,16 @@ } | ||
var newValue = fn.apply(this, arguments); | ||
var newKey = shouldCloneArguments ? key : slice.call(arguments, 0); | ||
orderByLru(cache, newKey, newValue, keys.length, maxSize); | ||
isPromise && updateAsyncCache(cache, memoized); | ||
shouldUpdateOnAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, normalizedOptions, memoized); | ||
var newKey = shouldCloneArguments ? key : copyArray(normalizedArgs); | ||
cache.orderByLru(newKey, newValue, cache.size); | ||
isPromise && cache._updateAsync(memoized); | ||
onCacheAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
return values[0]; | ||
return cache.values[0]; | ||
} | ||
defineProperties(memoized, { | ||
Object.defineProperties(memoized, { | ||
cache: { | ||
configurable: true, | ||
enumerable: false, | ||
value: cache, | ||
writable: true, | ||
}, | ||
@@ -258,5 +271,5 @@ cacheSnapshot: { | ||
return { | ||
keys: slice.call(cache.keys, 0), | ||
keys: copyArray(cache.keys), | ||
size: cache.size, | ||
values: slice.call(cache.values, 0), | ||
values: copyArray(cache.values), | ||
}; | ||
@@ -267,7 +280,11 @@ }, | ||
configurable: true, | ||
enumerable: false, | ||
value: true, | ||
writable: true, | ||
}, | ||
options: { | ||
configurable: true, | ||
enumerable: false, | ||
value: normalizedOptions, | ||
writable: true, | ||
}, | ||
@@ -274,0 +291,0 @@ }); |
@@ -7,2 +7,133 @@ (function (global, factory) { | ||
var Cache = /** @class */ (function () { | ||
function Cache(options) { | ||
this.keys = []; | ||
this.values = []; | ||
this.options = options; | ||
this.getKeyIndex = | ||
typeof options.isMatchingKey === 'function' | ||
? this._getKeyIndexByMatchingKey | ||
: options.maxSize > 1 | ||
? this._getKeyIndexForMultipleCache | ||
: this._getKeyIndexForSingleCache; | ||
} | ||
Object.defineProperty(Cache.prototype, "size", { | ||
get: function () { | ||
return this.keys.length; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Cache.prototype._getKeyIndexByMatchingKey = function (key) { | ||
if (this.options.isMatchingKey(this.keys[0], key)) { | ||
return 0; | ||
} | ||
if (this.options.maxSize > 1) { | ||
var keys = this.keys; | ||
var isMatchingKey = this.options.isMatchingKey; | ||
var keysLength = keys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(keys[index], key)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForMultipleCache = function (key) { | ||
var _a = this, keys = _a.keys, size = _a.size; | ||
var isEqual = this.options.isEqual; | ||
var keyLength = key.length; | ||
var existingKey; | ||
for (var index = 0; index < size; index++) { | ||
existingKey = keys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], key[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
Cache.prototype._getKeyIndexForSingleCache = function (key) { | ||
var existingKey = this.keys[0]; | ||
var keyLength = existingKey.length; | ||
if (key.length !== keyLength) { | ||
return -1; | ||
} | ||
var isEqual = this.options.isEqual; | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], key[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
/** | ||
* @instance | ||
* @function updateAsync | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param memoized the memoized function | ||
*/ | ||
Cache.prototype._updateAsync = function (memoized) { | ||
var _this = this; | ||
var key = this.keys[0]; | ||
this.values[0] = this.values[0] | ||
.then(function (value) { | ||
if (typeof _this.options.onCacheHit === 'function') { | ||
_this.options.onCacheHit(_this, _this.options, memoized); | ||
} | ||
if (typeof _this.options.onCacheChange === 'function') { | ||
_this.options.onCacheChange(_this, _this.options, memoized); | ||
} | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = _this.getKeyIndex(key); | ||
if (keyIndex !== -1) { | ||
_this.keys.splice(keyIndex, 1); | ||
_this.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
/** | ||
* @instance | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param key the new key to move to the front | ||
* @param value the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
Cache.prototype.orderByLru = function (key, value, startingIndex) { | ||
var _a = this, keys = _a.keys, values = _a.values; | ||
var maxSize = this.options.maxSize; | ||
var index = startingIndex; | ||
while (index--) { | ||
keys[index + 1] = keys[index]; | ||
values[index + 1] = values[index]; | ||
} | ||
keys[0] = key; | ||
values[0] = value; | ||
if (startingIndex >= maxSize) { | ||
keys.length = maxSize; | ||
values.length = maxSize; | ||
} | ||
}; | ||
return Cache; | ||
}()); | ||
var DEFAULT_OPTIONS_KEYS = { | ||
@@ -19,63 +150,17 @@ isEqual: true, | ||
/** | ||
* @function createGetKeyIndex | ||
* @function copyArray | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* copy an array-like object to a new array | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
* @param arrayLike the array-like object to copy | ||
* @returns the copied array | ||
*/ | ||
function createGetKeyIndex(_a) { | ||
var isEqual = _a.isEqual, isMatchingKey = _a.isMatchingKey, maxSize = _a.maxSize; | ||
if (typeof isMatchingKey === 'function') { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
if (isMatchingKey(allKeys[0], keyToMatch)) { | ||
return 0; | ||
} | ||
if (maxSize > 1) { | ||
var keysLength = allKeys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey(allKeys[index], keyToMatch)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
function copyArray(arrayLike) { | ||
var length = arrayLike.length; | ||
var array = new Array(length); | ||
for (var index = 0; index < length; index++) { | ||
array[index] = arrayLike[index]; | ||
} | ||
if (maxSize > 1) { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var keysLength = allKeys.length; | ||
var keyLength = keyToMatch.length; | ||
var existingKey; | ||
for (var index = 0; index < keysLength; index++) { | ||
existingKey = allKeys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], keyToMatch[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var existingKey = allKeys[0]; | ||
var keyLength = existingKey.length; | ||
if (keyToMatch.length !== keyLength) { | ||
return -1; | ||
} | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], keyToMatch[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
return array; | ||
} | ||
@@ -134,64 +219,4 @@ /** | ||
} | ||
/** | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param keys the keys to order | ||
* @param newKey the new key to move to the front | ||
* @param values the values to order | ||
* @param newValue the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
function orderByLru(cache, newKey, newValue, startingIndex, maxSize) { | ||
var index = startingIndex; | ||
while (index--) { | ||
cache.keys[index + 1] = cache.keys[index]; | ||
cache.values[index + 1] = cache.values[index]; | ||
} | ||
cache.keys[0] = newKey; | ||
cache.values[0] = newValue; | ||
if (startingIndex >= maxSize) { | ||
cache.keys.length = maxSize; | ||
cache.values.length = maxSize; | ||
} | ||
} | ||
function createUpdateAsyncCache(options) { | ||
var getKeyIndex = createGetKeyIndex(options); | ||
var onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
/** | ||
* @function updateAsyncCache | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param cache the memoized function's cache | ||
* @param memoized the memoized function | ||
*/ | ||
return function (cache, memoized) { | ||
var key = cache.keys[0]; | ||
cache.values[0] = cache.values[0] | ||
.then(function (value) { | ||
shouldUpdateOnHit && onCacheHit(cache, options, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, options, memoized); | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = getKeyIndex(cache.keys, key); | ||
if (keyIndex !== -1) { | ||
cache.keys.splice(keyIndex, 1); | ||
cache.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
} | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
// cache | ||
function createMemoizedFunction(fn, options) { | ||
@@ -214,30 +239,16 @@ if (options === void 0) { options = {}; } | ||
}); | ||
var getKeyIndex = createGetKeyIndex(normalizedOptions); | ||
var updateAsyncCache = createUpdateAsyncCache(normalizedOptions); | ||
var keys = []; | ||
var values = []; | ||
var cache = { | ||
keys: keys, | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
values: values, | ||
}; | ||
var cache = new Cache(normalizedOptions); | ||
var canTransformKey = typeof transformKey === 'function'; | ||
var shouldCloneArguments = !!(transformKey || isMatchingKey); | ||
var shouldUpdateOnAdd = typeof onCacheAdd === 'function'; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
var shouldCloneArguments = canTransformKey || !!isMatchingKey; | ||
function memoized() { | ||
var normalizedArgs = shouldCloneArguments | ||
? slice.call(arguments, 0) | ||
? copyArray(arguments) | ||
: arguments; | ||
var key = canTransformKey ? transformKey(normalizedArgs) : normalizedArgs; | ||
var keyIndex = keys.length ? getKeyIndex(keys, key) : -1; | ||
var keyIndex = cache.size ? cache.getKeyIndex(key) : -1; | ||
if (keyIndex !== -1) { | ||
shouldUpdateOnHit && onCacheHit(cache, normalizedOptions, memoized); | ||
onCacheHit && onCacheHit(cache, normalizedOptions, memoized); | ||
if (keyIndex) { | ||
orderByLru(cache, keys[keyIndex], values[keyIndex], keyIndex, maxSize); | ||
shouldUpdateOnChange && | ||
onCacheChange(cache, normalizedOptions, memoized); | ||
cache.orderByLru(cache.keys[keyIndex], cache.values[keyIndex], keyIndex); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
@@ -247,14 +258,16 @@ } | ||
var newValue = fn.apply(this, arguments); | ||
var newKey = shouldCloneArguments ? key : slice.call(arguments, 0); | ||
orderByLru(cache, newKey, newValue, keys.length, maxSize); | ||
isPromise && updateAsyncCache(cache, memoized); | ||
shouldUpdateOnAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, normalizedOptions, memoized); | ||
var newKey = shouldCloneArguments ? key : copyArray(normalizedArgs); | ||
cache.orderByLru(newKey, newValue, cache.size); | ||
isPromise && cache._updateAsync(memoized); | ||
onCacheAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
onCacheChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
return values[0]; | ||
return cache.values[0]; | ||
} | ||
defineProperties(memoized, { | ||
Object.defineProperties(memoized, { | ||
cache: { | ||
configurable: true, | ||
enumerable: false, | ||
value: cache, | ||
writable: true, | ||
}, | ||
@@ -265,5 +278,5 @@ cacheSnapshot: { | ||
return { | ||
keys: slice.call(cache.keys, 0), | ||
keys: copyArray(cache.keys), | ||
size: cache.size, | ||
values: slice.call(cache.values, 0), | ||
values: copyArray(cache.values), | ||
}; | ||
@@ -274,7 +287,11 @@ }, | ||
configurable: true, | ||
enumerable: false, | ||
value: true, | ||
writable: true, | ||
}, | ||
options: { | ||
configurable: true, | ||
enumerable: false, | ||
value: normalizedOptions, | ||
writable: true, | ||
}, | ||
@@ -281,0 +298,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self)["micro-memoize"]=n()}(this,function(){"use strict";var P={isEqual:!0,isMatchingKey:!0,isPromise:!0,maxSize:!0,onCacheAdd:!0,onCacheChange:!0,onCacheHit:!0,transformKey:!0};function j(e){var u=e.isEqual,r=e.isMatchingKey,o=e.maxSize;return"function"==typeof r?function(e,n){if(r(e[0],n))return 0;if(1<o)for(var t=e.length,i=1;i<t;i++)if(r(e[i],n))return i;return-1}:1<o?function(e,n){for(var t,i=e.length,r=n.length,o=0;o<i;o++)if((t=e[o]).length===r){for(var a=0;a<r&&u(t[a],n[a]);a++);if(a===r)return o}return-1}:function(e,n){var t=e[0],i=t.length;if(n.length!==i)return-1;for(var r=0;r<i;r++)if(!u(t[r],n[r]))return-1;return 0}}function w(e,n){return e===n||e!=e&&n!=n}function O(e,n,t,i,r){for(var o=i;o--;)e.keys[o+1]=e.keys[o],e.values[o+1]=e.values[o];e.keys[0]=n,e.values[0]=t,r<=i&&(e.keys.length=r,e.values.length=r)}var B=Array.prototype.slice,D=Object.defineProperties;return function(o,e){if(void 0===e&&(e={}),o.isMemoized)return o;var r,a,u,f,c,s,n=e.isEqual,t=void 0===n?w:n,i=e.isMatchingKey,l=e.isPromise,h=void 0!==l&&l,v=e.maxSize,y=void 0===v?1:v,g=e.onCacheAdd,d=e.onCacheChange,p=e.onCacheHit,m=e.transformKey,C=function(e,n){var t={};for(var i in e)t[i]=e[i];for(var i in n)t[i]=n[i];return t}(function(e){var n={};for(var t in e)P[t]||(n[t]=e[t]);return n}(e),{isEqual:t,isMatchingKey:i,isPromise:h,maxSize:y,onCacheAdd:g,onCacheChange:d,onCacheHit:p,transformKey:m}),k=j(C),z=(a=j(r=C),u=r.onCacheChange,f=r.onCacheHit,c="function"==typeof u,s="function"==typeof f,function(t,n){var i=t.keys[0];t.values[0]=t.values[0].then(function(e){return s&&f(t,r,n),c&&u(t,r,n),e}).catch(function(e){var n=a(t.keys,i);throw-1!==n&&(t.keys.splice(n,1),t.values.splice(n,1)),e})}),K=[],b=[],x={keys:K,get size(){return x.keys.length},values:b},M="function"==typeof m,S=!(!m&&!i),q="function"==typeof g,A="function"==typeof d,E="function"==typeof p;function H(){var e=S?B.call(arguments,0):arguments,n=M?m(e):e,t=K.length?k(K,n):-1;if(-1!==t)E&&p(x,C,H),t&&(O(x,K[t],b[t],t,y),A&&d(x,C,H));else{var i=o.apply(this,arguments),r=S?n:B.call(arguments,0);O(x,r,i,K.length,y),h&&z(x,H),q&&g(x,C,H),A&&d(x,C,H)}return b[0]}return D(H,{cache:{configurable:!0,value:x},cacheSnapshot:{configurable:!0,get:function(){return{keys:B.call(x.keys,0),size:x.size,values:B.call(x.values,0)}}},isMemoized:{configurable:!0,value:!0},options:{configurable:!0,value:C}}),H}}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self)["micro-memoize"]=t()}(this,function(){"use strict";var m=function(){function e(e){this.keys=[],this.values=[],this.options=e,this.getKeyIndex="function"==typeof e.isMatchingKey?this._getKeyIndexByMatchingKey:1<e.maxSize?this._getKeyIndexForMultipleCache:this._getKeyIndexForSingleCache}return Object.defineProperty(e.prototype,"size",{get:function(){return this.keys.length},enumerable:!0,configurable:!0}),e.prototype._getKeyIndexByMatchingKey=function(e){if(this.options.isMatchingKey(this.keys[0],e))return 0;if(1<this.options.maxSize)for(var t=this.keys,n=this.options.isMatchingKey,i=t.length,o=1;o<i;o++)if(n(t[o],e))return o;return-1},e.prototype._getKeyIndexForMultipleCache=function(e){for(var t,n=this.keys,i=this.size,o=this.options.isEqual,r=e.length,s=0;s<i;s++)if((t=n[s]).length===r){for(var a=0;a<r&&o(t[a],e[a]);a++);if(a===r)return s}return-1},e.prototype._getKeyIndexForSingleCache=function(e){var t=this.keys[0],n=t.length;if(e.length!==n)return-1;for(var i=this.options.isEqual,o=0;o<n;o++)if(!i(t[o],e[o]))return-1;return 0},e.prototype._updateAsync=function(t){var n=this,i=this.keys[0];this.values[0]=this.values[0].then(function(e){return"function"==typeof n.options.onCacheHit&&n.options.onCacheHit(n,n.options,t),"function"==typeof n.options.onCacheChange&&n.options.onCacheChange(n,n.options,t),e}).catch(function(e){var t=n.getKeyIndex(i);throw-1!==t&&(n.keys.splice(t,1),n.values.splice(t,1)),e})},e.prototype.orderByLru=function(e,t,n){for(var i=this.keys,o=this.values,r=this.options.maxSize,s=n;s--;)i[s+1]=i[s],o[s+1]=o[s];i[0]=e,o[0]=t,r<=n&&(i.length=r,o.length=r)},e}(),C={isEqual:!0,isMatchingKey:!0,isPromise:!0,maxSize:!0,onCacheAdd:!0,onCacheChange:!0,onCacheHit:!0,transformKey:!0};function K(e){for(var t=e.length,n=new Array(t),i=0;i<t;i++)n[i]=e[i];return n}function x(e,t){return e===t||e!=e&&t!=t}return function(r,e){if(void 0===e&&(e={}),r.isMemoized)return r;var t=e.isEqual,n=void 0===t?x:t,i=e.isMatchingKey,o=e.isPromise,s=void 0!==o&&o,a=e.maxSize,u=void 0===a?1:a,h=e.onCacheAdd,c=e.onCacheChange,f=e.onCacheHit,y=e.transformKey,l=function(e,t){var n={};for(var i in e)n[i]=e[i];for(var i in t)n[i]=t[i];return n}(function(e){var t={};for(var n in e)C[n]||(t[n]=e[n]);return t}(e),{isEqual:n,isMatchingKey:i,isPromise:s,maxSize:u,onCacheAdd:h,onCacheChange:c,onCacheHit:f,transformKey:y}),p=new m(l),g="function"==typeof y,d=g||!!i;function v(){var e=d?K(arguments):arguments,t=g?y(e):e,n=p.size?p.getKeyIndex(t):-1;if(-1!==n)f&&f(p,l,v),n&&(p.orderByLru(p.keys[n],p.values[n],n),c&&c(p,l,v));else{var i=r.apply(this,arguments),o=d?t:K(e);p.orderByLru(o,i,p.size),s&&p._updateAsync(v),h&&h(p,l,v),c&&c(p,l,v)}return p.values[0]}return Object.defineProperties(v,{cache:{configurable:!0,enumerable:!1,value:p,writable:!0},cacheSnapshot:{configurable:!0,get:function(){return{keys:K(p.keys),size:p.size,values:K(p.values)}}},isMemoized:{configurable:!0,enumerable:!1,value:!0,writable:!0},options:{configurable:!0,enumerable:!1,value:l,writable:!0}}),v}}); |
@@ -10,5 +10,17 @@ declare namespace MicroMemoize { | ||
export type Options = { | ||
isEqual?: EqualityComparator; | ||
isMatchingKey?: MatchingKeyComparator; | ||
isPromise?: boolean; | ||
maxSize?: number; | ||
onCacheAdd?: CacheModifiedHandler; | ||
onCacheChange?: CacheModifiedHandler; | ||
onCacheHit?: CacheModifiedHandler; | ||
transformKey?: KeyTransformer; | ||
}; | ||
export type Cache = { | ||
keys: Keys; | ||
size: number; | ||
getKeyIndex: (key: RawKey) => number; | ||
options: Options; | ||
values: Values; | ||
@@ -33,15 +45,2 @@ }; | ||
export type Options = { | ||
[key: string]: any; | ||
[index: number]: any; | ||
isEqual?: EqualityComparator; | ||
isMatchingKey?: MatchingKeyComparator; | ||
isPromise?: boolean; | ||
maxSize?: number; | ||
onCacheAdd?: CacheModifiedHandler; | ||
onCacheChange?: CacheModifiedHandler; | ||
onCacheHit?: CacheModifiedHandler; | ||
transformKey?: KeyTransformer; | ||
}; | ||
export interface Memoized extends Function { | ||
@@ -48,0 +47,0 @@ [key: string]: any; |
@@ -18,5 +18,5 @@ { | ||
"@types/bluebird": "^3.5.25", | ||
"@types/jest": "^24.0.5", | ||
"@types/jest": "^24.0.6", | ||
"@types/react": "^16.8.3", | ||
"benchee": "^1.0.0", | ||
"benchee": "^1.1.0", | ||
"benchmark": "^2.1.4", | ||
@@ -40,3 +40,3 @@ "bluebird": "^3.5.2", | ||
"react": "^16.8.2", | ||
"rollup": "^1.1.2", | ||
"rollup": "^1.2.1", | ||
"rollup-plugin-typescript": "^1.0.0", | ||
@@ -53,3 +53,3 @@ "rollup-plugin-uglify": "^6.0.0", | ||
"underscore": "^1.9.1", | ||
"webpack": "^4.29.4", | ||
"webpack": "^4.29.5", | ||
"webpack-cli": "^3.1.2", | ||
@@ -96,2 +96,4 @@ "webpack-dev-server": "^3.1.9" | ||
"release": "release-it", | ||
"release:beta": "release-it --config=.release-it.beta.json", | ||
"release:dry": "release-it --dry-run", | ||
"start": "npm run dev", | ||
@@ -104,3 +106,3 @@ "test": "NODE_PATH=. jest", | ||
"types": "./index.d.ts", | ||
"version": "3.0.1" | ||
"version": "3.1.0-beta.0" | ||
} |
{ | ||
"extends": "tslint-config-airbnb", | ||
"rules": { | ||
"function-name": false, | ||
"import-name": false, | ||
"no-increment-decrement": false, | ||
"no-this-assignment": false, | ||
"prefer-array-literal": false | ||
} | ||
} |
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
446452
29
2805
1