« get me outta code hell

data: miscellaneous cleanup for withOtherReleases logic - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-02-19 16:47:45 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-03-02 08:24:12 -0400
commit586c3b9defc0d6222502f43a0cc4fa39c871a018 (patch)
tree3bbd9cc289b0c29e126a2aceec30ef3b6636bb9f
parent76e508ffe3818a78fb941ecde05fe9c269e8bc22 (diff)
data: miscellaneous cleanup for withOtherReleases logic
Defines withOtherReleases in terms of new function
withAllReleases (also exposed as Track.allReleases),
in turn based on new property Track.secondaryReleases
(of the main release), which is a reverse ref list,
reverse.tracksWhichAreSecondaryReleasesOf().
-rw-r--r--src/data/composite/things/track/index.js1
-rw-r--r--src/data/composite/things/track/withAllReleases.js47
-rw-r--r--src/data/composite/things/track/withOtherReleases.js30
-rw-r--r--src/data/things/track.js19
4 files changed, 76 insertions, 21 deletions
diff --git a/src/data/composite/things/track/index.js b/src/data/composite/things/track/index.js
index 492b35be..beb8c6ab 100644
--- a/src/data/composite/things/track/index.js
+++ b/src/data/composite/things/track/index.js
@@ -2,6 +2,7 @@ export {default as exitWithoutUniqueCoverArt} from './exitWithoutUniqueCoverArt.
 export {default as inheritContributionListFromMainRelease} from './inheritContributionListFromMainRelease.js';
 export {default as inheritFromMainRelease} from './inheritFromMainRelease.js';
 export {default as withAlbum} from './withAlbum.js';
+export {default as withAllReleases} from './withAllReleases.js';
 export {default as withAlwaysReferenceByDirectory} from './withAlwaysReferenceByDirectory.js';
 export {default as withContainingTrackSection} from './withContainingTrackSection.js';
 export {default as withDate} from './withDate.js';
diff --git a/src/data/composite/things/track/withAllReleases.js b/src/data/composite/things/track/withAllReleases.js
new file mode 100644
index 00000000..b93bf753
--- /dev/null
+++ b/src/data/composite/things/track/withAllReleases.js
@@ -0,0 +1,47 @@
+// Gets all releases of the current track. All items of the outputs are
+// distinct Track objects; one track is the main release; all else are
+// secondary releases of that main release; and one item, which may be
+// the main release or one of the secondary releases, is the current
+// track. The results are sorted by date, and it is possible that the
+// main release is not actually the earliest/first.
+
+import {input, templateCompositeFrom} from '#composite';
+import {sortByDate} from '#sort';
+
+import {exitWithoutDependency} from '#composite/control-flow';
+import {withPropertyFromObject} from '#composite/data';
+
+import withMainRelease from './withMainRelease.js';
+
+export default templateCompositeFrom({
+  annotation: `withAllReleases`,
+
+  outputs: ['#allReleases'],
+
+  steps: () => [
+    withMainRelease({
+      selfIfMain: input.value(true),
+      notFoundValue: input.value([]),
+    }),
+
+    // We don't talk about bruno no no
+    // Yes, this can perform a normal access equivalent to
+    // `this.secondaryReleases` from within a data composition.
+    // Oooooooooooooooooooooooooooooooooooooooooooooooo
+    withPropertyFromObject({
+      object: '#mainRelease',
+      property: input.value('secondaryReleases'),
+    }),
+
+    {
+      dependencies: ['#mainRelease', '#mainRelease.secondaryReleases'],
+      compute: (continuation, {
+        ['#mainRelease']: mainRelease,
+        ['#mainRelease.secondaryReleases']: secondaryReleases,
+      }) => continuation({
+        ['#allReleases']:
+          sortByDate([mainRelease, ...secondaryReleases]),
+      }),
+    },
+  ],
+});
diff --git a/src/data/composite/things/track/withOtherReleases.js b/src/data/composite/things/track/withOtherReleases.js
index 3fec8742..0639742f 100644
--- a/src/data/composite/things/track/withOtherReleases.js
+++ b/src/data/composite/things/track/withOtherReleases.js
@@ -1,8 +1,12 @@
+// Gets all releases of the current track *except* this track itself;
+// in other words, all other releases of the current track.
+
 import {input, templateCompositeFrom} from '#composite';
 
 import {exitWithoutDependency} from '#composite/control-flow';
+import {withPropertyFromObject} from '#composite/data';
 
-import withMainRelease from './withMainRelease.js';
+import withAllReleases from './withAllReleases.js';
 
 export default templateCompositeFrom({
   annotation: `withOtherReleases`,
@@ -10,32 +14,16 @@ export default templateCompositeFrom({
   outputs: ['#otherReleases'],
 
   steps: () => [
-    exitWithoutDependency({
-      dependency: 'trackData',
-      mode: input.value('empty'),
-    }),
-
-    withMainRelease({
-      selfIfMain: input.value(true),
-      notFoundValue: input.value([]),
-    }),
+    withAllReleases(),
 
-    // TODO: Jegus shouldn't this be a proper reverse list
     {
-      dependencies: [input.myself(), '#mainRelease', 'trackData'],
+      dependencies: [input.myself(), '#allReleases'],
       compute: (continuation, {
         [input.myself()]: thisTrack,
-        ['#mainRelease']: mainRelease,
-        trackData,
+        ['#allReleases']: allReleases,
       }) => continuation({
         ['#otherReleases']:
-          (mainRelease === thisTrack
-            ? []
-            : [mainRelease])
-            .concat(trackData.filter(track =>
-              track !== mainRelease &&
-              track !== thisTrack &&
-              track.mainReleaseTrack === mainRelease)),
+          allReleases.filter(track => track !== thisTrack),
       }),
     },
   ],
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 6ac417b5..69eb98a5 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -63,6 +63,7 @@ import {
   inheritContributionListFromMainRelease,
   inheritFromMainRelease,
   withAlbum,
+  withAllReleases,
   withAlwaysReferenceByDirectory,
   withContainingTrackSection,
   withDate,
@@ -419,6 +420,17 @@ export class Track extends Thing {
       }),
     ],
 
+    // Only has any value for main releases, because secondary releases
+    // are never secondary to *another* secondary release.
+    secondaryReleases: reverseReferenceList({
+      reverse: soupyReverse.input('tracksWhichAreSecondaryReleasesOf'),
+    }),
+
+    allReleases: [
+      withAllReleases(),
+      exposeDependency({dependency: '#allReleases'}),
+    ],
+
     otherReleases: [
       withOtherReleases(),
       exposeDependency({dependency: '#otherReleases'}),
@@ -679,6 +691,13 @@ export class Track extends Thing {
       referencing: track => [track],
       referenced: track => track.commentatorArtists,
     },
+
+    tracksWhichAreSecondaryReleasesOf: {
+      bindTo: 'trackData',
+
+      referencing: track => track.isSecondaryRelease ? [track] : [],
+      referenced: track => [track.mainReleaseTrack],
+    },
   };
 
   // Track YAML loading is handled in album.js.