« get me outta code hell

data: moar WIP composite syntax! - 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>2023-09-20 13:01:25 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-09-20 13:01:25 -0300
commit8db50e29b5a1cfddfddf499129b697ecabfadcb0 (patch)
tree20264a070f6f010a719fa4ea1937eaa1fa1b34b1
parent86679ee48eee7e1000b2b2f35e4c3d1a8d1be143 (diff)
data: moar WIP composite syntax!
-rw-r--r--src/data/things/composite.js86
-rw-r--r--src/data/things/thing.js69
-rw-r--r--src/data/things/track.js73
-rw-r--r--src/data/things/validators.js4
4 files changed, 129 insertions, 103 deletions
diff --git a/src/data/things/composite.js b/src/data/things/composite.js
index 98b04a7..2e85374 100644
--- a/src/data/things/composite.js
+++ b/src/data/things/composite.js
@@ -1,7 +1,7 @@
 import {inspect} from 'node:util';
 
 import {colors} from '#cli';
-import {oneOf} from '#validators';
+import {isArray, oneOf} from '#validators';
 import {TupleMap} from '#wiki-data';
 
 import {
@@ -1193,7 +1193,7 @@ export function compositeFrom(description) {
 
         case 'raiseAbove':
           debug(() => colors.bright(`end composition - raiseAbove`));
-          return continuationIfApplicable.raise(...continuationArgs);
+          return continuationIfApplicable.raiseOutput(...continuationArgs);
 
         case 'continuation':
           if (isBase) {
@@ -1360,9 +1360,7 @@ export const withResultOfAvailabilityCheck = templateCompositeFrom({
     mode: input(availabilityCheckModeInput),
   },
 
-  outputs: {
-    into: '#availability',
-  },
+  outputs: ['#availability'],
 
   steps: () => [
     {
@@ -1388,7 +1386,7 @@ export const withResultOfAvailabilityCheck = templateCompositeFrom({
             break;
         }
 
-        return continuation({into: availability});
+        return continuation({'#availability': availability});
       },
     },
   ],
@@ -1571,35 +1569,56 @@ export const withPropertyFromObject = templateCompositeFrom({
     property: input({type: 'string'}),
   },
 
-  outputs: {
-    dependencies: [
-      input.staticDependency('object'),
-      input.staticValue('property'),
-    ],
-
-    compute: ({
-      [input.staticDependency('object')]: object,
-      [input.staticValue('property')]: property,
-    }) => {
-      return (
-        (object && property
-          ? (object.startsWith('#')
-              ? `${object}.${property}`
-              : `#${object}.${property}`)
-          : '#value'));
-    },
+  outputs: ({
+    [input.staticDependency('object')]: object,
+    [input.staticValue('property')]: property,
+  }) => {
+    return [
+      (object && property
+        ? (object.startsWith('#')
+            ? `${object}.${property}`
+            : `#${object}.${property}`)
+        : '#value'),
+    ];
   },
 
   steps: () => [
     {
-      dependencies: [input('object'), input('property')],
+      dependencies: [
+        input.staticDependency('object'),
+        input.staticValue('property'),
+      ],
+
+      compute: (continuation, {
+        [input.staticDependency('object')]: object,
+        [input.staticValue('property')]: property,
+      }) => continuation({
+        '#output':
+          (object && property
+            ? (object.startsWith('#')
+                ? `${object}.${property}`
+                : `#${object}.${property}`)
+            : '#value'),
+      }),
+    },
+
+    {
+      dependencies: [
+        '#output',
+        input('object'),
+        input('property'),
+      ],
+
       compute: (continuation, {
+        ['#output']: output,
         [input('object')]: object,
         [input('property')]: property,
-      }) =>
-        (object === null
-          ? continuation({into: null})
-          : continuation({into: object[property] ?? null})),
+      }) => continuation({
+        [output]:
+          (object === null
+            ? null
+            : object[property] ?? null),
+      }),
     },
   ],
 });
@@ -1780,14 +1799,11 @@ export const excludeFromList = templateCompositeFrom({
     items: input({validate: isArray, null: true}),
   },
 
-  outputs: {
-    dependencies: [input.staticDependency('list')],
-    compute: ({
-      [input.staticDependency('list')]: list,
-    }) => [list ?? '#list'],
-  },
+  outputs: ({
+    [input.staticDependency('list')]: list,
+  }) => [list ?? '#list'],
 
-  steps: [
+  steps: () => [
     {
       dependencies: [
         input.staticDependency('list'),
diff --git a/src/data/things/thing.js b/src/data/things/thing.js
index a5f0b78..cff2f49 100644
--- a/src/data/things/thing.js
+++ b/src/data/things/thing.js
@@ -476,15 +476,15 @@ export const withResolvedContribs = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    into: '#resolvedContribs',
-  },
+  outputs: ['#resolvedContribs'],
 
   steps: () => [
     raiseOutputWithoutDependency({
       dependency: input('from'),
       mode: input.value('empty'),
-      output: input.value({into: []}),
+      output: input.value({
+        ['#resolvedContribs']: [],
+      }),
     }),
 
     withPropertiesFromList({
@@ -496,9 +496,10 @@ export const withResolvedContribs = templateCompositeFrom({
     withResolvedReferenceList({
       list: '#contribs.who',
       data: 'artistData',
-      into: '#contribs.who',
       find: input('find'),
       notFoundMode: input('notFoundMode'),
+    }).outputs({
+      ['#resolvedReferenceList']: '#contribs.who',
     }),
 
     {
@@ -510,7 +511,7 @@ export const withResolvedContribs = templateCompositeFrom({
       }) {
         filterMultipleArrays(who, what, (who, _what) => who);
         return continuation({
-          '#composition.into': stitchArrays({who, what}),
+          ['#resolvedContribs']: stitchArrays({who, what}),
         });
       },
     },
@@ -577,14 +578,14 @@ export const withResolvedReference = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    into: '#resolvedReference',
-  },
+  outputs: ['#resolvedReference'],
 
   steps: () => [
     raiseOutputWithoutDependency({
       dependency: input('ref'),
-      output: input.value({into: null}),
+      output: input.value({
+        ['#resolvedReference']: null,
+      }),
     }),
 
     exitWithoutDependency({
@@ -611,7 +612,9 @@ export const withResolvedReference = templateCompositeFrom({
           return continuation.exit(null);
         }
 
-        return continuation.raise({match});
+        return continuation.raiseOutput({
+          ['#resolvedReference']: match,
+        });
       },
     },
   ],
@@ -640,9 +643,7 @@ export const withResolvedReferenceList = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    into: '#resolvedReferenceList',
-  },
+  outputs: ['#resolvedReferenceList'],
 
   steps: () => [
     exitWithoutDependency({
@@ -653,7 +654,9 @@ export const withResolvedReferenceList = templateCompositeFrom({
     raiseOutputWithoutDependency({
       dependency: input('list'),
       mode: input.value('empty'),
-      output: input.value({into: []}),
+      output: input.value({
+        ['#resolvedReferenceList']: [],
+      }),
     }),
 
     {
@@ -672,7 +675,9 @@ export const withResolvedReferenceList = templateCompositeFrom({
       dependencies: ['#matches'],
       compute: ({'#matches': matches}, continuation) =>
         (matches.every(match => match)
-          ? continuation.raise({'#continuation.into': matches})
+          ? continuation.raiseOutput({
+              ['#resolvedReferenceList']: matches,
+            })
           : continuation()),
     },
 
@@ -687,12 +692,16 @@ export const withResolvedReferenceList = templateCompositeFrom({
             return continuation.exit([]);
 
           case 'filter':
-            matches = matches.filter(match => match);
-            return continuation.raise({'#continuation.into': matches});
+            return continuation.raiseOutput({
+              ['#resolvedReferenceList']:
+                matches.filter(match => match),
+            });
 
           case 'null':
-            matches = matches.map(match => match ?? null);
-            return continuation.raise({'#continuation.into': matches});
+            return continuation.raiseOutput({
+              ['#resolvedReferenceList']:
+                matches.map(match => match ?? null),
+            });
 
           default:
             throw new TypeError(`Expected notFoundMode to be exit, filter, or null`);
@@ -714,30 +723,24 @@ export const withReverseReferenceList = templateCompositeFrom({
     list: input({type: 'string'}),
   },
 
-  outputs: {
-    into: '#reverseReferenceList',
-  },
+  outputs: ['#reverseReferenceList'],
 
   steps: () => [
     exitWithoutDependency({
-      dependency: '#composition.data',
+      dependency: input('data'),
       value: [],
     }),
 
     {
-      dependencies: [
-        'this',
-        '#composition.data',
-        '#composition.refListProperty',
-      ],
+      dependencies: [input.myself(), input('data'), input('list')],
 
       compute: ({
-        this: thisThing,
-        '#composition.data': data,
-        '#composition.refListProperty': refListProperty,
+        [input.myself()]: thisThing,
+        [input('data')]: data,
+        [input('list')]: refListProperty,
       }, continuation) =>
         continuation({
-          '#composition.into':
+          ['#reverseReferenceList']:
             data.filter(thing => thing[refListProperty].includes(thisThing)),
         }),
     },
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 135e6d1..37b3628 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -103,7 +103,7 @@ export class Track extends Thing {
 
       {
         dependencies: ['name', '#originalRelease.name'],
-        compute({name, '#originalRelease.name': originalName}) =>
+        compute: ({name, '#originalRelease.name': originalName}) =>
           name === originalName,
       },
     ],
@@ -389,34 +389,40 @@ export const withAlbum = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    into: '#album',
-  },
+  outputs: ['#album'],
 
   steps: () => [
     raiseOutputWithoutDependency({
       dependency: 'albumData',
       mode: input.value('empty'),
-      output: input.value({into: null}),
+      output: input.value({
+        ['#album']: null,
+      }),
     }),
 
     {
-      dependencies: ['this', 'albumData'],
-      compute: (continuation, {this: track, albumData}) =>
+      dependencies: [input.myself(), 'albumData'],
+      compute: (continuation, {
+        [input.myself()]: track,
+        ['albumData']: albumData,
+      }) =>
         continuation({
-          '#album': albumData.find(album => album.tracks.includes(track)),
+          ['#album']:
+            albumData.find(album => album.tracks.includes(track)),
         }),
     },
 
     raiseOutputWithoutDependency({
       dependency: '#album',
-      output: input.value({into: null}),
+      output: input.value({
+        ['#album']: null,
+      }),
     }),
 
     {
       dependencies: ['#album'],
       compute: (continuation, {'#album': album}) =>
-        continuation({into: album}),
+        continuation.raiseOutput({'#album': album}),
     },
   ],
 });
@@ -437,12 +443,9 @@ export const withPropertyFromAlbum = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    dependencies: [input.staticValue('property')],
-    compute: ({
-      [input.staticValue('property')]: property,
-    }) => ['#album.' + property],
-  },
+  outputs: ({
+    [input.staticValue('property')]: property,
+  }) => ['#album.' + property],
 
   steps: () => [
     withAlbum({
@@ -479,9 +482,7 @@ export const withContainingTrackSection = templateCompositeFrom({
     }),
   },
 
-  outputs: {
-    into: '#trackSection',
-  },
+  outputs: ['#trackSection'],
 
   steps: () => [
     withPropertyFromAlbum({
@@ -502,18 +503,24 @@ export const withContainingTrackSection = templateCompositeFrom({
         ['#album.trackSections']: trackSections,
       }) {
         if (!trackSections) {
-          return continuation({into: null});
+          return continuation.raiseOutput({
+            ['#trackSection']: null,
+          });
         }
 
         const trackSection =
           trackSections.find(({tracks}) => tracks.includes(track));
 
         if (trackSection) {
-          return continuation({into: trackSection});
+          return continuation.raiseOutput({
+            ['#trackSection']: trackSection,
+          });
         } else if (notFoundMode === 'exit') {
           return continuation.exit(null);
         } else {
-          return continuation({into: null});
+          return continuation.raiseOutput({
+            ['#trackSection']: null,
+          });
         }
       },
     },
@@ -536,9 +543,7 @@ export const withOriginalRelease = templateCompositeFrom({
     data: input({defaultDependency: 'trackData'}),
   },
 
-  outputs: {
-    into: '#originalRelease',
-  },
+  outputs: ['#originalRelease'],
 
   steps: () => [
     withResolvedReference({
@@ -547,7 +552,7 @@ export const withOriginalRelease = templateCompositeFrom({
       find: input.value(find.track),
       notFoundMode: input.value('exit'),
     }).outputs({
-      '#resolvedReference': '#originalRelease',
+      ['#resolvedReference']: '#originalRelease',
     }),
 
     {
@@ -563,7 +568,7 @@ export const withOriginalRelease = templateCompositeFrom({
         ['#originalRelease']: originalRelease,
       }) =>
         continuation({
-          into:
+          ['#originalRelease']:
             (originalRelease ??
               (selfIfOriginal
                 ? track
@@ -578,9 +583,7 @@ export const withOriginalRelease = templateCompositeFrom({
 export const withHasUniqueCoverArt = templateCompositeFrom({
   annotation: 'withHasUniqueCoverArt',
 
-  outputs: {
-    into: '#hasUniqueCoverArt',
-  },
+  outputs: ['#hasUniqueCoverArt'],
 
   steps: () => [
     {
@@ -602,7 +605,10 @@ export const withHasUniqueCoverArt = templateCompositeFrom({
       }) =>
         (empty(contribsFromTrack)
           ? continuation()
-          : continuation.raiseOutput({into: true})),
+          : continuation.raiseOutput({
+              ['#hasUniqueCoverArt']:
+                true,
+            })),
     },
 
     withPropertyFromAlbum({property: 'trackCoverArtistContribs'}),
@@ -612,8 +618,9 @@ export const withHasUniqueCoverArt = templateCompositeFrom({
       compute: (continuation, {
         ['#album.trackCoverArtistContribs']: contribsFromAlbum,
       }) =>
-        continuation({
-          into: !empty(contribsFromAlbum),
+        continuation.raiseOutput({
+          ['#hasUniqueCoverArt']:
+            !empty(contribsFromAlbum),
         }),
     },
   ],
diff --git a/src/data/things/validators.js b/src/data/things/validators.js
index f0d1d9f..cd4c2b4 100644
--- a/src/data/things/validators.js
+++ b/src/data/things/validators.js
@@ -9,11 +9,11 @@ function inspect(value) {
 
 // Basic types (primitives)
 
-function a(noun) {
+export function a(noun) {
   return /[aeiou]/.test(noun[0]) ? `an ${noun}` : `a ${noun}`;
 }
 
-function isType(value, type) {
+export function isType(value, type) {
   if (typeof value !== type)
     throw new TypeError(`Expected ${a(type)}, got ${typeof value}`);