From 8db50e29b5a1cfddfddf499129b697ecabfadcb0 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 20 Sep 2023 13:01:25 -0300 Subject: data: moar WIP composite syntax! --- src/data/things/composite.js | 86 +++++++++++++++++++++++++------------------ src/data/things/thing.js | 69 +++++++++++++++++----------------- src/data/things/track.js | 73 +++++++++++++++++++----------------- src/data/things/validators.js | 4 +- 4 files changed, 129 insertions(+), 103 deletions(-) (limited to 'src/data') diff --git a/src/data/things/composite.js b/src/data/things/composite.js index 98b04a7e..2e85374f 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 a5f0b78d..cff2f498 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 135e6d1f..37b36287 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 f0d1d9fd..cd4c2b46 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}`); -- cgit 1.3.0-6-gf8a5