diff options
-rw-r--r-- | src/data/composite/things/track/withAlbum.js | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/src/data/composite/things/track/withAlbum.js b/src/data/composite/things/track/withAlbum.js index 0e85cee9..9c974cd1 100644 --- a/src/data/composite/things/track/withAlbum.js +++ b/src/data/composite/things/track/withAlbum.js @@ -4,9 +4,12 @@ // exit instead. import {input, templateCompositeFrom} from '#composite'; -import {empty} from '#sugar'; import {is} from '#validators'; +import {exitWithoutDependency, withResultOfAvailabilityCheck} + from '#composite/control-flow'; +import {withPropertyFromList} from '#composite/data'; + export default templateCompositeFrom({ annotation: `withAlbum`, @@ -20,43 +23,84 @@ export default templateCompositeFrom({ outputs: ['#album'], steps: () => [ + // null albumData is always an early exit. + + exitWithoutDependency({ + dependency: 'albumData', + mode: input.value('null'), + }), + + // empty albumData conditionally exits early or outputs null. + + withResultOfAvailabilityCheck({ + from: 'albumData', + mode: input.value('empty'), + }).outputs({ + '#availability': '#albumDataAvailability', + }), + { - dependencies: [input('notFoundMode'), 'albumData'], - compute: (continuation, { + dependencies: [input('notFoundMode'), '#albumDataAvailability'], + compute(continuation, { [input('notFoundMode')]: notFoundMode, - ['albumData']: albumData, - }) => - (albumData === null - ? continuation.exit(null) - : empty(albumData) - ? (notFoundMode === 'exit' - ? continuation.exit(null) - : continuation.raiseOutput({'#album': null})) - : continuation()), + ['#albumDataAvailability']: albumDataIsAvailable, + }) { + if (albumDataIsAvailable) return continuation(); + switch (notFoundMode) { + case 'exit': return continuation.exit(null); + case 'null': return continuation.raiseOutput({'#album': null}); + } + }, }, + withPropertyFromList({ + list: 'albumData', + property: input.value('tracks'), + }), + { - dependencies: [input.myself(), 'albumData'], + dependencies: [input.myself(), '#albumData.tracks'], compute: (continuation, { [input.myself()]: track, - ['albumData']: albumData, - }) => - continuation({ - ['#album']: - albumData.find(album => album.tracks.includes(track)) - ?? null, - }), + ['#albumData.tracks']: trackLists, + }) => continuation({ + ['#albumIndex']: + trackLists.findIndex(tracks => tracks.includes(track)), + }), }, + // album not found conditionally exits or outputs null. + + withResultOfAvailabilityCheck({ + from: '#albumIndex', + mode: input.value('index'), + }).outputs({ + '#availability': '#albumAvailability', + }), + { - dependencies: [input('notFoundMode'), '#album'], - compute: (continuation, { + dependencies: [input('notFoundMode'), '#albumAvailability'], + compute(continuation, { [input('notFoundMode')]: notFoundMode, - ['#album']: album, - }) => - ((album === null && notFoundMode === 'exit') - ? continuation.exit(null) - : continuation.raiseOutput({'#album': album})), + ['#albumAvailability']: albumIsAvailable, + }) { + if (albumIsAvailable) return continuation(); + switch (notFoundMode) { + case 'exit': return continuation.exit(null); + case 'null': return continuation.raiseOutput({'#album': null}); + } + }, + }, + + { + dependencies: ['albumData', '#albumIndex'], + compute: (continuation, { + ['albumData']: albumData, + ['#albumIndex']: albumIndex, + }) => continuation.raiseOutput({ + ['#album']: + albumData[albumIndex], + }), }, ], }); |