From 13f91d9ff89dcf0ca8b7895b21b1e0cf43df38f9 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 11 Jan 2025 17:05:25 -0400 Subject: find, reverse: fr.bind + bindReverse --- src/find-reverse.js | 34 ++++++++++++++++++++++++++++++++++ src/find.js | 41 ++++++++++------------------------------- src/reverse.js | 17 ++++++++++++++++- src/write/build-modes/repl.js | 13 ++++++++++++- 4 files changed, 72 insertions(+), 33 deletions(-) diff --git a/src/find-reverse.js b/src/find-reverse.js index 5f8e2100..1e897a5c 100644 --- a/src/find-reverse.js +++ b/src/find-reverse.js @@ -96,4 +96,38 @@ export function tokenProxy({ }); } +export function bind(wikiData, opts1, { + getAllSpecs, + prepareBehavior, +}) { + const specs = getAllSpecs(); + + const bound = {}; + + for (const [key, spec] of Object.entries(specs)) { + if (!spec.bindTo) continue; + + const behavior = prepareBehavior(spec); + const thingData = wikiData[spec.bindTo]; + + bound[key] = + (opts1 + ? (ref, opts2) => + (opts2 + ? behavior(ref, thingData, {...opts1, ...opts2}) + : behavior(ref, thingData, opts1)) + : (ref, opts2) => + (opts2 + ? behavior(ref, thingData, opts2) + : behavior(ref, thingData))); + + bound[key][boundData] = thingData; + bound[key][boundOptions] = opts1 ?? {}; + } + + return bound; +} + export const tokenKey = Symbol.for('find.tokenKey'); +export const boundData = Symbol.for('find.boundData'); +export const boundOptions = Symbol.for('find.boundOptions'); diff --git a/src/find.js b/src/find.js index d1435fb5..c7813e32 100644 --- a/src/find.js +++ b/src/find.js @@ -9,9 +9,11 @@ import * as fr from './find-reverse.js'; import { tokenKey as findTokenKey, + boundData as boundFindData, + boundOptions as boundFindOptions, } from './find-reverse.js'; -export {findTokenKey}; +export {findTokenKey, boundFindData, boundFindOptions}; function warnOrThrow(mode, message) { if (mode === 'error') { @@ -284,9 +286,6 @@ export function findFindSpec(key) { return fr.findSpec(key, findReverseHelperConfig); } -export const boundFindData = Symbol.for('find.boundFindData'); -export const boundFindOptions = Symbol.for('find.boundFindOptions'); - function findMixedHelper(config) { const keys = Object.keys(config), @@ -415,33 +414,13 @@ export default fr.tokenProxy({ // 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; } diff --git a/src/reverse.js b/src/reverse.js index 0f235369..324cbabe 100644 --- a/src/reverse.js +++ b/src/reverse.js @@ -1,5 +1,13 @@ import * as fr from './find-reverse.js'; +function reverseHelper(spec) { + const cache = new WeakMap(); + + return (thing, data) => { + return ({spec, from: thing, data: data.length}); + }; +} + const hardcodedReverseSpecs = {}; const findReverseHelperConfig = { @@ -28,5 +36,12 @@ export function findReverseSpec(key) { export default fr.tokenProxy({ findSpec: findReverseSpec, - prepareBehavior: spec => from => ({spec, from}), + prepareBehavior: reverseHelper, }); + +export function bindReverse(wikiData, opts) { + return fr.bind(wikiData, opts, { + getAllSpecs: getAllReverseSpecs, + prepareBehavior: reverseHelper, + }); +} diff --git a/src/write/build-modes/repl.js b/src/write/build-modes/repl.js index ff64ee82..920ad9f7 100644 --- a/src/write/build-modes/repl.js +++ b/src/write/build-modes/repl.js @@ -36,7 +36,7 @@ import * as path from 'node:path'; import * as repl from 'node:repl'; import _find, {bindFind} from '#find'; -import _reverse from '#reverse'; +import _reverse, {bindReverse} from '#reverse'; import CacheableObject from '#cacheable-object'; import {logWarn} from '#cli'; import {debugComposite} from '#composite'; @@ -67,6 +67,15 @@ export async function getContextAssignments({ logWarn`\`find\` variable will be missing`; } + let reverse; + try { + reverse = bindReverse(wikiData); + } catch (error) { + console.error(error); + logWarn`Failed to prepare wikiData-bound reverse() functions`; + logWarn`\`reverse\` variable will be missing`; + } + const replContext = { universalUtilities, ...universalUtilities, @@ -97,6 +106,8 @@ export async function getContextAssignments({ bindFind, _reverse, + reverse, + bindReverse, showAggregate, }; -- cgit 1.3.0-6-gf8a5