diff options
Diffstat (limited to 'src/find.js')
-rw-r--r-- | src/find.js | 128 |
1 files changed, 34 insertions, 94 deletions
diff --git a/src/find.js b/src/find.js index d647419a..e590bc4f 100644 --- a/src/find.js +++ b/src/find.js @@ -5,6 +5,16 @@ import {compareObjects, stitchArrays, typeAppearance} from '#sugar'; import thingConstructors from '#things'; import {isFunction, validateArrayItems} from '#validators'; +import * as fr from './find-reverse.js'; + +import { + tokenKey as findTokenKey, + boundData as boundFindData, + boundOptions as boundFindOptions, +} from './find-reverse.js'; + +export {findTokenKey, boundFindData, boundFindOptions}; + function warnOrThrow(mode, message) { if (mode === 'error') { throw new Error(message); @@ -24,7 +34,7 @@ export function processAvailableMatchesByName(data, { include = _thing => true, getMatchableNames = thing => - (Object.hasOwn(thing, 'name') + (thing.constructor.hasPropertyDescriptor('name') ? [thing.name] : []), @@ -62,7 +72,7 @@ export function processAvailableMatchesByDirectory(data, { include = _thing => true, getMatchableDirectories = thing => - (Object.hasOwn(thing, 'directory') + (thing.constructor.hasPropertyDescriptor('directory') ? [thing.directory] : [null]), @@ -240,6 +250,14 @@ const hardcodedFindSpecs = { }, }; +const findReverseHelperConfig = { + word: `find`, + constructorKey: Symbol.for('Thing.findSpecs'), + + hardcodedSpecs: hardcodedFindSpecs, + postprocessSpec: postprocessFindSpec, +}; + export function postprocessFindSpec(spec, {thingConstructor}) { const newSpec = {...spec}; @@ -261,58 +279,13 @@ export function postprocessFindSpec(spec, {thingConstructor}) { } export function getAllFindSpecs() { - try { - thingConstructors; - } catch (error) { - throw new Error(`Thing constructors aren't ready yet, can't get all find specs`); - } - - const findSpecs = {...hardcodedFindSpecs}; - - for (const thingConstructor of Object.values(thingConstructors)) { - const thingFindSpecs = thingConstructor[Symbol.for('Thing.findSpecs')]; - if (!thingFindSpecs) continue; - - for (const [key, spec] of Object.entries(thingFindSpecs)) { - findSpecs[key] = - postprocessFindSpec(spec, { - thingConstructor, - }); - } - } - - return findSpecs; + return fr.getAllSpecs(findReverseHelperConfig); } export function findFindSpec(key) { - if (Object.hasOwn(hardcodedFindSpecs, key)) { - return hardcodedFindSpecs[key]; - } - - try { - thingConstructors; - } catch (error) { - throw new Error(`Thing constructors aren't ready yet, can't check if "find.${key}" available`); - } - - for (const thingConstructor of Object.values(thingConstructors)) { - const thingFindSpecs = thingConstructor[Symbol.for('Thing.findSpecs')]; - if (!thingFindSpecs) continue; - - if (Object.hasOwn(thingFindSpecs, key)) { - return postprocessFindSpec(thingFindSpecs[key], { - thingConstructor, - }); - } - } - - throw new Error(`"find.${key}" isn't available`); + return fr.findSpec(key, findReverseHelperConfig); } -export const findTokenKey = Symbol.for('find.findTokenKey'); -export const boundFindData = Symbol.for('find.boundFindData'); -export const boundFindOptions = Symbol.for('find.boundFindOptions'); - function findMixedHelper(config) { const keys = Object.keys(config), @@ -425,27 +398,14 @@ export function findMixed(config) { return findMixedStore.get(config); } -export default new Proxy({}, { - get: (store, key) => { +export default fr.tokenProxy({ + findSpec: findFindSpec, + prepareBehavior: findHelper, + + handle(key) { if (key === 'mixed') { return findMixed; } - - if (!Object.hasOwn(store, key)) { - let behavior = (...args) => { - // This will error if the find spec isn't available... - const findSpec = findFindSpec(key); - - // ...or, if it is available, replace this function with the - // ready-for-use find function made out of that find spec. - return (behavior = findHelper(findSpec))(...args); - }; - - store[key] = (...args) => behavior(...args); - store[key][findTokenKey] = key; - } - - return store[key]; }, }); @@ -454,33 +414,13 @@ export default new Proxy({}, { // function. Note that this caches the arrays read from wikiData right when it's // called, so if their values change, you'll have to continue with a fresh call // to bindFind. -export function bindFind(wikiData, opts1) { - const findSpecs = getAllFindSpecs(); - - const boundFindFns = {}; - - for (const [key, spec] of Object.entries(findSpecs)) { - if (!spec.bindTo) continue; - - const findFn = findHelper(spec); - const thingData = wikiData[spec.bindTo]; - - boundFindFns[key] = - (opts1 - ? (ref, opts2) => - (opts2 - ? findFn(ref, thingData, {...opts1, ...opts2}) - : findFn(ref, thingData, opts1)) - : (ref, opts2) => - (opts2 - ? findFn(ref, thingData, opts2) - : findFn(ref, thingData))); - - boundFindFns[key][boundFindData] = thingData; - boundFindFns[key][boundFindOptions] = opts1 ?? {}; - } +export function bindFind(wikiData, opts) { + const boundFind = fr.bind(wikiData, opts, { + getAllSpecs: getAllFindSpecs, + prepareBehavior: findHelper, + }); - boundFindFns.mixed = findMixed; + boundFind.mixed = findMixed; - return boundFindFns; + return boundFind; } |