From 301ed2a12f4716a85359b6cb50462e415539553f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 17 Jan 2024 13:58:47 -0400 Subject: data: stub reverseContributionList --- src/data/composite/wiki-data/index.js | 1 + .../wiki-data/withReverseContributionList.js | 45 +++++ src/data/composite/wiki-properties/index.js | 1 + .../wiki-properties/reverseContributionList.js | 24 +++ src/data/things/artist.js | 187 ++++++++++++++------- src/page/artist.js | 2 + 6 files changed, 202 insertions(+), 58 deletions(-) create mode 100644 src/data/composite/wiki-data/withReverseContributionList.js create mode 100644 src/data/composite/wiki-properties/reverseContributionList.js diff --git a/src/data/composite/wiki-data/index.js b/src/data/composite/wiki-data/index.js index a2ff09d..d64930e 100644 --- a/src/data/composite/wiki-data/index.js +++ b/src/data/composite/wiki-data/index.js @@ -11,5 +11,6 @@ export {default as withParsedCommentaryEntries} from './withParsedCommentaryEntr export {default as withResolvedContribs} from './withResolvedContribs.js'; export {default as withResolvedReference} from './withResolvedReference.js'; export {default as withResolvedReferenceList} from './withResolvedReferenceList.js'; +export {default as withReverseContributionList} from './withReverseContributionList.js'; export {default as withReverseReferenceList} from './withReverseReferenceList.js'; export {default as withThingsSortedAlphabetically} from './withThingsSortedAlphabetically.js'; diff --git a/src/data/composite/wiki-data/withReverseContributionList.js b/src/data/composite/wiki-data/withReverseContributionList.js new file mode 100644 index 0000000..71e3c1a --- /dev/null +++ b/src/data/composite/wiki-data/withReverseContributionList.js @@ -0,0 +1,45 @@ +// Analogous implementation for withReverseReferenceList, but contributions. +// +// This implementation uses a global cache (via WeakMap) to attempt to speed +// up subsequent similar accesses. Reverse contribution lists are the most +// costly in live-dev-server, but we intend to expand the impelemntation here +// to reverse reference lists in general later on. + +import {input, templateCompositeFrom} from '#composite'; + +import {exitWithoutDependency} from '#composite/control-flow'; + +import inputWikiData from './inputWikiData.js'; + +export default templateCompositeFrom({ + annotation: `withReverseContributionList`, + + inputs: { + data: inputWikiData({allowMixedTypes: false}), + list: input({type: 'string'}), + }, + + outputs: ['#reverseContributionList'], + + steps: () => [ + exitWithoutDependency({ + dependency: input('data'), + value: input.value([]), + mode: input.value('empty'), + }), + + { + dependencies: [input.myself(), input('data'), input('list')], + + compute: (continuation, { + [input.myself()]: myself, + [input('data')]: data, + [input('list')]: list, + }) => + continuation({ + ['#reverseContributionList']: + data.filter(thing => thing[list].some(({who}) => who === myself)), + }), + }, + ], +}); diff --git a/src/data/composite/wiki-properties/index.js b/src/data/composite/wiki-properties/index.js index 46b8564..89cb683 100644 --- a/src/data/composite/wiki-properties/index.js +++ b/src/data/composite/wiki-properties/index.js @@ -19,6 +19,7 @@ export {default as fileExtension} from './fileExtension.js'; export {default as flag} from './flag.js'; export {default as name} from './name.js'; export {default as referenceList} from './referenceList.js'; +export {default as reverseContributionList} from './reverseContributionList.js'; export {default as reverseReferenceList} from './reverseReferenceList.js'; export {default as simpleDate} from './simpleDate.js'; export {default as simpleString} from './simpleString.js'; diff --git a/src/data/composite/wiki-properties/reverseContributionList.js b/src/data/composite/wiki-properties/reverseContributionList.js new file mode 100644 index 0000000..7f3f9c8 --- /dev/null +++ b/src/data/composite/wiki-properties/reverseContributionList.js @@ -0,0 +1,24 @@ +import {input, templateCompositeFrom} from '#composite'; + +import {exposeDependency} from '#composite/control-flow'; +import {inputWikiData, withReverseContributionList} from '#composite/wiki-data'; + +export default templateCompositeFrom({ + annotation: `reverseContributionList`, + + compose: false, + + inputs: { + data: inputWikiData({allowMixedTypes: false}), + list: input({type: 'string'}), + }, + + steps: () => [ + withReverseContributionList({ + data: input('data'), + list: input('list'), + }), + + exposeDependency({dependency: '#reverseContributionList'}), + ], +}); diff --git a/src/data/things/artist.js b/src/data/things/artist.js index 391a980..66a7346 100644 --- a/src/data/things/artist.js +++ b/src/data/things/artist.js @@ -8,11 +8,16 @@ import { fileExtension, flag, name, + reverseContributionList, singleReference, urls, wikiData, } from '#composite/wiki-properties'; +import { + withReverseContributionList, +} from '#composite/wiki-data'; + import Thing from './thing.js'; export class Artist extends Thing { @@ -64,28 +69,62 @@ export class Artist extends Thing { // Expose only - tracksAsArtist: - Artist.filterByContrib('trackData', 'artistContribs'), - tracksAsContributor: - Artist.filterByContrib('trackData', 'contributorContribs'), - tracksAsCoverArtist: - Artist.filterByContrib('trackData', 'coverArtistContribs'), + tracksAsArtist: reverseContributionList({ + data: 'trackData', + list: input.value('artistContribs'), + }), - tracksAsAny: { - flags: {expose: true}, + tracksAsContributor: reverseContributionList({ + data: 'trackData', + list: input.value('contributorContribs'), + }), - expose: { - dependencies: ['this', 'trackData'], + tracksAsCoverArtist: reverseContributionList({ + data: 'trackData', + list: input.value('coverArtistContribs'), + }), - compute: ({this: artist, trackData}) => - trackData?.filter((track) => - [ - ...track.artistContribs ?? [], - ...track.contributorContribs ?? [], - ...track.coverArtistContribs ?? [], - ].some(({who}) => who === artist)) ?? [], + tracksAsAny: [ + withReverseContributionList({ + data: 'trackData', + list: input.value('artistContribs'), + }).outputs({ + '#reverseContributionList': '#tracksAsArtist', + }), + + withReverseContributionList({ + data: 'trackData', + list: input.value('contributorContribs'), + }).outputs({ + '#reverseContributionList': '#tracksAsContributor', + }), + + withReverseContributionList({ + data: 'trackData', + list: input.value('coverArtistContribs'), + }).outputs({ + '#reverseContributionList': '#tracksAsCoverArtist', + }), + + { + dependencies: [ + '#tracksAsArtist', + '#tracksAsContributor', + '#tracksAsCoverArtist', + ], + + compute: ({ + ['#tracksAsArtist']: tracksAsArtist, + ['#tracksAsContributor']: tracksAsContributor, + ['#tracksAsCoverArtist']: tracksAsCoverArtist, + }) => + unique([ + ...tracksAsArtist, + ...tracksAsContributor, + ...tracksAsCoverArtist, + ]), }, - }, + ], tracksAsCommentator: { flags: {expose: true}, @@ -99,31 +138,77 @@ export class Artist extends Thing { }, }, - albumsAsAlbumArtist: - Artist.filterByContrib('albumData', 'artistContribs'), - albumsAsCoverArtist: - Artist.filterByContrib('albumData', 'coverArtistContribs'), - albumsAsWallpaperArtist: - Artist.filterByContrib('albumData', 'wallpaperArtistContribs'), - albumsAsBannerArtist: - Artist.filterByContrib('albumData', 'bannerArtistContribs'), + albumsAsAlbumArtist: reverseContributionList({ + data: 'albumData', + list: input.value('artistContribs'), + }), - albumsAsAny: { - flags: {expose: true}, + albumsAsCoverArtist: reverseContributionList({ + data: 'albumData', + list: input.value('coverArtistContribs'), + }), - expose: { - dependencies: ['albumData'], - - compute: ({albumData, [Artist.instance]: artist}) => - albumData?.filter((album) => - [ - ...album.artistContribs, - ...album.coverArtistContribs, - ...album.wallpaperArtistContribs, - ...album.bannerArtistContribs, - ].some(({who}) => who === artist)) ?? [], + albumsAsWallpaperArtist: reverseContributionList({ + data: 'albumData', + list: input.value('wallpaperArtistContribs'), + }), + + albumsAsBannerArtist: reverseContributionList({ + data: 'albumData', + list: input.value('bannerArtistContribs'), + }), + + albumsAsAny: [ + withReverseContributionList({ + data: 'albumData', + list: input.value('artistContribs'), + }).outputs({ + '#reverseContributionList': '#albumsAsArtist', + }), + + withReverseContributionList({ + data: 'albumData', + list: input.value('coverArtistContribs'), + }).outputs({ + '#reverseContributionList': '#albumsAsCoverArtist', + }), + + withReverseContributionList({ + data: 'albumData', + list: input.value('wallpaperArtistContribs'), + }).outputs({ + '#reverseContributionList': '#albumsAsWallpaperArtist', + }), + + withReverseContributionList({ + data: 'albumData', + list: input.value('bannerArtistContribs'), + }).outputs({ + '#reverseContributionList': '#albumsAsBannerArtist', + }), + + { + dependencies: [ + '#albumsAsArtist', + '#albumsAsCoverArtist', + '#albumsAsWallpaperArtist', + '#albumsAsBannerArtist', + ], + + compute: ({ + ['#albumsAsArtist']: albumsAsArtist, + ['#albumsAsCoverArtist']: albumsAsCoverArtist, + ['#albumsAsWallpaperArtist']: albumsAsWallpaperArtist, + ['#albumsAsBannerArtist']: albumsAsBannerArtist, + }) => + unique([ + ...albumsAsArtist, + ...albumsAsCoverArtist, + ...albumsAsWallpaperArtist, + ...albumsAsBannerArtist, + ]), }, - }, + ], albumsAsCommentator: { flags: {expose: true}, @@ -137,8 +222,10 @@ export class Artist extends Thing { }, }, - flashesAsContributor: - Artist.filterByContrib('flashData', 'contributorContribs'), + flashesAsContributor: reverseContributionList({ + data: 'flashData', + list: input.value('contributorContribs'), + }), }); static [Thing.getSerializeDescriptors] = ({ @@ -167,20 +254,4 @@ export class Artist extends Thing { flashesAsContributor: S.toRefs, }); - - static filterByContrib = (thingDataProperty, contribsProperty) => ({ - flags: {expose: true}, - - expose: { - dependencies: ['this', thingDataProperty], - - compute: ({ - this: artist, - [thingDataProperty]: thingData, - }) => - thingData?.filter(thing => - thing[contribsProperty] - ?.some(contrib => contrib.who === artist)) ?? [], - }, - }); } diff --git a/src/page/artist.js b/src/page/artist.js index 27ff896..b9a2f73 100644 --- a/src/page/artist.js +++ b/src/page/artist.js @@ -1,5 +1,7 @@ import {empty} from '#sugar'; +import CacheableObject from '#cacheable-object'; + export const description = `per-artist info & artwork gallery pages`; // NB: See artist-alias.js for artist alias redirect pages. -- cgit 1.3.0-6-gf8a5