diff --git a/TODO.md b/TODO.md index 47a6cfb..8b13789 100644 --- a/TODO.md +++ b/TODO.md @@ -1,2 +1 @@ -- $and | Add 'strict' mode option (src/expressions/logical.ts) -- paramResolver | Study paramResolver memoization (src/interpreter/asyncParamResolver.ts) + diff --git a/package.json b/package.json index b0c526b..a8e13d5 100644 --- a/package.json +++ b/package.json @@ -65,8 +65,9 @@ "typescript": "^4.0.2" }, "dependencies": { - "@orioro/typing": "^4.3.0", - "lodash": "^4.17.20" + "@orioro/typing": "^4.4.0", + "lodash": "^4.17.20", + "memoizee": "^0.4.15" }, "config": { "commitizen": { diff --git a/src/interpreter/asyncInterpreter.ts b/src/interpreter/asyncInterpreter.ts index 16f1c11..329cfc4 100644 --- a/src/interpreter/asyncInterpreter.ts +++ b/src/interpreter/asyncInterpreter.ts @@ -2,13 +2,15 @@ import { InterpreterSpecSingle, InterpreterFunction } from '../types' import { asyncParamResolver } from './asyncParamResolver' +import { castTypeSpec } from '@orioro/typing' + export const asyncInterpreter = ( spec: InterpreterSpecSingle ): InterpreterFunction => { const [ fn, - paramResolvers, - { defaultParam = paramResolvers.length - 1 } = {}, + paramTypeSpecs, + { defaultParam = paramTypeSpecs.length - 1 } = {}, ] = spec // @@ -16,8 +18,8 @@ export const asyncInterpreter = ( // to outside the returned interperter wrapper function // in order to minimize expression evaluation performance // - const asyncParamResolvers = paramResolvers.map((resolver) => - asyncParamResolver(resolver) + const asyncParamResolvers = paramTypeSpecs.map((typeSpec) => + asyncParamResolver(castTypeSpec(typeSpec)) ) return (context, ...args) => diff --git a/src/interpreter/asyncParamResolver.ts b/src/interpreter/asyncParamResolver.ts index e3b70b2..43252a0 100644 --- a/src/interpreter/asyncParamResolver.ts +++ b/src/interpreter/asyncParamResolver.ts @@ -1,5 +1,6 @@ +import memoize from 'memoizee/weak' + import { - castTypeSpec, ANY_TYPE, SINGLE_TYPE, ONE_OF_TYPES, @@ -8,11 +9,12 @@ import { INDEFINITE_OBJECT_OF_TYPE, TUPLE_TYPE, OBJECT_TYPE, + NonShorthandTypeSpec, } from '@orioro/typing' import { validateType, isType } from '../typing' -import { TypeSpec, ParamResolver } from '../types' +import { ParamResolver } from '../types' import { evaluate, evaluateTypedAsync } from '../evaluate' import { promiseResolveObject } from '../util/promiseResolveObject' @@ -21,110 +23,111 @@ import { _pseudoSymbol } from '../util/misc' const _NOT_RESOLVED = _pseudoSymbol() -const _asyncParamResolver = (typeSpec: TypeSpec): ParamResolver => { - const expectedType = castTypeSpec(typeSpec) - - if (expectedType === null) { - throw new TypeError(`Invalid typeSpec: ${JSON.stringify(typeSpec)}`) - } +const _asyncParamResolver = memoize( + (typeSpec: NonShorthandTypeSpec): ParamResolver => { + if (typeSpec.skipEvaluation) { + return (context, value) => Promise.resolve(value) + } - if (expectedType.skipEvaluation) { - return (context, value) => Promise.resolve(value) - } + switch (typeSpec.specType) { + case ANY_TYPE: + case SINGLE_TYPE: + case ENUM_TYPE: + return (context, value) => Promise.resolve(evaluate(context, value)) + case ONE_OF_TYPES: { + // This resolver is quite costly: it attempts to resolve + // against each of the listed possible types + const candidateResolverPairs: [ + NonShorthandTypeSpec, + ParamResolver + ][] = typeSpec.types.map((type) => [type, _asyncParamResolver(type)]) + + return (context, value) => { + return candidateResolverPairs + .reduce((accPromise, [candidateType, candidateResolver]) => { + return accPromise.then((acc) => { + if (acc !== _NOT_RESOLVED) { + return acc + } else { + return candidateResolver(context, value).then((result) => { + return isType(candidateType, result) + ? result + : _NOT_RESOLVED + }) + } + }) + }, Promise.resolve(_NOT_RESOLVED)) + .then((result) => (result === _NOT_RESOLVED ? value : result)) + } + } + case TUPLE_TYPE: { + const itemParamResolvers = typeSpec.items.map((itemResolver) => + _asyncParamResolver(itemResolver) + ) - switch (expectedType.specType) { - case ANY_TYPE: - case SINGLE_TYPE: - case ENUM_TYPE: - return (context, value) => Promise.resolve(evaluate(context, value)) - case ONE_OF_TYPES: { - // This resolver is quite costly: it attempts to resolve - // against each of the listed possible types - const candidateResolverPairs: [ - TypeSpec, - ParamResolver - ][] = expectedType.types.map((type) => [type, _asyncParamResolver(type)]) - - return (context, value) => { - return candidateResolverPairs - .reduce((accPromise, [candidateType, candidateResolver]) => { - return accPromise.then((acc) => { - if (acc !== _NOT_RESOLVED) { - return acc - } else { - return candidateResolver(context, value).then((result) => { - return isType(candidateType, result) ? result : _NOT_RESOLVED - }) - } - }) - }, Promise.resolve(_NOT_RESOLVED)) - .then((result) => (result === _NOT_RESOLVED ? value : result)) + return (context, value) => { + return evaluateTypedAsync('array', context, value).then((array) => { + return Promise.all( + array.map((item, index) => { + return itemParamResolvers[index](context, item) + }) + ) + }) + } } - } - case TUPLE_TYPE: { - const itemParamResolvers = expectedType.items.map((itemResolver) => - _asyncParamResolver(itemResolver) - ) - - return (context, value) => { - return evaluateTypedAsync('array', context, value).then((array) => { - return Promise.all( - array.map((item, index) => { - return itemParamResolvers[index](context, item) - }) - ) - }) + case INDEFINITE_ARRAY_OF_TYPE: { + const itemParamResolver = _asyncParamResolver(typeSpec.itemType) + + return (context, value) => { + return evaluateTypedAsync('array', context, value).then((array) => { + return Promise.all( + array.map((item) => itemParamResolver(context, item)) + ) + }) + } } - } - case INDEFINITE_ARRAY_OF_TYPE: { - const itemParamResolver = _asyncParamResolver(expectedType.itemType) + case OBJECT_TYPE: { + const propertyParamResolvers = Object.keys(typeSpec.properties).reduce( + (acc, key) => ({ + ...acc, + [key]: _asyncParamResolver(typeSpec.properties[key]), + }), + {} + ) - return (context, value) => { - return evaluateTypedAsync('array', context, value).then((array) => { - return Promise.all( - array.map((item) => itemParamResolver(context, item)) + return (context, value) => + evaluateTypedAsync( + 'object', + context, + value + ).then((unresolvedObject) => + promiseResolveObject( + unresolvedObject, + (propertyValue, propertyKey) => + propertyParamResolvers[propertyKey](context, propertyValue) + ) ) - }) } - } - case OBJECT_TYPE: { - const propertyParamResolvers = Object.keys( - expectedType.properties - ).reduce( - (acc, key) => ({ - ...acc, - [key]: _asyncParamResolver(expectedType.properties[key]), - }), - {} - ) - - return (context, value) => - evaluateTypedAsync('object', context, value).then((unresolvedObject) => - promiseResolveObject(unresolvedObject, (propertyValue, propertyKey) => - propertyParamResolvers[propertyKey](context, propertyValue) + case INDEFINITE_OBJECT_OF_TYPE: { + const propertyParamResolver = _asyncParamResolver(typeSpec.propertyType) + + return (context, value) => + evaluateTypedAsync('object', context, value).then((object) => + promiseResolveObject(object, (propertyValue) => + propertyParamResolver(context, propertyValue) + ) ) - ) - } - case INDEFINITE_OBJECT_OF_TYPE: { - const propertyParamResolver = _asyncParamResolver( - expectedType.propertyType - ) - - return (context, value) => - evaluateTypedAsync('object', context, value).then((object) => - promiseResolveObject(object, (propertyValue) => - propertyParamResolver(context, propertyValue) - ) - ) + } } } -} +) /** - * @todo paramResolver Study paramResolver memoization * @function asyncParamResolver */ -export const asyncParamResolver = (typeSpec: TypeSpec): ParamResolver => { +export const asyncParamResolver = ( + typeSpec: NonShorthandTypeSpec +): ParamResolver => { // `_asyncParamResolver` (private) contains the logic for the resolution itself // but does not run any kind of validation // validation is executed at `asyncParamResolver` (public) diff --git a/src/interpreter/paramResolver.spec.ts b/src/interpreter/paramResolver.spec.ts index 236a27c..f45637b 100644 --- a/src/interpreter/paramResolver.spec.ts +++ b/src/interpreter/paramResolver.spec.ts @@ -2,6 +2,7 @@ import { testCases, asyncResult } from '@orioro/jest-util' import { ALL_EXPRESSIONS } from '../' import { + castTypeSpec, anyType, tupleType, indefiniteArrayOfType, @@ -15,6 +16,8 @@ import { asyncParamResolver } from './asyncParamResolver' const interpreters = interpreterList(ALL_EXPRESSIONS) const _resolverTestCases = (cases, paramSpec) => { + paramSpec = castTypeSpec(paramSpec) + const syncResolver = syncParamResolver(paramSpec) const asyncResolver = asyncParamResolver(paramSpec) @@ -56,14 +59,6 @@ const _resolverTestCases = (cases, paramSpec) => { ) } -test('invalid type', () => { - expect(() => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - syncParamResolver(10) - }).toThrow('Invalid typeSpec') -}) - describe('anyType()', () => { _resolverTestCases( [ diff --git a/src/interpreter/syncInterpreter.ts b/src/interpreter/syncInterpreter.ts index 9752856..ecde9ef 100644 --- a/src/interpreter/syncInterpreter.ts +++ b/src/interpreter/syncInterpreter.ts @@ -2,6 +2,8 @@ import { InterpreterSpecSingle, InterpreterFunction } from '../types' import { syncParamResolver } from './syncParamResolver' +import { castTypeSpec } from '@orioro/typing' + /** * @function syncInterpreter * @returns {Interpreter} @@ -21,7 +23,7 @@ export const syncInterpreter = ( // in order to minimize expression evaluation performance // const syncParamResolvers = paramTypeSpecs.map((typeSpec) => - syncParamResolver(typeSpec) + syncParamResolver(castTypeSpec(typeSpec)) ) return (context, ...args) => diff --git a/src/interpreter/syncParamResolver.ts b/src/interpreter/syncParamResolver.ts index 3ee2817..380b536 100644 --- a/src/interpreter/syncParamResolver.ts +++ b/src/interpreter/syncParamResolver.ts @@ -1,5 +1,6 @@ +import memoize from 'memoizee/weak' + import { - castTypeSpec, ANY_TYPE, SINGLE_TYPE, ONE_OF_TYPES, @@ -8,11 +9,12 @@ import { INDEFINITE_OBJECT_OF_TYPE, TUPLE_TYPE, OBJECT_TYPE, + NonShorthandTypeSpec, } from '@orioro/typing' import { validateType, isType } from '../typing' -import { ParamResolver, TypeSpec } from '../types' +import { ParamResolver } from '../types' import { evaluate, evaluateTyped } from '../evaluate' @@ -20,114 +22,107 @@ import { _pseudoSymbol } from '../util/misc' const _NOT_RESOLVED = _pseudoSymbol() -const _syncParamResolver = (typeSpec: TypeSpec): ParamResolver => { - const expectedType = castTypeSpec(typeSpec) - - if (expectedType === null) { - throw new TypeError(`Invalid typeSpec: ${JSON.stringify(typeSpec)}`) - } - - if (expectedType.skipEvaluation) { - return (context, value) => value - } +const _syncParamResolver = memoize( + (typeSpec: NonShorthandTypeSpec): ParamResolver => { + if (typeSpec.skipEvaluation) { + return (context, value) => value + } - switch (expectedType.specType) { - case ANY_TYPE: - case SINGLE_TYPE: - case ENUM_TYPE: - return evaluate - case ONE_OF_TYPES: { - const candidateResolverPairs: [ - TypeSpec, - ParamResolver - ][] = expectedType.types.map((type) => [type, _syncParamResolver(type)]) - - return (context, value) => { - const result = candidateResolverPairs.reduce( - (acc, [candidateType, candidateResolver]) => { - if (acc !== _NOT_RESOLVED) { - return acc - } else { - const result = candidateResolver(context, value) - - return isType(candidateType, result) ? result : _NOT_RESOLVED - } - }, - _NOT_RESOLVED + switch (typeSpec.specType) { + case ANY_TYPE: + case SINGLE_TYPE: + case ENUM_TYPE: + return evaluate + case ONE_OF_TYPES: { + const candidateResolverPairs: [ + NonShorthandTypeSpec, + ParamResolver + ][] = typeSpec.types.map((type) => [type, _syncParamResolver(type)]) + + return (context, value) => { + const result = candidateResolverPairs.reduce( + (acc, [candidateType, candidateResolver]) => { + if (acc !== _NOT_RESOLVED) { + return acc + } else { + const result = candidateResolver(context, value) + + return isType(candidateType, result) ? result : _NOT_RESOLVED + } + }, + _NOT_RESOLVED + ) + + return result === _NOT_RESOLVED ? value : result + } + } + case TUPLE_TYPE: { + const itemParamResolvers = typeSpec.items.map((itemResolver) => + _syncParamResolver(itemResolver) ) - return result === _NOT_RESOLVED ? value : result - } - } - case TUPLE_TYPE: { - const itemParamResolvers = expectedType.items.map((itemResolver) => - _syncParamResolver(itemResolver) - ) - - return (context, value) => { - const array = evaluateTyped( - 'array', - context, - value - ).map((item, index) => itemParamResolvers[index](context, item)) - - return array + return (context, value) => { + const array = evaluateTyped( + 'array', + context, + value + ).map((item, index) => itemParamResolvers[index](context, item)) + + return array + } } - } - case INDEFINITE_ARRAY_OF_TYPE: { - const itemParamResolver = _syncParamResolver(expectedType.itemType) + case INDEFINITE_ARRAY_OF_TYPE: { + const itemParamResolver = _syncParamResolver(typeSpec.itemType) - return (context, value) => { - const array = evaluateTyped('array', context, value).map((item) => - itemParamResolver(context, item) - ) + return (context, value) => { + const array = evaluateTyped('array', context, value).map((item) => + itemParamResolver(context, item) + ) - return array + return array + } } - } - case OBJECT_TYPE: { - const propertyParamResolvers = Object.keys( - expectedType.properties - ).reduce( - (acc, key) => ({ - ...acc, - [key]: _syncParamResolver(expectedType.properties[key]), - }), - {} - ) - - return (context, value) => { - const _object = evaluateTyped('object', context, value) - const object = Object.keys(_object).reduce( + case OBJECT_TYPE: { + const propertyParamResolvers = Object.keys(typeSpec.properties).reduce( (acc, key) => ({ ...acc, - [key]: propertyParamResolvers[key](context, _object[key]), + [key]: _syncParamResolver(typeSpec.properties[key]), }), {} ) - return object + return (context, value) => { + const _object = evaluateTyped('object', context, value) + const object = Object.keys(_object).reduce( + (acc, key) => ({ + ...acc, + [key]: propertyParamResolvers[key](context, _object[key]), + }), + {} + ) + + return object + } } - } - case INDEFINITE_OBJECT_OF_TYPE: - return (context, value) => { - const propertyParamResolver = _syncParamResolver( - expectedType.propertyType - ) - - const _object = evaluateTyped('object', context, value) - const object = Object.keys(_object).reduce( - (acc, key) => ({ - ...acc, - [key]: propertyParamResolver(context, _object[key]), - }), - {} - ) - - return object + case INDEFINITE_OBJECT_OF_TYPE: { + const propertyParamResolver = _syncParamResolver(typeSpec.propertyType) + + return (context, value) => { + const _object = evaluateTyped('object', context, value) + const object = Object.keys(_object).reduce( + (acc, key) => ({ + ...acc, + [key]: propertyParamResolver(context, _object[key]), + }), + {} + ) + + return object + } } + } } -} +) /** * @function syncParamResolver @@ -135,7 +130,9 @@ const _syncParamResolver = (typeSpec: TypeSpec): ParamResolver => { * @param {TypeSpec} typeSpec * @returns {ParamResolver} */ -export const syncParamResolver = (typeSpec: TypeSpec): ParamResolver => { +export const syncParamResolver = ( + typeSpec: NonShorthandTypeSpec +): ParamResolver => { const _paramResolver = _syncParamResolver(typeSpec) return (context, value) => { diff --git a/yarn.lock b/yarn.lock index 7de69a0..deeaa27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1271,10 +1271,10 @@ vinyl-fs "^3.0.3" yargs "^16.2.0" -"@orioro/typing@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@orioro/typing/-/typing-4.3.0.tgz#c704bba696a5ecf987dc3b8d3e178c811ba86a15" - integrity sha512-Qnq+f4MkpGX0pfGNcs3WzXQfslZ4ovwfkzERf1kdb8XPUXd90m7Of5nS5fmYhWw1RkwLXfSEAvsvjh8HfVjVSg== +"@orioro/typing@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@orioro/typing/-/typing-4.4.0.tgz#e87db967cd028939706ca822b22a4db0407b69a5" + integrity sha512-h2tOZLCM/QvBRsvMfPcTZvpjaHjGeVWlA5JJWcxEh2WwZaGhpY5UDA+WVysTuXBaHvcu5E6T3jyKMdPFxAQ1KA== dependencies: "@orioro/cascade" "^3.0.0" deep-equal "^2.0.5" @@ -2869,6 +2869,14 @@ cz-conventional-changelog@^3.3.0: optionalDependencies: "@commitlint/load" ">6.1.1" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3308,6 +3316,24 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -3320,6 +3346,24 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -3480,6 +3524,14 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + exec-sh@^0.3.2: version "0.3.4" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" @@ -3585,6 +3637,13 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -4865,6 +4924,11 @@ is-potential-custom-element-name@^1.0.0: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" @@ -6024,6 +6088,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + luxon@^1.25.0: version "1.25.0" resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72" @@ -6153,6 +6224,20 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +memoizee@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -6385,6 +6470,16 @@ nerf-dart@^1.0.0: resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" integrity sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo= +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -8681,6 +8776,14 @@ timed-out@^4.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= +timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + tiny-relative-date@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" @@ -8862,6 +8965,16 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"