« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/track.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/things/track.js')
-rw-r--r--src/data/things/track.js796
1 files changed, 462 insertions, 334 deletions
diff --git a/src/data/things/track.js b/src/data/things/track.js
index e176acb4..bf56a6dd 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -44,60 +44,72 @@ export class Track extends Thing {
     sampledTracksByRef: Thing.common.referenceList(Track),
     artTagsByRef: Thing.common.referenceList(ArtTag),
 
-    hasCoverArt: {
-      flags: {update: true, expose: true},
-
-      update: {
-        validate(value) {
-          if (value !== false) {
-            throw new TypeError(`Expected false or null`);
-          }
-
-          return true;
-        },
-      },
-
-      expose: {
-        dependencies: ['albumData', 'coverArtistContribsByRef'],
-        transform: (hasCoverArt, {
-          albumData,
-          coverArtistContribsByRef,
-          [Track.instance]: track,
-        }) =>
-          Track.hasCoverArt(
-            track,
-            albumData,
-            coverArtistContribsByRef,
-            hasCoverArt
-          ),
+    color: Thing.composite.from(`Track.color`, [
+      Thing.composite.exposeUpdateValueOrContinue(),
+      Track.composite.withContainingTrackSection({earlyExitIfNotFound: false}),
+
+      {
+        dependencies: ['#trackSection'],
+        compute: ({'#trackSection': trackSection}, continuation) =>
+          // Album.trackSections guarantees the track section will have a
+          // color property (inheriting from the album's own color), but only
+          // if it's actually present! Color will be inherited directly from
+          // album otherwise.
+          (trackSection
+            ? trackSection.color
+            : continuation()),
       },
-    },
 
-    coverArtFileExtension: {
-      flags: {update: true, expose: true},
-
-      update: {validate: isFileExtension},
-
-      expose: {
-        dependencies: ['albumData', 'coverArtistContribsByRef'],
-        transform: (coverArtFileExtension, {
-          albumData,
-          coverArtistContribsByRef,
-          hasCoverArt,
-          [Track.instance]: track,
-        }) =>
-          coverArtFileExtension ??
-          (Track.hasCoverArt(
-            track,
-            albumData,
-            coverArtistContribsByRef,
-            hasCoverArt
-          )
-            ? Track.findAlbum(track, albumData)?.trackCoverArtFileExtension
-            : Track.findAlbum(track, albumData)?.coverArtFileExtension) ??
-          'jpg',
-      },
-    },
+      Track.composite.withAlbumProperty('color'),
+      Thing.composite.exposeDependency('#album.color', {
+        update: {validate: isColor},
+      }),
+    ]),
+
+    // Disables presenting the track as though it has its own unique artwork.
+    // This flag should only be used in select circumstances, i.e. to override
+    // an album's trackCoverArtists. This flag supercedes that property, as well
+    // as the track's own coverArtists.
+    disableUniqueCoverArt: Thing.common.flag(),
+
+    // File extension for track's corresponding media file. This represents the
+    // track's unique cover artwork, if any, and does not inherit the extension
+    // of the album's main artwork. It does inherit trackCoverArtFileExtension,
+    // if present on the album.
+    coverArtFileExtension: Thing.composite.from(`Track.coverArtFileExtension`, [
+      // No cover art file extension if the track doesn't have unique artwork
+      // in the first place.
+      Track.composite.withHasUniqueCoverArt(),
+      Thing.composite.earlyExitWithoutDependency('#hasUniqueCoverArt', {mode: 'falsy'}),
+
+      // Expose custom coverArtFileExtension update value first.
+      Thing.composite.exposeUpdateValueOrContinue(),
+
+      // Expose album's trackCoverArtFileExtension if no update value set.
+      Track.composite.withAlbumProperty('trackCoverArtFileExtension'),
+      Thing.composite.exposeDependencyOrContinue('#album.trackCoverArtFileExtension'),
+
+      // Fallback to 'jpg'.
+      Thing.composite.exposeConstant('jpg', {
+        update: {validate: isFileExtension},
+      }),
+    ]),
+
+    // Date of cover art release. Like coverArtFileExtension, this represents
+    // only the track's own unique cover artwork, if any. This exposes only as
+    // the track's own coverArtDate or its album's trackArtDate, so if neither
+    // is specified, this value is null.
+    coverArtDate: Thing.composite.from(`Track.coverArtDate`, [
+      Track.composite.withHasUniqueCoverArt(),
+      Thing.composite.earlyExitWithoutDependency('#hasUniqueCoverArt', {mode: 'falsy'}),
+
+      Thing.composite.exposeUpdateValueOrContinue(),
+
+      Track.composite.withAlbumProperty('trackArtDate'),
+      Thing.composite.exposeDependency('#album.trackArtDate', {
+        update: {validate: isDate},
+      }),
+    ]),
 
     originalReleaseTrackByRef: Thing.common.singleReference(Track),
 
@@ -121,15 +133,10 @@ export class Track extends Thing {
 
     commentatorArtists: Thing.common.commentatorArtists(),
 
-    album: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['albumData'],
-        compute: ({[Track.instance]: track, albumData}) =>
-          albumData?.find((album) => album.tracks.includes(track)) ?? null,
-      },
-    },
+    album: Thing.composite.from(`Track.album`, [
+      Track.composite.withAlbum(),
+      Thing.composite.exposeDependency('#album'),
+    ]),
 
     // Note - this is an internal property used only to help identify a track.
     // It should not be assumed in general that the album and dataSourceAlbum match
@@ -138,158 +145,120 @@ export class Track extends Thing {
     // not generally relevant information). It's also not guaranteed that
     // dataSourceAlbum is available (depending on the Track creator to optionally
     // provide dataSourceAlbumByRef).
-    dataSourceAlbum: Thing.common.dynamicThingFromSingleReference(
-      'dataSourceAlbumByRef',
-      'albumData',
-      find.album
-    ),
-
-    date: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['albumData', 'dateFirstReleased'],
-        compute: ({albumData, dateFirstReleased, [Track.instance]: track}) =>
-          dateFirstReleased ?? Track.findAlbum(track, albumData)?.date ?? null,
+    dataSourceAlbum: Thing.common.dynamicThingFromSingleReference('dataSourceAlbumByRef', 'albumData', find.album),
+
+    date: Thing.composite.from(`Track.date`, [
+      Thing.composite.exposeDependencyOrContinue('dateFirstReleased'),
+      Track.composite.withAlbumProperty('date'),
+      Thing.composite.exposeDependency('#album.date'),
+    ]),
+
+    // Whether or not the track has "unique" cover artwork - a cover which is
+    // specifically associated with this track in particular, rather than with
+    // the track's album as a whole. This is typically used to select between
+    // displaying the track artwork and a fallback, such as the album artwork
+    // or a placeholder. (This property is named hasUniqueCoverArt instead of
+    // the usual hasCoverArt to emphasize that it does not inherit from the
+    // album.)
+    hasUniqueCoverArt: Thing.composite.from(`Track.hasUniqueCoverArt`, [
+      Track.composite.withHasUniqueCoverArt(),
+      Thing.composite.exposeDependency('#hasUniqueCoverArt'),
+    ]),
+
+    originalReleaseTrack: Thing.composite.from(`Track.originalReleaseTrack`, [
+      Track.composite.withOriginalRelease(),
+      Thing.composite.exposeDependency('#originalRelease'),
+    ]),
+
+    otherReleases: Thing.composite.from(`Track.otherReleases`, [
+      Thing.composite.earlyExitWithoutDependency('trackData', {mode: 'empty'}),
+      Track.composite.withOriginalRelease({selfIfOriginal: true}),
+
+      {
+        flags: {expose: true},
+        expose: {
+          dependencies: ['this', 'trackData', '#originalRelease'],
+          compute: ({
+            this: thisTrack,
+            trackData,
+            '#originalRelease': originalRelease,
+          }) =>
+            (originalRelease === thisTrack
+              ? []
+              : [originalRelease])
+              .concat(trackData.filter(track =>
+                track !== originalRelease &&
+                track !== thisTrack &&
+                track.originalReleaseTrack === originalRelease)),
+        },
       },
-    },
-
-    color: {
-      flags: {update: true, expose: true},
-
-      update: {validate: isColor},
-
-      expose: {
-        dependencies: ['albumData'],
-
-        transform: (color, {albumData, [Track.instance]: track}) =>
-          color ??
-            Track.findAlbum(track, albumData)
-              ?.trackSections.find(({tracks}) => tracks.includes(track))
-                ?.color ?? null,
+    ]),
+
+    artistContribs: Thing.composite.from(`Track.artistContribs`, [
+      Track.composite.inheritFromOriginalRelease({property: 'artistContribs'}),
+
+      Thing.composite.withResolvedContribs({
+        from: 'artistContribsByRef',
+        to: '#artistContribs',
+      }),
+
+      {
+        dependencies: ['#artistContribs'],
+        compute: ({'#artistContribs': contribsFromTrack}, continuation) =>
+          (empty(contribsFromTrack)
+            ? continuation()
+            : contribsFromTrack),
       },
-    },
 
-    coverArtDate: {
-      flags: {update: true, expose: true},
+      Track.composite.withAlbumProperty('artistContribs'),
+      Thing.composite.exposeDependency('#album.artistContribs'),
+    ]),
 
-      update: {validate: isDate},
-
-      expose: {
-        dependencies: [
-          'albumData',
-          'coverArtistContribsByRef',
-          'dateFirstReleased',
-          'hasCoverArt',
-        ],
-        transform: (coverArtDate, {
-          albumData,
-          coverArtistContribsByRef,
-          dateFirstReleased,
-          hasCoverArt,
-          [Track.instance]: track,
-        }) =>
-          (Track.hasCoverArt(track, albumData, coverArtistContribsByRef, hasCoverArt)
-            ? coverArtDate ??
-              dateFirstReleased ??
-              Track.findAlbum(track, albumData)?.trackArtDate ??
-              Track.findAlbum(track, albumData)?.date ??
-              null
-            : null),
-      },
-    },
+    contributorContribs: Thing.composite.from(`Track.contributorContribs`, [
+      Track.composite.inheritFromOriginalRelease({property: 'contributorContribs'}),
+      Thing.common.dynamicContribs('contributorContribsByRef'),
+    ]),
 
-    hasUniqueCoverArt: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['albumData', 'coverArtistContribsByRef', 'hasCoverArt'],
-        compute: ({
-          albumData,
-          coverArtistContribsByRef,
-          hasCoverArt,
-          [Track.instance]: track,
-        }) =>
-          Track.hasUniqueCoverArt(
-            track,
-            albumData,
-            coverArtistContribsByRef,
-            hasCoverArt
-          ),
+    // Cover artists aren't inherited from the original release, since it
+    // typically varies by release and isn't defined by the musical qualities
+    // of the track.
+    coverArtistContribs: Thing.composite.from(`Track.coverArtistContribs`, [
+      {
+        dependencies: ['disableUniqueCoverArt'],
+        compute: ({disableUniqueCoverArt}, continuation) =>
+          (disableUniqueCoverArt
+            ? null
+            : continuation()),
       },
-    },
 
-    originalReleaseTrack: Thing.common.dynamicThingFromSingleReference(
-      'originalReleaseTrackByRef',
-      'trackData',
-      find.track
-    ),
-
-    otherReleases: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['originalReleaseTrackByRef', 'trackData'],
-
-        compute: ({
-          originalReleaseTrackByRef: t1origRef,
-          trackData,
-          [Track.instance]: t1,
-        }) => {
-          if (!trackData) {
-            return [];
-          }
-
-          const t1orig = find.track(t1origRef, trackData);
-
-          return [
-            t1orig,
-            ...trackData.filter((t2) => {
-              const {originalReleaseTrack: t2orig} = t2;
-              return t2 !== t1 && t2orig && (t2orig === t1orig || t2orig === t1);
-            }),
-          ].filter(Boolean);
-        },
+      Thing.composite.withResolvedContribs({
+        from: 'coverArtistContribsByRef',
+        to: '#coverArtistContribs',
+      }),
+
+      {
+        dependencies: ['#coverArtistContribs'],
+        compute: ({'#coverArtistContribs': contribsFromTrack}, continuation) =>
+          (empty(contribsFromTrack)
+            ? continuation()
+            : contribsFromTrack),
       },
-    },
 
-    artistContribs:
-      Track.inheritFromOriginalRelease('artistContribs', [],
-        Thing.common.dynamicInheritContribs(
-          null,
-          'artistContribsByRef',
-          'artistContribsByRef',
-          'albumData',
-          Track.findAlbum)),
+      Track.composite.withAlbumProperty('trackCoverArtistContribs'),
+      Thing.composite.exposeDependency('#album.trackCoverArtistContribs'),
+    ]),
 
-    contributorContribs:
-      Track.inheritFromOriginalRelease('contributorContribs', [],
-        Thing.common.dynamicContribs('contributorContribsByRef')),
+    referencedTracks: Thing.composite.from(`Track.referencedTracks`, [
+      Track.composite.inheritFromOriginalRelease({property: 'referencedTracks'}),
+      Thing.common.dynamicThingsFromReferenceList('referencedTracksByRef', 'trackData', find.track),
+    ]),
 
-    // Cover artists aren't inherited from the original release, since it
-    // typically varies by release and isn't defined by the musical qualities
-    // of the track.
-    coverArtistContribs:
-      Thing.common.dynamicInheritContribs(
-        'hasCoverArt',
-        'coverArtistContribsByRef',
-        'trackCoverArtistContribsByRef',
-        'albumData',
-        Track.findAlbum),
-
-    referencedTracks:
-      Track.inheritFromOriginalRelease('referencedTracks', [],
-        Thing.common.dynamicThingsFromReferenceList(
-          'referencedTracksByRef',
-          'trackData',
-          find.track)),
-
-    sampledTracks:
-      Track.inheritFromOriginalRelease('sampledTracks', [],
-        Thing.common.dynamicThingsFromReferenceList(
-          'sampledTracksByRef',
-          'trackData',
-          find.track)),
+    sampledTracks: Thing.composite.from(`Track.sampledTracks`, [
+      Track.composite.inheritFromOriginalRelease({property: 'sampledTracks'}),
+      Thing.common.dynamicThingsFromReferenceList('sampledTracksByRef', 'trackData', find.track),
+    ]),
+
+    artTags: Thing.common.dynamicThingsFromReferenceList('artTagsByRef', 'artTagData', find.artTag),
 
     // Specifically exclude re-releases from this list - while it's useful to
     // get from a re-release to the tracks it references, re-releases aren't
@@ -299,162 +268,321 @@ export class Track extends Thing {
     // counting the number of times a track has been referenced, for use in
     // the "Tracks - by Times Referenced" listing page (or other data
     // processing).
-    referencedByTracks: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['trackData'],
-
-        compute: ({trackData, [Track.instance]: track}) =>
-          trackData
-            ? trackData
-                .filter((t) => !t.originalReleaseTrack)
-                .filter((t) => t.referencedTracks?.includes(track))
-            : [],
-      },
-    },
+    referencedByTracks: Track.composite.trackReverseReferenceList('referencedTracks'),
 
     // For the same reasoning, exclude re-releases from sampled tracks too.
-    sampledByTracks: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['trackData'],
-
-        compute: ({trackData, [Track.instance]: track}) =>
-          trackData
-            ? trackData
-                .filter((t) => !t.originalReleaseTrack)
-                .filter((t) => t.sampledTracks?.includes(track))
-            : [],
-      },
-    },
-
-    featuredInFlashes: Thing.common.reverseReferenceList(
-      'flashData',
-      'featuredTracks'
-    ),
+    sampledByTracks: Track.composite.trackReverseReferenceList('sampledTracks'),
 
-    artTags: Thing.common.dynamicThingsFromReferenceList(
-      'artTagsByRef',
-      'artTagData',
-      find.artTag
-    ),
+    featuredInFlashes: Thing.common.reverseReferenceList({
+      data: 'flashData',
+      refList: 'featuredTracks',
+    }),
   });
 
-  // This is a quick utility function for now, since the same code is reused in
-  // several places. Ideally it wouldn't be - we'd just reuse the `album`
-  // property - but support for that hasn't been coded yet :P
-  static findAlbum = (track, albumData) =>
-    albumData?.find((album) => album.tracks.includes(track));
-
-  // Another reused utility function. This one's logic is a bit more complicated.
-  static hasCoverArt(
-    track,
-    albumData,
-    coverArtistContribsByRef,
-    hasCoverArt
-  ) {
-    if (!empty(coverArtistContribsByRef)) {
-      return true;
-    }
+  static composite = {
+    // Early exits with a value inherited from the original release, if
+    // this track is a rerelease, and otherwise continues with no further
+    // dependencies provided. If allowOverride is true, then the continuation
+    // will also be called if the original release exposed the requested
+    // property as null.
+    inheritFromOriginalRelease({
+      property: originalProperty,
+      allowOverride = false,
+    }) {
+      return Thing.composite.from(`Track.composite.inheritFromOriginalRelease`, [
+        Track.composite.withOriginalRelease(),
+
+        {
+          dependencies: ['#originalRelease'],
+          compute({'#originalRelease': originalRelease}, continuation) {
+            if (!originalRelease) return continuation.raise();
+
+            const value = originalRelease[originalProperty];
+            if (allowOverride && value === null) return continuation.raise();
+
+            return continuation.exit(value);
+          },
+        },
+      ]);
+    },
 
-    const album = Track.findAlbum(track, albumData);
-    if (album && !empty(album.trackCoverArtistContribsByRef)) {
-      return true;
-    }
+    // Gets the track's album. Unless earlyExitIfNotFound is overridden false,
+    // this will early exit with null in two cases - albumData being missing,
+    // or not including an album whose .tracks array includes this track.
+    withAlbum({to = '#album', earlyExitIfNotFound = true} = {}) {
+      return Thing.composite.from(`Track.composite.withAlbum`, [
+        Thing.composite.withResultOfAvailabilityCheck({
+          fromDependency: 'albumData',
+          mode: 'empty',
+          to: '#albumDataAvailability',
+        }),
+
+        {
+          dependencies: ['#albumDataAvailability'],
+          options: {earlyExitIfNotFound},
+          mapContinuation: {to},
+
+          compute: ({
+            '#albumDataAvailability': albumDataAvailability,
+            '#options': {earlyExitIfNotFound},
+          }, continuation) =>
+            (albumDataAvailability
+              ? continuation()
+              : (earlyExitIfNotFound
+                  ? continuation.exit(null)
+                  : continuation.raise({to: null}))),
+        },
 
-    return false;
-  }
+        {
+          dependencies: ['this', 'albumData'],
+          compute: ({this: track, albumData}, continuation) =>
+            continuation({
+              '#album':
+                albumData.find(album => album.tracks.includes(track)),
+            }),
+        },
 
-  static hasUniqueCoverArt(
-    track,
-    albumData,
-    coverArtistContribsByRef,
-    hasCoverArt
-  ) {
-    if (!empty(coverArtistContribsByRef)) {
-      return true;
-    }
+        {
+          dependencies: ['#album'],
+          options: {earlyExitIfNotFound},
+          mapContinuation: {to},
+          compute: ({
+            '#album': album,
+            '#options': {earlyExitIfNotFound},
+          }, continuation) =>
+            (album
+              ? continuation.raise({to: album})
+              : (earlyExitIfNotFound
+                  ? continuation.exit(null)
+                  : continuation.raise({to: album}))),
+        },
+      ]);
+    },
 
-    if (hasCoverArt === false) {
-      return false;
-    }
+    // Gets a single property from this track's album, providing it as the same
+    // property name prefixed with '#album.' (by default). If the track's album
+    // isn't available, and earlyExitIfNotFound hasn't been set, the property
+    // will be provided as null.
+    withAlbumProperty(property, {
+      to = '#album.' + property,
+      earlyExitIfNotFound = false,
+    } = {}) {
+      return Thing.composite.from(`Track.composite.withAlbumProperty`, [
+        Track.composite.withAlbum({earlyExitIfNotFound}),
+
+        {
+          dependencies: ['#album'],
+          options: {property},
+          mapContinuation: {to},
+
+          compute: ({
+            '#album': album,
+            '#options': {property},
+          }, continuation) =>
+            (album
+              ? continuation.raise({to: album[property]})
+              : continuation.raise({to: null})),
+        },
+      ]);
+    },
 
-    const album = Track.findAlbum(track, albumData);
-    if (album && !empty(album.trackCoverArtistContribsByRef)) {
-      return true;
-    }
+    // Gets the listed properties from this track's album, providing them as
+    // dependencies (by default) with '#album.' prefixed before each property
+    // name. If the track's album isn't available, and earlyExitIfNotFound
+    // hasn't been set, the same dependency names will be provided as null.
+    withAlbumProperties({
+      properties,
+      prefix = '#album',
+      earlyExitIfNotFound = false,
+    }) {
+      return Thing.composite.from(`Track.composite.withAlbumProperties`, [
+        Track.composite.withAlbum({earlyExitIfNotFound}),
+
+        {
+          dependencies: ['#album'],
+          options: {properties, prefix},
+
+          compute({
+            '#album': album,
+            '#options': {properties, prefix},
+          }, continuation) {
+            const raise = {};
+
+            if (album) {
+              for (const property of properties) {
+                raise[prefix + '.' + property] = album[property];
+              }
+            } else {
+              for (const property of properties) {
+                raise[prefix + '.' + property] = null;
+              }
+            }
+
+            return continuation.raise(raise);
+          },
+        },
+      ]);
+    },
 
-    return false;
-  }
+    // Gets the track section containing this track from its album's track list.
+    // Unless earlyExitIfNotFound is overridden false, this will early exit if
+    // the album can't be found or if none of its trackSections includes the
+    // track for some reason.
+    withContainingTrackSection({
+      to = '#trackSection',
+      earlyExitIfNotFound = true,
+    } = {}) {
+      return Thing.composite.from(`Track.composite.withContainingTrackSection`, [
+        Track.composite.withAlbumProperty('trackSections', {earlyExitIfNotFound}),
+
+        {
+          dependencies: ['this', '#album.trackSections'],
+          mapContinuation: {to},
+
+          compute({
+            this: track,
+            '#album.trackSections': trackSections,
+          }, continuation) {
+            if (!trackSections) {
+              return continuation.raise({to: null});
+            }
+
+            const trackSection =
+              trackSections.find(({tracks}) => tracks.includes(track));
+
+            if (trackSection) {
+              return continuation.raise({to: trackSection});
+            } else if (earlyExitIfNotFound) {
+              return continuation.exit(null);
+            } else {
+              return continuation.raise({to: null});
+            }
+          },
+        },
+      ]);
+    },
 
-  static inheritFromOriginalRelease(
-    originalProperty,
-    originalMissingValue,
-    ownPropertyDescriptor
-  ) {
-    return {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: [
-          ...ownPropertyDescriptor.expose.dependencies,
-          'originalReleaseTrackByRef',
-          'trackData',
-        ],
-
-        compute(dependencies) {
-          const {
-            originalReleaseTrackByRef,
-            trackData,
-          } = dependencies;
+    // Just includes the original release of this track as a dependency.
+    // If this track isn't a rerelease, then it'll provide null, unless the
+    // {selfIfOriginal} option is set, in which case it'll provide this track
+    // itself. Note that this will early exit if the original release is
+    // specified by reference and that reference doesn't resolve to anything.
+    // Outputs to '#originalRelease' by default.
+    withOriginalRelease({
+      to = '#originalRelease',
+      selfIfOriginal = false,
+    } = {}) {
+      return Thing.composite.from(`Track.composite.withOriginalRelease`, [
+        Thing.composite.withResolvedReference({
+          ref: 'originalReleaseTrackByRef',
+          data: 'trackData',
+          to: '#originalRelease',
+          find: find.track,
+          earlyExitIfNotFound: true,
+        }),
+
+        {
+          dependencies: ['this', '#originalRelease'],
+          options: {selfIfOriginal},
+          mapContinuation: {to},
+          compute: ({
+            this: track,
+            '#originalRelease': originalRelease,
+            '#options': {selfIfOriginal},
+          }, continuation) =>
+            continuation.raise({
+              to:
+                (originalRelease ??
+                  (selfIfOriginal
+                    ? track
+                    : null)),
+            }),
+        },
+      ]);
+    },
 
-          if (originalReleaseTrackByRef) {
-            if (!trackData) return originalMissingValue;
-            const original = find.track(originalReleaseTrackByRef, trackData, {mode: 'quiet'});
-            if (!original) return originalMissingValue;
-            return original[originalProperty];
-          }
+    // The algorithm for checking if a track has unique cover art is used in a
+    // couple places, so it's defined in full as a compositional step.
+    withHasUniqueCoverArt({
+      to = '#hasUniqueCoverArt',
+    } = {}) {
+      return Thing.composite.from(`Track.composite.withHasUniqueCoverArt`, [
+        {
+          dependencies: ['disableUniqueCoverArt'],
+          mapContinuation: {to},
+          compute: ({disableUniqueCoverArt}, continuation) =>
+            (disableUniqueCoverArt
+              ? continuation.raise({to: false})
+              : continuation()),
+        },
 
-          return ownPropertyDescriptor.expose.compute(dependencies);
+        Thing.composite.withResolvedContribs({
+          from: 'coverArtistContribsByRef',
+          to: '#coverArtistContribs',
+        }),
+
+        {
+          dependencies: ['#coverArtistContribs'],
+          mapContinuation: {to},
+          compute: ({'#coverArtistContribs': contribsFromTrack}, continuation) =>
+            (empty(contribsFromTrack)
+              ? continuation()
+              : continuation.raise({to: true})),
         },
-      },
-    };
-  }
 
-  [inspect.custom]() {
-    const base = Thing.prototype[inspect.custom].apply(this);
+        Track.composite.withAlbumProperty('trackCoverArtistContribs'),
 
-    const rereleasePart =
-      (this.originalReleaseTrackByRef
-        ? `${color.yellow('[rerelease]')} `
-        : ``);
+        {
+          dependencies: ['#album.trackCoverArtistContribs'],
+          mapContinuation: {to},
+          compute: ({'#album.trackCoverArtistContribs': contribsFromAlbum}, continuation) =>
+            (empty(contribsFromAlbum)
+              ? continuation.raise({to: false})
+              : continuation.raise({to: true})),
+        },
+      ]);
+    },
 
-    const {album, dataSourceAlbum} = this;
+    trackReverseReferenceList(refListProperty) {
+      return Thing.composite.from(`Track.composite.trackReverseReferenceList`, [
+        Thing.composite.withReverseReferenceList({
+          data: 'trackData',
+          refList: refListProperty,
+          originalTracksOnly: true,
+        }),
+
+        {
+          flags: {expose: true},
+          expose: {
+            dependencies: ['#reverseReferenceList'],
+            compute: ({'#reverseReferenceList': reverseReferenceList}) =>
+              reverseReferenceList.filter(track => !track.originalReleaseTrack),
+          },
+        },
+      ]);
+    },
+  };
 
-    const albumName =
-      (album
-        ? album.name
-        : dataSourceAlbum?.name);
+  [inspect.custom](depth) {
+    const parts = [];
 
-    const albumIndex =
-      albumName &&
-        (album
-          ? album.tracks.indexOf(this)
-          : dataSourceAlbum.tracks.indexOf(this));
+    parts.push(Thing.prototype[inspect.custom].apply(this));
 
-    const trackNum =
-      albumName &&
+    if (this.originalReleaseTrackByRef) {
+      parts.unshift(`${color.yellow('[rerelease]')} `);
+    }
+
+    let album;
+    if (depth >= 0 && (album = this.album ?? this.dataSourceAlbum)) {
+      const albumName = album.name;
+      const albumIndex = album.tracks.indexOf(this);
+      const trackNum =
         (albumIndex === -1
           ? '#?'
           : `#${albumIndex + 1}`);
+      parts.push(` (${color.yellow(trackNum)} in ${color.green(albumName)})`);
+    }
 
-    const albumPart =
-      albumName
-        ? ` (${color.yellow(trackNum)} in ${color.green(albumName)})`
-        : ``;
-
-    return rereleasePart + base + albumPart;
+    return parts.join('');
   }
 }