« get me outta code hell

data: withPropertiesFrom{Object,List} - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/composite.js
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-09-09 08:47:38 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-09-09 08:47:38 -0300
commit7a21c665d888b0db4c47c72049f7649bf1dabcde (patch)
tree0f35daa330a9520c90866d2f5eaf1f45791a1be3 /src/data/things/composite.js
parent726118e7e8eefa9002562ca2dd0a4f6deb8a05b9 (diff)
data: withPropertiesFrom{Object,List}
Diffstat (limited to 'src/data/things/composite.js')
-rw-r--r--src/data/things/composite.js72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/data/things/composite.js b/src/data/things/composite.js
index b37b8e31..e3225563 100644
--- a/src/data/things/composite.js
+++ b/src/data/things/composite.js
@@ -1119,6 +1119,39 @@ export function withPropertyFromObject({
   };
 }
 
+// Gets the listed properties from some object, providing each property's value
+// as a dependency prefixed with the same name as the object (by default).
+// If the object itself is null, all provided dependencies will be null;
+// if it's missing only select properties, those will be provided as null.
+export function withPropertiesFromObject({
+  object,
+  properties,
+  prefix =
+    (object.startsWith('#')
+      ? object
+      : `#${object}`),
+}) {
+  return {
+    annotation: `withPropertiesFromObject`,
+    flags: {expose: true, compose: true},
+
+    expose: {
+      mapDependencies: {object},
+      options: {prefix, properties},
+
+      compute: ({object, '#options': {prefix, properties}}, continuation) =>
+        continuation(
+          Object.fromEntries(
+            properties.map(property => [
+              `${prefix}.${property}`,
+              (object === null || object === undefined
+                ? null
+                : object[property] ?? null),
+            ]))),
+    },
+  };
+}
+
 // Gets a property from each of a list of objects (in a dependency) and
 // provides the results. This doesn't alter any list indices, so positions
 // which were null in the original list are kept null here. Objects which don't
@@ -1159,6 +1192,45 @@ export function withPropertyFromList({
   };
 }
 
+// Gets the listed properties from each of a list of objects, providing lists
+// of property values each into a dependency prefixed with the same name as the
+// list (by default). Like withPropertyFromList, this doesn't alter indices.
+export function withPropertiesFromList({
+  list,
+  properties,
+  prefix =
+    (list.startsWith('#')
+      ? list
+      : `#${list}`),
+}) {
+  return {
+    annotation: `withPropertiesFromList`,
+    flags: {expose: true, compose: true},
+
+    expose: {
+      mapDependencies: {list},
+      options: {prefix, properties},
+
+      compute({list, '#options': {prefix, properties}}, continuation) {
+        const lists =
+          Object.fromEntries(
+            properties.map(property => [`${prefix}.${property}`, []]));
+
+        for (const item of list) {
+          for (const property of properties) {
+            lists[`${prefix}.${property}`].push(
+              (item === null || item === undefined
+                ? null
+                : item[property] ?? null));
+          }
+        }
+
+        return continuation(lists);
+      }
+    }
+  }
+}
+
 // Replaces items of a list, which are null or undefined, with some fallback
 // value, either a constant (set {value}) or from a dependency ({dependency}).
 // By default, this replaces the passed dependency.