« get me outta code hell

find, reverse: fr.bind + bindReverse - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-01-11 17:05:25 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-01-11 17:05:25 -0400
commit13f91d9ff89dcf0ca8b7895b21b1e0cf43df38f9 (patch)
treef25a02cd225c505ec8d1b16f5f3b59e77f8fd4a8 /src
parent3cc050187760c758c4760121281ff9a7e0b626f5 (diff)
find, reverse: fr.bind + bindReverse
Diffstat (limited to 'src')
-rw-r--r--src/find-reverse.js34
-rw-r--r--src/find.js41
-rw-r--r--src/reverse.js17
-rw-r--r--src/write/build-modes/repl.js13
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,
   };