« 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/album.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/things/album.js')
-rw-r--r--src/data/things/album.js367
1 files changed, 223 insertions, 144 deletions
diff --git a/src/data/things/album.js b/src/data/things/album.js
index c012c243..c0042ae2 100644
--- a/src/data/things/album.js
+++ b/src/data/things/album.js
@@ -1,163 +1,242 @@
-import {empty} from '#sugar';
 import find from '#find';
-
-import Thing from './thing.js';
+import {empty, stitchArrays} from '#sugar';
+import {isDate, isTrackSectionList} from '#validators';
+import {filterMultipleArrays} from '#wiki-data';
+
+import {
+  exitWithoutDependency,
+  exitWithoutUpdateValue,
+  exposeDependency,
+  exposeUpdateValueOrContinue,
+  input,
+  fillMissingListItems,
+  withFlattenedArray,
+  withPropertiesFromList,
+  withUnflattenedArray,
+} from '#composite';
+
+import Thing, {
+  additionalFiles,
+  commentary,
+  color,
+  commentatorArtists,
+  contribsPresent,
+  contributionList,
+  dimensions,
+  directory,
+  exitWithoutContribs,
+  fileExtension,
+  flag,
+  name,
+  referenceList,
+  simpleDate,
+  simpleString,
+  urls,
+  wikiData,
+  withResolvedReferenceList,
+} from './thing.js';
 
 export class Album extends Thing {
   static [Thing.referenceType] = 'album';
 
-  static [Thing.getPropertyDescriptors] = ({
-    ArtTag,
-    Artist,
-    Group,
-    Track,
-
-    validators: {
-      isDate,
-      isDimensions,
-      isTrackSectionList,
-    },
-  }) => ({
+  static [Thing.getPropertyDescriptors] = ({ArtTag, Artist, Group, Track}) => ({
     // Update & expose
 
-    name: Thing.common.name('Unnamed Album'),
-    color: Thing.common.color(),
-    directory: Thing.common.directory(),
-    urls: Thing.common.urls(),
-
-    date: Thing.common.simpleDate(),
-    trackArtDate: Thing.common.simpleDate(),
-    dateAddedToWiki: Thing.common.simpleDate(),
-
-    coverArtDate: {
-      flags: {update: true, expose: true},
-
-      update: {validate: isDate},
-
-      expose: {
-        dependencies: ['date', 'coverArtistContribsByRef'],
-        transform: (coverArtDate, {
-          coverArtistContribsByRef,
-          date,
-        }) =>
-          (!empty(coverArtistContribsByRef)
-            ? coverArtDate ?? date ?? null
-            : null),
-      },
-    },
-
-    artistContribsByRef: Thing.common.contribsByRef(),
-    coverArtistContribsByRef: Thing.common.contribsByRef(),
-    trackCoverArtistContribsByRef: Thing.common.contribsByRef(),
-    wallpaperArtistContribsByRef: Thing.common.contribsByRef(),
-    bannerArtistContribsByRef: Thing.common.contribsByRef(),
-
-    groupsByRef: Thing.common.referenceList(Group),
-    artTagsByRef: Thing.common.referenceList(ArtTag),
-
-    trackSections: {
-      flags: {update: true, expose: true},
-
-      update: {
-        validate: isTrackSectionList,
+    name: name('Unnamed Album'),
+    color: color(),
+    directory: directory(),
+    urls: urls(),
+
+    date: simpleDate(),
+    trackArtDate: simpleDate(),
+    dateAddedToWiki: simpleDate(),
+
+    coverArtDate: [
+      exitWithoutContribs({contribs: 'coverArtistContribs'}),
+      exposeUpdateValueOrContinue(),
+      exposeDependency({
+        dependency: 'date',
+        update: {validate: isDate},
+      }),
+    ],
+
+    coverArtFileExtension: [
+      exitWithoutContribs({contribs: 'coverArtistContribs'}),
+      fileExtension('jpg'),
+    ],
+
+    trackCoverArtFileExtension: fileExtension('jpg'),
+
+    wallpaperFileExtension: [
+      exitWithoutContribs({contribs: 'wallpaperArtistContribs'}),
+      fileExtension('jpg'),
+    ],
+
+    bannerFileExtension: [
+      exitWithoutContribs({contribs: 'bannerArtistContribs'}),
+      fileExtension('jpg'),
+    ],
+
+    wallpaperStyle: [
+      exitWithoutContribs({contribs: 'wallpaperArtistContribs'}),
+      simpleString(),
+    ],
+
+    bannerStyle: [
+      exitWithoutContribs({contribs: 'bannerArtistContribs'}),
+      simpleString(),
+    ],
+
+    bannerDimensions: [
+      exitWithoutContribs({contribs: 'bannerArtistContribs'}),
+      dimensions(),
+    ],
+
+    hasTrackNumbers: flag(true),
+    isListedOnHomepage: flag(true),
+    isListedInGalleries: flag(true),
+
+    commentary: commentary(),
+    additionalFiles: additionalFiles(),
+
+    trackSections: [
+      exitWithoutDependency({dependency: 'trackData', value: []}),
+      exitWithoutUpdateValue({value: [], mode: 'empty'}),
+
+      withPropertiesFromList({
+        list: input.updateValue(),
+        prefix: input.value('#sections'),
+        properties: input.value([
+          'tracks',
+          'dateOriginallyReleased',
+          'isDefaultTrackSection',
+          'color',
+        ]),
+      }),
+
+      fillMissingListItems({list: '#sections.tracks', value: []}),
+      fillMissingListItems({list: '#sections.isDefaultTrackSection', value: false}),
+      fillMissingListItems({list: '#sections.color', dependency: 'color'}),
+
+      withFlattenedArray({
+        from: '#sections.tracks',
+        into: '#trackRefs',
+        intoIndices: '#sections.startIndex',
+      }),
+
+      {
+        dependencies: ['#trackRefs'],
+        compute: ({'#trackRefs': tracks}, continuation) => {
+          console.log(tracks);
+          return continuation();
+        }
       },
 
-      expose: {
-        dependencies: ['color', 'trackData'],
-        transform(trackSections, {
-          color: albumColor,
-          trackData,
-        }) {
-          let startIndex = 0;
-          return trackSections?.map(section => ({
-            name: section.name ?? null,
-            color: section.color ?? albumColor ?? null,
-            dateOriginallyReleased: section.dateOriginallyReleased ?? null,
-            isDefaultTrackSection: section.isDefaultTrackSection ?? false,
-
-            startIndex: (
-              startIndex += section.tracksByRef.length,
-              startIndex - section.tracksByRef.length
-            ),
-
-            tracksByRef: section.tracksByRef ?? [],
-            tracks:
-              (trackData && section.tracksByRef
-                ?.map(ref => find.track(ref, trackData, {mode: 'quiet'}))
-                .filter(Boolean)) ??
-              [],
-          }));
+      withResolvedReferenceList({
+        list: '#trackRefs',
+        data: 'trackData',
+        notFoundMode: 'null',
+        find: find.track,
+        into: '#tracks',
+      }),
+
+      withUnflattenedArray({
+        from: '#tracks',
+        fromIndices: '#sections.startIndex',
+        into: '#sections.tracks',
+      }),
+
+      {
+        flags: {update: true, expose: true},
+
+        update: {validate: isTrackSectionList},
+
+        expose: {
+          dependencies: [
+            '#sections.tracks',
+            '#sections.color',
+            '#sections.dateOriginallyReleased',
+            '#sections.isDefaultTrackSection',
+            '#sections.startIndex',
+          ],
+
+          transform(trackSections, {
+            '#sections.tracks': tracks,
+            '#sections.color': color,
+            '#sections.dateOriginallyReleased': dateOriginallyReleased,
+            '#sections.isDefaultTrackSection': isDefaultTrackSection,
+            '#sections.startIndex': startIndex,
+          }) {
+            filterMultipleArrays(
+              tracks, color, dateOriginallyReleased, isDefaultTrackSection, startIndex,
+              tracks => !empty(tracks));
+
+            return stitchArrays({
+              tracks,
+              color,
+              dateOriginallyReleased,
+              isDefaultTrackSection,
+              startIndex,
+            });
+          }
         },
       },
-    },
+    ],
+
+    artistContribs: contributionList(),
+    coverArtistContribs: contributionList(),
+    trackCoverArtistContribs: contributionList(),
+    wallpaperArtistContribs: contributionList(),
+    bannerArtistContribs: contributionList(),
+
+    groups: referenceList({
+      class: Group,
+      find: find.group,
+      data: 'groupData',
+    }),
+
+    artTags: referenceList({
+      class: ArtTag,
+      find: find.artTag,
+      data: 'artTagData',
+    }),
 
-    coverArtFileExtension: Thing.common.fileExtension('jpg'),
-    trackCoverArtFileExtension: Thing.common.fileExtension('jpg'),
+    // Update only
 
-    wallpaperStyle: Thing.common.simpleString(),
-    wallpaperFileExtension: Thing.common.fileExtension('jpg'),
+    artistData: wikiData(Artist),
+    artTagData: wikiData(ArtTag),
+    groupData: wikiData(Group),
+    trackData: wikiData(Track),
 
-    bannerStyle: Thing.common.simpleString(),
-    bannerFileExtension: Thing.common.fileExtension('jpg'),
-    bannerDimensions: {
-      flags: {update: true, expose: true},
-      update: {validate: isDimensions},
-    },
+    // Expose only
 
-    hasTrackNumbers: Thing.common.flag(true),
-    isListedOnHomepage: Thing.common.flag(true),
-    isListedInGalleries: Thing.common.flag(true),
+    commentatorArtists: commentatorArtists(),
 
-    commentary: Thing.common.commentary(),
-    additionalFiles: Thing.common.additionalFiles(),
+    hasCoverArt: contribsPresent({contribs: 'coverArtistContribs'}),
+    hasWallpaperArt: contribsPresent({contribs: 'wallpaperArtistContribs'}),
+    hasBannerArt: contribsPresent({contribs: 'bannerArtistContribs'}),
 
-    // Update only
+    tracks: [
+      exitWithoutDependency({dependency: 'trackData', value: []}),
+      exitWithoutDependency({dependency: 'trackSections', mode: 'empty', value: []}),
 
-    artistData: Thing.common.wikiData(Artist),
-    artTagData: Thing.common.wikiData(ArtTag),
-    groupData: Thing.common.wikiData(Group),
-    trackData: Thing.common.wikiData(Track),
+      {
+        dependencies: ['trackSections'],
+        compute: ({trackSections}, continuation) =>
+          continuation({
+            '#trackRefs': trackSections
+              .flatMap(section => section.tracks ?? []),
+          }),
+      },
 
-    // Expose only
+      withResolvedReferenceList({
+        list: '#trackRefs',
+        data: 'trackData',
+        find: find.track,
+      }),
 
-    artistContribs: Thing.common.dynamicContribs('artistContribsByRef'),
-    coverArtistContribs: Thing.common.dynamicContribs('coverArtistContribsByRef'),
-    trackCoverArtistContribs: Thing.common.dynamicContribs('trackCoverArtistContribsByRef'),
-    wallpaperArtistContribs: Thing.common.dynamicContribs('wallpaperArtistContribsByRef'),
-    bannerArtistContribs: Thing.common.dynamicContribs('bannerArtistContribsByRef'),
-
-    commentatorArtists: Thing.common.commentatorArtists(),
-
-    hasCoverArt: Thing.common.contribsPresent('coverArtistContribsByRef'),
-    hasWallpaperArt: Thing.common.contribsPresent('wallpaperArtistContribsByRef'),
-    hasBannerArt: Thing.common.contribsPresent('bannerArtistContribsByRef'),
-
-    tracks: {
-      flags: {expose: true},
-
-      expose: {
-        dependencies: ['trackSections', 'trackData'],
-        compute: ({trackSections, trackData}) =>
-          trackSections && trackData
-            ? trackSections
-                .flatMap((section) => section.tracksByRef ?? [])
-                .map((ref) => find.track(ref, trackData, {mode: 'quiet'}))
-                .filter(Boolean)
-            : [],
-      },
-    },
-
-    groups: Thing.common.dynamicThingsFromReferenceList(
-      'groupsByRef',
-      'groupData',
-      find.group
-    ),
-
-    artTags: Thing.common.dynamicThingsFromReferenceList(
-      'artTagsByRef',
-      'artTagData',
-      find.artTag
-    ),
+      exposeDependency({dependency: '#resolvedReferenceList'}),
+    ],
   });
 
   static [Thing.getSerializeDescriptors] = ({
@@ -202,9 +281,9 @@ export class Album extends Thing {
 
 export class TrackSectionHelper extends Thing {
   static [Thing.getPropertyDescriptors] = () => ({
-    name: Thing.common.name('Unnamed Track Group'),
-    color: Thing.common.color(),
-    dateOriginallyReleased: Thing.common.simpleDate(),
-    isDefaultTrackGroup: Thing.common.flag(false),
+    name: name('Unnamed Track Group'),
+    color: color(),
+    dateOriginallyReleased: simpleDate(),
+    isDefaultTrackGroup: flag(false),
   })
 }