diff options
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/composite/control-flow/flipFilter.js | 36 | ||||
-rw-r--r-- | src/data/composite/control-flow/index.js | 1 | ||||
-rw-r--r-- | src/data/composite/control-flow/withAvailabilityFilter.js | 1 | ||||
-rw-r--r-- | src/data/composite/data/withFilteredList.js | 16 | ||||
-rw-r--r-- | src/data/composite/data/withNearbyItemFromList.js | 52 | ||||
-rw-r--r-- | src/data/composite/things/artwork/index.js | 5 | ||||
-rw-r--r-- | src/data/composite/things/artwork/withAttachedArtwork.js | 43 | ||||
-rw-r--r-- | src/data/composite/things/artwork/withContribsFromAttachedArtwork.js (renamed from src/data/composite/things/artwork/withContribsFromMainArtwork.js) | 15 | ||||
-rw-r--r-- | src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js | 65 | ||||
-rw-r--r-- | src/data/composite/things/artwork/withPropertyFromMainArtwork.js | 100 | ||||
-rw-r--r-- | src/data/things/artwork.js | 61 |
11 files changed, 227 insertions, 168 deletions
diff --git a/src/data/composite/control-flow/flipFilter.js b/src/data/composite/control-flow/flipFilter.js new file mode 100644 index 00000000..995bacad --- /dev/null +++ b/src/data/composite/control-flow/flipFilter.js @@ -0,0 +1,36 @@ +// Flips a filter, so that each true item becomes false, and vice versa. +// Overwrites the provided dependency. +// +// See also: +// - withAvailabilityFilter + +import {input, templateCompositeFrom} from '#composite'; + +export default templateCompositeFrom({ + annotation: `flipFilter`, + + inputs: { + filter: input({type: 'array'}), + }, + + outputs: ({ + [input.staticDependency('filter')]: filterDependency, + }) => [filterDependency ?? '#flippedFilter'], + + steps: () => [ + { + dependencies: [ + input('filter'), + input.staticDependency('filter'), + ], + + compute: (continuation, { + [input('filter')]: filter, + [input.staticDependency('filter')]: filterDependency, + }) => continuation({ + [filterDependency ?? '#flippedFilter']: + filter.map(item => !item), + }), + }, + ], +}); diff --git a/src/data/composite/control-flow/index.js b/src/data/composite/control-flow/index.js index 7e137a14..778dc66b 100644 --- a/src/data/composite/control-flow/index.js +++ b/src/data/composite/control-flow/index.js @@ -10,6 +10,7 @@ export {default as exposeDependency} from './exposeDependency.js'; export {default as exposeDependencyOrContinue} from './exposeDependencyOrContinue.js'; export {default as exposeUpdateValueOrContinue} from './exposeUpdateValueOrContinue.js'; export {default as exposeWhetherDependencyAvailable} from './exposeWhetherDependencyAvailable.js'; +export {default as flipFilter} from './flipFilter.js'; export {default as raiseOutputWithoutDependency} from './raiseOutputWithoutDependency.js'; export {default as raiseOutputWithoutUpdateValue} from './raiseOutputWithoutUpdateValue.js'; export {default as withAvailabilityFilter} from './withAvailabilityFilter.js'; diff --git a/src/data/composite/control-flow/withAvailabilityFilter.js b/src/data/composite/control-flow/withAvailabilityFilter.js index cfea998e..fd93af71 100644 --- a/src/data/composite/control-flow/withAvailabilityFilter.js +++ b/src/data/composite/control-flow/withAvailabilityFilter.js @@ -4,6 +4,7 @@ // Accepts the same mode options as withResultOfAvailabilityCheck. // // See also: +// - flipFilter // - withFilteredList // - withResultOfAvailabilityCheck // diff --git a/src/data/composite/data/withFilteredList.js b/src/data/composite/data/withFilteredList.js index 44c1661d..15ee3373 100644 --- a/src/data/composite/data/withFilteredList.js +++ b/src/data/composite/data/withFilteredList.js @@ -2,9 +2,6 @@ // corresponding items in a list. Items which correspond to a truthy value // are kept, and the rest are excluded from the output list. // -// If the flip option is set, only items corresponding with a *falsy* value in -// the filter are kept. -// // TODO: There should be two outputs - one for the items included according to // the filter, and one for the items excluded. // @@ -22,28 +19,19 @@ export default templateCompositeFrom({ inputs: { list: input({type: 'array'}), filter: input({type: 'array'}), - - flip: input({ - type: 'boolean', - defaultValue: false, - }), }, outputs: ['#filteredList'], steps: () => [ { - dependencies: [input('list'), input('filter'), input('flip')], + dependencies: [input('list'), input('filter')], compute: (continuation, { [input('list')]: list, [input('filter')]: filter, - [input('flip')]: flip, }) => continuation({ '#filteredList': - list.filter((_item, index) => - (flip - ? !filter[index] - : filter[index])), + list.filter((_item, index) => filter[index]), }), }, ], diff --git a/src/data/composite/data/withNearbyItemFromList.js b/src/data/composite/data/withNearbyItemFromList.js index 83a8cc21..5e165219 100644 --- a/src/data/composite/data/withNearbyItemFromList.js +++ b/src/data/composite/data/withNearbyItemFromList.js @@ -9,6 +9,10 @@ // - If the 'valuePastEdge' input is provided, that value will be output // instead of null. // +// - If the 'filter' input is provided, corresponding items will be skipped, +// and only (repeating `offset`) the next included in the filter will be +// returned. +// // Both the list and item must be provided. // // See also: @@ -16,7 +20,6 @@ // import {input, templateCompositeFrom} from '#composite'; -import {atOffset} from '#sugar'; import {raiseOutputWithoutDependency} from '#composite/control-flow'; @@ -28,9 +31,12 @@ export default templateCompositeFrom({ inputs: { list: input({acceptsNull: false, type: 'array'}), item: input({acceptsNull: false}), - offset: input({type: 'number'}), + wrap: input({type: 'boolean', defaultValue: false}), + valuePastEdge: input({defaultValue: null}), + + filter: input({defaultValue: null, type: 'array'}), }, outputs: ['#nearbyItem'], @@ -45,29 +51,55 @@ export default templateCompositeFrom({ dependency: '#index', mode: input.value('index'), - output: input.value({ - ['#nearbyItem']: - null, - }), + output: input.value({'#nearbyItem': null}), }), { dependencies: [ input('list'), input('offset'), + input('wrap'), + input('valuePastEdge'), + + input('filter'), + '#index', ], compute: (continuation, { [input('list')]: list, [input('offset')]: offset, + [input('wrap')]: wrap, + [input('valuePastEdge')]: valuePastEdge, + + [input('filter')]: filter, + ['#index']: index, - }) => continuation({ - ['#nearbyItem']: - atOffset(list, index, offset, {wrap}), - }), + }) => { + const startIndex = index; + + do { + index += offset; + + if (wrap) { + index = index % list.length; + } else if (index < 0) { + return continuation({'#nearbyItem': valuePastEdge}); + } else if (index >= list.length) { + return continuation({'#nearbyItem': valuePastEdge}); + } + + if (filter && !filter[index]) { + continue; + } + + return continuation({'#nearbyItem': list[index]}); + } while (index !== startIndex); + + return continuation({'#nearbyItem': null}); + }, }, ], }); diff --git a/src/data/composite/things/artwork/index.js b/src/data/composite/things/artwork/index.js index 5a592777..3693c10f 100644 --- a/src/data/composite/things/artwork/index.js +++ b/src/data/composite/things/artwork/index.js @@ -1,4 +1,5 @@ +export {default as withAttachedArtwork} from './withAttachedArtwork.js'; export {default as withContainingArtworkList} from './withContainingArtworkList.js'; -export {default as withContribsFromMainArtwork} from './withContribsFromMainArtwork.js'; +export {default as withContribsFromAttachedArtwork} from './withContribsFromAttachedArtwork.js'; export {default as withDate} from './withDate.js'; -export {default as withPropertyFromMainArtwork} from './withPropertyFromMainArtwork.js'; +export {default as withPropertyFromAttachedArtwork} from './withPropertyFromAttachedArtwork.js'; diff --git a/src/data/composite/things/artwork/withAttachedArtwork.js b/src/data/composite/things/artwork/withAttachedArtwork.js new file mode 100644 index 00000000..d7c0d87b --- /dev/null +++ b/src/data/composite/things/artwork/withAttachedArtwork.js @@ -0,0 +1,43 @@ +import {input, templateCompositeFrom} from '#composite'; + +import {flipFilter, raiseOutputWithoutDependency} + from '#composite/control-flow'; +import {withNearbyItemFromList, withPropertyFromList} from '#composite/data'; + +import withContainingArtworkList from './withContainingArtworkList.js'; + +export default templateCompositeFrom({ + annotaion: `withContribsFromMainArtwork`, + + outputs: ['#attachedArtwork'], + + steps: () => [ + raiseOutputWithoutDependency({ + dependency: 'attachAbove', + mode: input.value('falsy'), + output: input.value({'#attachedArtwork': null}), + }), + + withContainingArtworkList(), + + withPropertyFromList({ + list: '#containingArtworkList', + property: input.value('attachAbove'), + }), + + flipFilter({ + filter: '#containingArtworkList.attachAbove', + }).outputs({ + '#containingArtworkList.attachAbove': '#filterNotAttached', + }), + + withNearbyItemFromList({ + list: '#containingArtworkList', + item: input.myself(), + offset: input.value(-1), + filter: '#filterNotAttached', + }).outputs({ + '#nearbyItem': '#attachedArtwork', + }), + ], +}); diff --git a/src/data/composite/things/artwork/withContribsFromMainArtwork.js b/src/data/composite/things/artwork/withContribsFromAttachedArtwork.js index 25616ad6..36abb3fe 100644 --- a/src/data/composite/things/artwork/withContribsFromMainArtwork.js +++ b/src/data/composite/things/artwork/withContribsFromAttachedArtwork.js @@ -4,26 +4,25 @@ import {raiseOutputWithoutDependency} from '#composite/control-flow'; import {withPropertyFromObject} from '#composite/data'; import {withRecontextualizedContributionList} from '#composite/wiki-data'; -import withPropertyFromMainArtwork from './withPropertyFromMainArtwork.js'; +import withPropertyFromAttachedArtwork from './withPropertyFromAttachedArtwork.js'; export default templateCompositeFrom({ - annotaion: `withContribsFromMainArtwork`, + annotaion: `withContribsFromAttachedArtwork`, - outputs: ['#mainArtwork.artistContribs'], + outputs: ['#attachedArtwork.artistContribs'], steps: () => [ - withPropertyFromMainArtwork({ + withPropertyFromAttachedArtwork({ property: input.value('artistContribs'), - onlyIfAttached: input.value(true), }), raiseOutputWithoutDependency({ - dependency: '#mainArtwork.artistContribs', - output: input.value({'#mainArtwork.artistContribs': null}), + dependency: '#attachedArtwork.artistContribs', + output: input.value({'#attachedArtwork.artistContribs': null}), }), withRecontextualizedContributionList({ - list: '#mainArtwork.artistContribs', + list: '#attachedArtwork.artistContribs', }), ], }); diff --git a/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js b/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js new file mode 100644 index 00000000..a2f954b9 --- /dev/null +++ b/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js @@ -0,0 +1,65 @@ +import {input, templateCompositeFrom} from '#composite'; + +import {withResultOfAvailabilityCheck} from '#composite/control-flow'; +import {withPropertyFromObject} from '#composite/data'; + +import withAttachedArtwork from './withAttachedArtwork.js'; + +function getOutputName({ + [input.staticValue('property')]: property, +}) { + if (property) { + return `#attachedArtwork.${property}`; + } else { + return '#value'; + } +} + +export default templateCompositeFrom({ + annotation: `withPropertyFromAttachedArtwork`, + + inputs: { + property: input({type: 'string'}), + }, + + outputs: inputs => [getOutputName(inputs)], + + steps: () => [ + { + dependencies: [input.staticValue('property')], + compute: (continuation, inputs) => + continuation({'#output': getOutputName(inputs)}), + }, + + withAttachedArtwork(), + + withResultOfAvailabilityCheck({ + from: '#attachedArtwork', + }), + + { + dependencies: ['#availability', '#output'], + compute: (continuation, { + ['#availability']: availability, + ['#output']: output, + }) => + (availability + ? continuation() + : continuation.raiseOutput({[output]: null})), + }, + + withPropertyFromObject({ + object: '#attachedArtwork', + property: input('property'), + }), + + { + dependencies: ['#value', '#output'], + compute: (continuation, { + ['#value']: value, + ['#output']: output, + }) => + continuation.raiseOutput({[output]: value}), + }, + ], +}); diff --git a/src/data/composite/things/artwork/withPropertyFromMainArtwork.js b/src/data/composite/things/artwork/withPropertyFromMainArtwork.js deleted file mode 100644 index a0233119..00000000 --- a/src/data/composite/things/artwork/withPropertyFromMainArtwork.js +++ /dev/null @@ -1,100 +0,0 @@ -import {input, templateCompositeFrom} from '#composite'; - -import {withResultOfAvailabilityCheck} from '#composite/control-flow'; -import {withPropertyFromObject} from '#composite/data'; - -import withContainingArtworkList from './withContainingArtworkList.js'; - -function getOutputName({ - [input.staticValue('property')]: property, -}) { - if (property) { - return `#mainArtwork.${property}`; - } else { - return '#value'; - } -} - -export default templateCompositeFrom({ - annotation: `withPropertyFromMainArtwork`, - - inputs: { - property: input({type: 'string'}), - onlyIfAttached: input({type: 'boolean', defaultValue: false}), - }, - - outputs: inputs => [getOutputName(inputs)], - - steps: () => [ - { - dependencies: [input.staticValue('property')], - compute: (continuation, inputs) => - continuation({'#output': getOutputName(inputs)}), - }, - - { - dependencies: [input('onlyIfAttached'), 'attachAbove', '#output'], - compute: (continuation, { - [input('onlyIfAttached')]: onlyIfAttached, - ['attachAbove']: attachAbove, - ['#output']: output, - }) => - (onlyIfAttached && attachAbove - ? continuation() - : onlyIfAttached - ? continuation.raiseOutput({[output]: null}) - : continuation()), - }, - - withContainingArtworkList(), - - withResultOfAvailabilityCheck({ - from: '#containingArtworkList', - }), - - { - dependencies: ['#availability', '#output'], - compute: (continuation, { - ['#availability']: availability, - ['#output']: output, - }) => - (availability - ? continuation() - : continuation.raiseOutput({[output]: null})), - }, - - { - dependencies: ['#containingArtworkList'], - compute: (continuation, { - ['#containingArtworkList']: list, - }) => - continuation({'#mainArtwork': list[0]}), - }, - - { - dependencies: [input.myself(), '#mainArtwork', '#output'], - compute: (continuation, { - [input.myself()]: myself, - ['#mainArtwork']: mainArtwork, - ['#output']: output, - }) => - (myself === mainArtwork - ? continuation.raiseOutput({[output]: null}) - : continuation()), - }, - - withPropertyFromObject({ - object: '#mainArtwork', - property: input('property'), - }), - - { - dependencies: ['#value', '#output'], - compute: (continuation, { - ['#value']: value, - ['#output']: output, - }) => - continuation.raiseOutput({[output]: value}), - }, - ], -}); diff --git a/src/data/things/artwork.js b/src/data/things/artwork.js index 8c88dea7..3cdb07d0 100644 --- a/src/data/things/artwork.js +++ b/src/data/things/artwork.js @@ -54,9 +54,10 @@ import { } from '#composite/wiki-properties'; import { + withAttachedArtwork, withContainingArtworkList, - withContribsFromMainArtwork, - withPropertyFromMainArtwork, + withContribsFromAttachedArtwork, + withPropertyFromAttachedArtwork, withDate, } from '#composite/things/artwork'; @@ -178,10 +179,10 @@ export class Artwork extends Thing { mode: input.value('empty'), }), - withContribsFromMainArtwork(), + withContribsFromAttachedArtwork(), exposeDependencyOrContinue({ - dependency: '#mainArtwork.artistContribs', + dependency: '#attachedArtwork.artistContribs', }), exitWithoutDependency({ @@ -222,13 +223,12 @@ export class Artwork extends Thing { mode: input.value('empty'), }), - withPropertyFromMainArtwork({ + withPropertyFromAttachedArtwork({ property: input.value('artTags'), - onlyIfAttached: input.value(true), }), exposeDependencyOrContinue({ - dependency: '#mainArtwork.artTags', + dependency: '#attachedArtwork.artTags', }), exitWithoutDependency({ @@ -360,36 +360,17 @@ export class Artwork extends Thing { }, ], - siblingArtworks: [ - withContainingArtworkList(), - - exitWithoutDependency({ - dependency: '#containingArtworkList', - value: input.value(null), - }), + attachedArtwork: [ + withAttachedArtwork(), - withIndexInList({ - list: '#containingArtworkList', - item: input.myself(), - }), - - exitWithoutDependency({ - dependency: '#index', - mode: input.value('index'), - value: input.value(null), + exposeDependency({ + dependency: '#attachedArtwork', }), - - { - dependencies: ['#containingArtworkList', '#index'], - compute: ({ - ['#containingArtworkList']: list, - ['#index']: index, - }) => [ - ...list.slice(0, index), - ...list.slice(index + 1), - ], - }, ], + + attachingArtworks: reverseReferenceList({ + reverse: soupyReverse.input('artworksWhichAttach'), + }), }); static [Thing.yamlDocumentSpec] = { @@ -448,6 +429,18 @@ export class Artwork extends Thing { date: ({artwork}) => artwork.date, }, + artworksWhichAttach: { + bindTo: 'artworkData', + + referencing: referencingArtwork => + (referencingArtwork.attachAbove + ? [referencingArtwork] + : []), + + referenced: referencingArtwork => + [referencingArtwork.attachedArtwork], + }, + artworksWhichFeature: { bindTo: 'artworkData', |