« get me outta code hell

data: soupy reverse - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-01-11 20:49:26 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-01-11 20:49:26 -0400
commit77fc589466fc0c04326231638c5ec6026e7948d4 (patch)
treedbc019e4f72851bd3fa8fd5195d87fe6f6177f7c /src/data/things
parent3bb0a89e80fddb985cc1fc4775e58b0d4a7445dc (diff)
data: soupy reverse
Diffstat (limited to 'src/data/things')
-rw-r--r--src/data/things/album.js71
-rw-r--r--src/data/things/art-tag.js21
-rw-r--r--src/data/things/artist.js83
-rw-r--r--src/data/things/flash.js50
-rw-r--r--src/data/things/group.js58
-rw-r--r--src/data/things/track.js54
6 files changed, 207 insertions, 130 deletions
diff --git a/src/data/things/album.js b/src/data/things/album.js
index e4463d27..151b5087 100644
--- a/src/data/things/album.js
+++ b/src/data/things/album.js
@@ -44,10 +44,11 @@ import {
   name,
   referencedArtworkList,
   referenceList,
-  reverseReferencedArtworkList,
+  reverseReferenceList,
   simpleDate,
   simpleString,
   soupyFind,
+  soupyReverse,
   thing,
   thingList,
   urls,
@@ -262,6 +263,7 @@ export class Album extends Thing {
     // Update only
 
     find: soupyFind(),
+    reverse: soupyReverse(),
 
     // used for referencedArtworkList (mixedFind)
     albumData: wikiData({
@@ -297,7 +299,9 @@ export class Album extends Thing {
         value: input.value([]),
       }),
 
-      reverseReferencedArtworkList(),
+      reverseReferenceList({
+        reverse: soupyReverse.input('artworksWhichReference'),
+      }),
     ],
   });
 
@@ -356,6 +360,55 @@ export class Album extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    albumsWhoseTracksInclude: {
+      bindTo: 'albumData',
+
+      referencing: album => [album],
+      referenced: album => album.tracks,
+    },
+
+    albumsWhoseTrackSectionsInclude: {
+      bindTo: 'albumData',
+
+      referencing: album => [album],
+      referenced: album => album.trackSections,
+    },
+
+    albumsWhoseArtworksFeature: {
+      bindTo: 'albumData',
+
+      referencing: album => [album],
+      referenced: album => album.artTags,
+    },
+
+    albumsWhoseGroupsInclude: {
+      bindTo: 'albumData',
+
+      referencing: album => [album],
+      referenced: album => album.groups,
+    },
+
+    albumArtistContributionsBy:
+      soupyReverse.contributionsBy('albumData', 'artistContribs'),
+
+    albumCoverArtistContributionsBy:
+      soupyReverse.contributionsBy('albumData', 'coverArtistContribs'),
+
+    albumWallpaperArtistContributionsBy:
+      soupyReverse.contributionsBy('albumData', 'wallpaperArtistContribs'),
+
+    albumBannerArtistContributionsBy:
+      soupyReverse.contributionsBy('albumData', 'bannerArtistContribs'),
+
+    albumsWithCommentaryBy: {
+      bindTo: 'albumData',
+
+      referencing: album => [album],
+      referenced: album => album.commentatorArtists,
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Album': {property: 'name'},
@@ -624,10 +677,7 @@ export class TrackSection extends Thing {
 
     // Update only
 
-    // used for withAlbum
-    albumData: wikiData({
-      class: input.value(Album),
-    }),
+    reverse: soupyReverse(),
 
     // Expose only
 
@@ -712,6 +762,15 @@ export class TrackSection extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    trackSectionsWhichInclude: {
+      bindTo: 'trackSectionData',
+
+      referencing: trackSection => [trackSection],
+      referenced: trackSection => trackSection.tracks,
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Section': {property: 'name'},
diff --git a/src/data/things/art-tag.js b/src/data/things/art-tag.js
index b7d79e8c..9842c887 100644
--- a/src/data/things/art-tag.js
+++ b/src/data/things/art-tag.js
@@ -12,6 +12,7 @@ import {
   directory,
   flag,
   name,
+  soupyReverse,
   wikiData,
 } from '#composite/wiki-properties';
 
@@ -41,15 +42,7 @@ export class ArtTag extends Thing {
 
     // Update only
 
-    // used for taggedInThings (reverse)
-    albumData: wikiData({
-      class: input.value(Album),
-    }),
-
-    // used for taggedInThings (reverse)
-    trackData: wikiData({
-      class: input.value(Track),
-    }),
+    reverse: soupyReverse(),
 
     // Expose only
 
@@ -57,11 +50,13 @@ export class ArtTag extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'albumData', 'trackData'],
-        compute: ({this: artTag, albumData, trackData}) =>
+        dependencies: ['this', 'reverse'],
+        compute: ({this: artTag, reverse}) =>
           sortAlbumsTracksChronologically(
-            [...albumData, ...trackData]
-              .filter(({artTags}) => artTags.includes(artTag)),
+            [
+              ...reverse.albumsWhoseArtworksFeature(artTag),
+              ...reverse.tracksWhoseArtworksFeature(artTag),
+            ],
             {getDate: thing => thing.coverArtDate ?? thing.date}),
       },
     },
diff --git a/src/data/things/artist.js b/src/data/things/artist.js
index 746e767a..7ed99a8e 100644
--- a/src/data/things/artist.js
+++ b/src/data/things/artist.js
@@ -11,19 +11,16 @@ import Thing from '#thing';
 import {isName, validateArrayItems} from '#validators';
 import {getKebabCase} from '#wiki-data';
 
-import {withReverseContributionList} from '#composite/wiki-data';
-
 import {
   contentString,
   directory,
   fileExtension,
   flag,
   name,
-  reverseAnnotatedReferenceList,
-  reverseContributionList,
   reverseReferenceList,
   singleReference,
   soupyFind,
+  soupyReverse,
   urls,
   wikiData,
 } from '#composite/wiki-properties';
@@ -62,90 +59,56 @@ export class Artist extends Thing {
     // Update only
 
     find: soupyFind(),
-
-    // used for reverse contribution lists
-    albumData: wikiData({
-      class: input.value(Album),
-    }),
-
-    // used for reverse contribution lists
-    flashData: wikiData({
-      class: input.value(Flash),
-    }),
-
-    // used for closelyLinkedGroups
-    groupData: wikiData({
-      class: input.value(Group),
-    }),
-
-    // used for reverse contribution lists
-    trackData: wikiData({
-      class: input.value(Track),
-    }),
+    reverse: soupyReverse(),
 
     // Expose only
 
-    trackArtistContributions: reverseContributionList({
-      data: 'trackData',
-      list: input.value('artistContribs'),
+    trackArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('trackArtistContributionsBy'),
     }),
 
-    trackContributorContributions: reverseContributionList({
-      data: 'trackData',
-      list: input.value('contributorContribs'),
+    trackContributorContributions: reverseReferenceList({
+      reverse: soupyReverse.input('trackContributorContributionsBy'),
     }),
 
-    trackCoverArtistContributions: reverseContributionList({
-      data: 'trackData',
-      list: input.value('coverArtistContribs'),
+    trackCoverArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('trackCoverArtistContributionsBy'),
     }),
 
     tracksAsCommentator: reverseReferenceList({
-      data: 'trackData',
-      list: input.value('commentatorArtists'),
+      reverse: soupyReverse.input('tracksWithCommentaryBy'),
     }),
 
-    albumArtistContributions: reverseContributionList({
-      data: 'albumData',
-      list: input.value('artistContribs'),
+    albumArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('albumArtistContributionsBy'),
     }),
 
-    albumCoverArtistContributions: reverseContributionList({
-      data: 'albumData',
-      list: input.value('coverArtistContribs'),
+    albumCoverArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('albumCoverArtistContributionsBy'),
     }),
 
-    albumWallpaperArtistContributions: reverseContributionList({
-      data: 'albumData',
-      list: input.value('wallpaperArtistContribs'),
+    albumWallpaperArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('albumWallpaperArtistContributionsBy'),
     }),
 
-    albumBannerArtistContributions: reverseContributionList({
-      data: 'albumData',
-      list: input.value('bannerArtistContribs'),
+    albumBannerArtistContributions: reverseReferenceList({
+      reverse: soupyReverse.input('albumBannerArtistContributionsBy'),
     }),
 
     albumsAsCommentator: reverseReferenceList({
-      data: 'albumData',
-      list: input.value('commentatorArtists'),
+      reverse: soupyReverse.input('albumsWithCommentaryBy'),
     }),
 
-    flashContributorContributions: reverseContributionList({
-      data: 'flashData',
-      list: input.value('contributorContribs'),
+    flashContributorContributions: reverseReferenceList({
+      reverse: soupyReverse.input('flashContributorContributionsBy'),
     }),
 
     flashesAsCommentator: reverseReferenceList({
-      data: 'flashData',
-      list: input.value('commentatorArtists'),
+      reverse: soupyReverse.input('flashesWithCommentaryBy'),
     }),
 
-    closelyLinkedGroups: reverseAnnotatedReferenceList({
-      data: 'groupData',
-      list: input.value('closelyLinkedArtists'),
-
-      forward: input.value('artist'),
-      backward: input.value('group'),
+    closelyLinkedGroups: reverseReferenceList({
+      reverse: soupyReverse.input('groupsCloselyLinkedTo'),
     }),
 
     totalDuration: artistTotalDuration(),
diff --git a/src/data/things/flash.js b/src/data/things/flash.js
index 8a3fc374..b143b560 100644
--- a/src/data/things/flash.js
+++ b/src/data/things/flash.js
@@ -30,6 +30,7 @@ import {
   referenceList,
   simpleDate,
   soupyFind,
+  soupyReverse,
   thing,
   urls,
   wikiData,
@@ -115,11 +116,7 @@ export class Flash extends Thing {
     // Update only
 
     find: soupyFind(),
-
-    // used for withFlashAct (reverse)
-    flashActData: wikiData({
-      class: input.value(FlashAct),
-    }),
+    reverse: soupyReverse(),
 
     // used for withMatchingContributionPresets (indirectly by Contribution)
     wikiInfo: thing({
@@ -167,6 +164,25 @@ export class Flash extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    flashesWhichFeature: {
+      bindTo: 'flashData',
+
+      referencing: flash => [flash],
+      referenced: flash => flash.featuredTracks,
+    },
+
+    flashContributorContributionsBy:
+      soupyReverse.contributionsBy('flashData', 'contributorContribs'),
+
+    flashesWithCommentaryBy: {
+      bindTo: 'flashData',
+
+      referencing: flash => [flash],
+      referenced: flash => flash.commentatorArtists,
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Flash': {property: 'name'},
@@ -242,11 +258,7 @@ export class FlashAct extends Thing {
     // Update only
 
     find: soupyFind(),
-
-    // used for withFlashSide
-    flashSideData: wikiData({
-      class: input.value(FlashSide),
-    }),
+    reverse: soupyReverse(),
 
     // Expose only
 
@@ -263,6 +275,15 @@ export class FlashAct extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    flashActsWhoseFlashesInclude: {
+      bindTo: 'flashActData',
+
+      referencing: flashAct => [flashAct],
+      referenced: flashAct => flashAct.flashes,
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Act': {property: 'name'},
@@ -314,6 +335,15 @@ export class FlashSide extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    flashSidesWhoseActsInclude: {
+      bindTo: 'flashSideData',
+
+      referencing: flashSide => [flashSide],
+      referenced: flashSide => flashSide.acts,
+    },
+  };
+
   static [Thing.getYamlLoadingSpec] = ({
     documentModes: {allInOne},
     thingConstructors: {Flash, FlashAct},
diff --git a/src/data/things/group.js b/src/data/things/group.js
index 8bc71931..ed3c59bb 100644
--- a/src/data/things/group.js
+++ b/src/data/things/group.js
@@ -52,17 +52,7 @@ export class Group extends Thing {
     // Update only
 
     find: soupyFind(),
-
-    // used for albums (reverse)
-    albumData: wikiData({
-      class: input.value(Album),
-    }),
-
-    // used for category (reverse)
-    // used for color (reverse)
-    groupCategoryData: wikiData({
-      class: input.value(GroupCategory),
-    }),
+    reverse: soupyFind(),
 
     // Expose only
 
@@ -82,9 +72,9 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'albumData'],
-        compute: ({this: group, albumData}) =>
-          albumData?.filter((album) => album.groups.includes(group)) ?? [],
+        dependencies: ['this', 'reverse'],
+        compute: ({this: group, reverse}) =>
+          reverse.albumsWhoseGroupsInclude(group),
       },
     },
 
@@ -92,9 +82,9 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'groupCategoryData'],
-        compute: ({this: group, groupCategoryData}) =>
-          groupCategoryData.find((category) => category.groups.includes(group))
+        dependencies: ['this', 'reverse'],
+        compute: ({this: group, reverse}) =>
+          reverse.groupCategoriesWhichInclude(group, {unique: true})
             ?.color,
       },
     },
@@ -103,9 +93,9 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'groupCategoryData'],
-        compute: ({this: group, groupCategoryData}) =>
-          groupCategoryData.find((category) => category.groups.includes(group)) ??
+        dependencies: ['this', 'reverse'],
+        compute: ({this: group, reverse}) =>
+          reverse.groupCategoriesWhichInclude(group, {unique: true}) ??
           null,
       },
     },
@@ -118,6 +108,25 @@ export class Group extends Thing {
     },
   };
 
+  static [Thing.reverseSpecs] = {
+    groupsCloselyLinkedTo: {
+      bindTo: 'groupData',
+
+      referencing: group =>
+        group.closelyLinkedArtists
+          .map(({artist, ...referenceDetails}) => ({
+            group,
+            artist,
+            referenceDetails,
+          })),
+
+      referenced: ({artist}) => [artist],
+
+      tidy: ({group, referenceDetails}) =>
+        ({group, ...referenceDetails}),
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Group': {property: 'name'},
@@ -217,6 +226,15 @@ export class GroupCategory extends Thing {
     find: soupyFind(),
   });
 
+  static [Thing.reverseSpecs] = {
+    groupCategoriesWhichInclude: {
+      bindTo: 'groupCategoryData',
+
+      referencing: groupCategory => [groupCategory],
+      referenced: groupCategory => groupCategory.groups,
+    },
+  };
+
   static [Thing.yamlDocumentSpec] = {
     fields: {
       'Category': {property: 'name'},
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 81ba35bb..ff4750db 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -48,11 +48,11 @@ import {
   referenceList,
   referencedArtworkList,
   reverseReferenceList,
-  reverseReferencedArtworkList,
   simpleDate,
   simpleString,
   singleReference,
   soupyFind,
+  soupyReverse,
   thing,
   urls,
   wikiData,
@@ -62,7 +62,6 @@ import {
   exitWithoutUniqueCoverArt,
   inheritContributionListFromOriginalRelease,
   inheritFromOriginalRelease,
-  trackReverseReferenceList,
   withAlbum,
   withAlwaysReferenceByDirectory,
   withContainingTrackSection,
@@ -370,29 +369,18 @@ export class Track extends Thing {
     // Update only
 
     find: soupyFind(),
+    reverse: soupyReverse(),
 
     // used for referencedArtworkList (mixedFind)
-    // used for withAlbum (reverse)
     albumData: wikiData({
       class: input.value(Album),
     }),
 
-    // used for featuredInFlashes (reverse)
-    flashData: wikiData({
-      class: input.value(Flash),
-    }),
-
     // used for referencedArtworkList (mixedFind)
-    // used for trackReverseReferenceList (reverse)
     trackData: wikiData({
       class: input.value(Track),
     }),
 
-    // used for withContainingTrackSection (reverse)
-    trackSectionData: wikiData({
-      class: input.value(TrackSection),
-    }),
-
     // used for withMatchingContributionPresets (indirectly by Contribution)
     wikiInfo: thing({
       class: input.value(WikiInfo),
@@ -439,17 +427,16 @@ export class Track extends Thing {
       exposeDependency({dependency: '#otherReleases'}),
     ],
 
-    referencedByTracks: trackReverseReferenceList({
-      list: input.value('referencedTracks'),
+    referencedByTracks: reverseReferenceList({
+      reverse: soupyReverse.input('tracksWhichReference'),
     }),
 
-    sampledByTracks: trackReverseReferenceList({
-      list: input.value('sampledTracks'),
+    sampledByTracks: reverseReferenceList({
+      reverse: soupyReverse.input('tracksWhichSample'),
     }),
 
     featuredInFlashes: reverseReferenceList({
-      data: 'flashData',
-      list: input.value('featuredTracks'),
+      reverse: soupyReverse.input('flashesWhichFeature'),
     }),
 
     referencedByArtworks: [
@@ -457,7 +444,9 @@ export class Track extends Thing {
         value: input.value([]),
       }),
 
-      reverseReferencedArtworkList(),
+      reverseReferenceList({
+        reverse: soupyReverse.input('artworksWhichReference'),
+      }),
     ],
   });
 
@@ -664,6 +653,29 @@ export class Track extends Thing {
       referencing: track => track.isOriginalRelease ? [track] : [],
       referenced: track => track.sampledTracks,
     },
+
+    tracksWhoseArtworksFeature: {
+      bindTo: 'trackData',
+
+      referencing: track => [track],
+      referenced: track => track.artTags,
+    },
+
+    trackArtistContributionsBy:
+      soupyReverse.contributionsBy('trackData', 'artistContribs'),
+
+    trackContributorContributionsBy:
+      soupyReverse.contributionsBy('trackData', 'contributorContribs'),
+
+    trackCoverArtistContributionsBy:
+      soupyReverse.contributionsBy('trackData', 'coverArtistContribs'),
+
+    tracksWithCommentaryBy: {
+      bindTo: 'trackData',
+
+      referencing: track => [track],
+      referenced: track => track.commentatorArtists,
+    },
   };
 
   // Track YAML loading is handled in album.js.