« get me outta code hell

data: withClonedThings - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-03-07 10:55:48 -0400
committer(quasar) nebula <qznebula@protonmail.com>2024-06-12 17:26:38 -0300
commit89e73c133d66a868c73c4ef0bac3e0aef67e6c26 (patch)
treec83b6002f4f65bd7366915daa4752e404917ff40
parent0e85744d5527774b7d6988cc543bb58b64d9e5f6 (diff)
data: withClonedThings
-rw-r--r--src/data/composite/wiki-data/index.js1
-rw-r--r--src/data/composite/wiki-data/withClonedThings.js68
-rw-r--r--src/data/composite/wiki-data/withRecontextualizedContributionList.js52
3 files changed, 97 insertions, 24 deletions
diff --git a/src/data/composite/wiki-data/index.js b/src/data/composite/wiki-data/index.js
index 9a9a5fa2..10922d72 100644
--- a/src/data/composite/wiki-data/index.js
+++ b/src/data/composite/wiki-data/index.js
@@ -6,6 +6,7 @@
 
 export {default as exitWithoutContribs} from './exitWithoutContribs.js';
 export {default as inputWikiData} from './inputWikiData.js';
+export {default as withClonedThings} from './withClonedThings.js';
 export {default as withContributionListSums} from './withContributionListSums.js';
 export {default as withDirectory} from './withDirectory.js';
 export {default as withDirectoryFromName} from './withDirectoryFromName.js';
diff --git a/src/data/composite/wiki-data/withClonedThings.js b/src/data/composite/wiki-data/withClonedThings.js
new file mode 100644
index 00000000..9af6aa84
--- /dev/null
+++ b/src/data/composite/wiki-data/withClonedThings.js
@@ -0,0 +1,68 @@
+// Clones all the things in a list. If the 'assign' input is provided,
+// all new things are assigned the same specified properties. If the
+// 'assignEach' input is provided, each new thing is assigned the
+// corresponding properties.
+
+import CacheableObject from '#cacheable-object';
+import {input, templateCompositeFrom} from '#composite';
+import {isObject, sparseArrayOf} from '#validators';
+
+import {withMappedList} from '#composite/data';
+
+export default templateCompositeFrom({
+  annotation: `withClonedThings`,
+
+  inputs: {
+    things: input({type: 'array'}),
+
+    assign: input({
+      type: 'object',
+      defaultValue: null,
+    }),
+
+    assignEach: input({
+      validate: sparseArrayOf(isObject),
+      defaultValue: null,
+    }),
+  },
+
+  outputs: ['#clonedThings'],
+
+  steps: () => [
+    {
+      dependencies: [input('assign'), input('assignEach')],
+      compute: (continuation, {
+        [input('assign')]: assign,
+        [input('assignEach')]: assignEach,
+      }) => continuation({
+        ['#assignmentMap']:
+          (index) =>
+            (assign && assignEach
+              ? {...assignEach[index] ?? {}, ...assign}
+           : assignEach
+              ? assignEach[index] ?? {}
+              : assign ?? {}),
+      }),
+    },
+
+    {
+      dependencies: ['#assignmentMap'],
+      compute: (continuation, {
+        ['#assignmentMap']: assignmentMap,
+      }) => continuation({
+        ['#cloningMap']:
+          (thing, index) =>
+            Object.assign(
+              CacheableObject.clone(thing),
+              assignmentMap(index)),
+      }),
+    },
+
+    withMappedList({
+      list: input('things'),
+      map: '#cloningMap',
+    }).outputs({
+      '#mappedList': '#clonedThings',
+    }),
+  ],
+});
diff --git a/src/data/composite/wiki-data/withRecontextualizedContributionList.js b/src/data/composite/wiki-data/withRecontextualizedContributionList.js
index 418b346f..1c86c0ab 100644
--- a/src/data/composite/wiki-data/withRecontextualizedContributionList.js
+++ b/src/data/composite/wiki-data/withRecontextualizedContributionList.js
@@ -2,11 +2,10 @@
 // updated to match the current thing. Overwrite the provided dependency.
 // Doesn't do anything if the provided dependency is null.
 
-import CacheableObject from '#cacheable-object';
 import {input, templateCompositeFrom} from '#composite';
 
 import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withMappedList} from '#composite/data';
+import {withClonedThings} from '#composite/wiki-data';
 
 export default templateCompositeFrom({
   annotation: `withRecontextualizedContributionList`,
@@ -23,9 +22,25 @@ export default templateCompositeFrom({
   }) => [list],
 
   steps: () => [
-    raiseOutputWithoutDependency({
-      dependency: input('list'),
-    }),
+    // TODO: Is raiseOutputWithoutDependency workable here?
+    // Is it true that not specifying any output wouldn't overwrite
+    // the provided dependency?
+    {
+      dependencies: [
+        input.staticDependency('list'),
+        input('list'),
+      ],
+
+      compute: (continuation, {
+        [input.staticDependency('list')]: dependency,
+        [input('list')]: list,
+      }) =>
+        (list
+          ? continuation()
+          : continuation.raiseOutput({
+              [dependency]: list,
+            })),
+    },
 
     {
       dependencies: [input.myself(), input.thisProperty()],
@@ -41,29 +56,18 @@ export default templateCompositeFrom({
       }),
     },
 
-    {
-      dependencies: ['#assignment'],
-
-      compute: (continuation, {
-        ['#assignment']: assignment,
-      }) => continuation({
-        ['#map']:
-          contrib =>
-            Object.assign(
-              CacheableObject.clone(contrib),
-              assignment),
-      }),
-    },
-
-    withMappedList({
-      list: input('list'),
-      map: '#map',
+    withClonedThings({
+      things: input('list'),
+      assign: '#assignment',
     }).outputs({
-      '#mappedList': '#newContributions',
+      '#clonedThings': '#newContributions',
     }),
 
     {
-      dependencies: [input.staticDependency('list'), '#newContributions'],
+      dependencies: [
+        input.staticDependency('list'),
+        '#newContributions',
+      ],
 
       compute: (continuation, {
         [input.staticDependency('list')]: listDependency,