From f39164ed44fe5c86f1f1911514d38a5549e51f92 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 8 Sep 2023 16:17:05 -0300 Subject: data: rearrange track properties --- src/data/things/track.js | 153 +++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 78 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index 8263d399..0cd39dca 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -62,12 +62,6 @@ export class Track extends Thing { urls: urls(), dateFirstReleased: simpleDate(), - artTags: referenceList({ - class: ArtTag, - find: find.artTag, - data: 'artTagData', - }), - color: compositeFrom(`Track.color`, [ exposeUpdateValueOrContinue(), withContainingTrackSection(), @@ -139,90 +133,28 @@ export class Track extends Thing { }), ]), + commentary: commentary(), + lyrics: simpleString(), + + additionalFiles: additionalFiles(), + sheetMusicFiles: additionalFiles(), + midiProjectFiles: additionalFiles(), + originalReleaseTrack: singleReference({ class: Track, find: find.track, data: 'trackData', }), - // 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 - // (i.e. a track may dynamically be moved from one album to another, at - // which point dataSourceAlbum refers to where it was originally from, and is - // not generally relevant information). It's also not guaranteed that - // dataSourceAlbum is available (depending on the Track creator to optionally - // provide this property's update value). + // Internal use only - for directly identifying an album inside a track's + // util.inspect display, if it isn't indirectly available (by way of being + // included in an album's track list). dataSourceAlbum: singleReference({ class: Album, find: find.album, data: 'albumData', }), - commentary: commentary(), - lyrics: simpleString(), - additionalFiles: additionalFiles(), - sheetMusicFiles: additionalFiles(), - midiProjectFiles: additionalFiles(), - - // Update only - - albumData: wikiData(Album), - artistData: wikiData(Artist), - artTagData: wikiData(ArtTag), - flashData: wikiData(Flash), - trackData: wikiData(Track), - - // Expose only - - commentatorArtists: commentatorArtists(), - - album: compositeFrom(`Track.album`, [ - withAlbum(), - exposeDependency({dependency: '#album'}), - ]), - - date: compositeFrom(`Track.date`, [ - exposeDependencyOrContinue({dependency: 'dateFirstReleased'}), - withAlbumProperty({property: 'date'}), - exposeDependency({dependency: '#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: compositeFrom(`Track.hasUniqueCoverArt`, [ - withHasUniqueCoverArt(), - exposeDependency({dependency: '#hasUniqueCoverArt'}), - ]), - - otherReleases: compositeFrom(`Track.otherReleases`, [ - exitWithoutDependency({dependency: 'trackData', mode: 'empty'}), - 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)), - }, - }, - ]), - artistContribs: compositeFrom(`Track.artistContribs`, [ inheritFromOriginalRelease({property: 'artistContribs'}), @@ -283,6 +215,71 @@ export class Track extends Thing { }), ]), + artTags: referenceList({ + class: ArtTag, + find: find.artTag, + data: 'artTagData', + }), + + // Update only + + albumData: wikiData(Album), + artistData: wikiData(Artist), + artTagData: wikiData(ArtTag), + flashData: wikiData(Flash), + trackData: wikiData(Track), + + // Expose only + + commentatorArtists: commentatorArtists(), + + album: compositeFrom(`Track.album`, [ + withAlbum(), + exposeDependency({dependency: '#album'}), + ]), + + date: compositeFrom(`Track.date`, [ + exposeDependencyOrContinue({dependency: 'dateFirstReleased'}), + withAlbumProperty({property: 'date'}), + exposeDependency({dependency: '#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: compositeFrom(`Track.hasUniqueCoverArt`, [ + withHasUniqueCoverArt(), + exposeDependency({dependency: '#hasUniqueCoverArt'}), + ]), + + otherReleases: compositeFrom(`Track.otherReleases`, [ + exitWithoutDependency({dependency: 'trackData', mode: 'empty'}), + 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)), + }, + }, + ]), + // 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 // generally relevant from the perspective of the tracks being referenced. -- cgit 1.3.0-6-gf8a5 From cd3e2ae7384d82f0f2758beb0ae38ce0fe9f5e09 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 8 Sep 2023 16:25:22 -0300 Subject: data: duration utility --- src/data/things/track.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index 0cd39dca..53798cda 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -19,7 +19,6 @@ import { isColor, isContributionList, isDate, - isDuration, isFileExtension, } from '#validators'; @@ -31,6 +30,7 @@ import Thing, { commentatorArtists, contributionList, directory, + duration, flag, name, referenceList, @@ -54,11 +54,7 @@ export class Track extends Thing { name: name('Unnamed Track'), directory: directory(), - duration: { - flags: {update: true, expose: true}, - update: {validate: isDuration}, - }, - + duration: duration(), urls: urls(), dateFirstReleased: simpleDate(), -- cgit 1.3.0-6-gf8a5 From c82784ebb4e5141bfe97664f3252303b3e833863 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 9 Sep 2023 08:13:44 -0300 Subject: data: withPropertyFrom{Object,List}, fillMissingListItems utils --- src/data/things/track.js | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index 53798cda..a307fda9 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -11,6 +11,7 @@ import { exposeDependency, exposeDependencyOrContinue, exposeUpdateValueOrContinue, + withPropertyFromObject, withResultOfAvailabilityCheck, withUpdateValueAsDependency, } from '#composite'; @@ -430,20 +431,7 @@ function withAlbumProperty({ }) { return compositeFrom(`withAlbumProperty`, [ withAlbum({notFoundMode}), - - { - dependencies: ['#album'], - options: {property}, - mapContinuation: {into}, - - compute: ({ - '#album': album, - '#options': {property}, - }, continuation) => - (album - ? continuation.raise({into: album[property]}) - : continuation.raise({into: null})), - }, + withPropertyFromObject({object: '#album', property, into}), ]); } -- cgit 1.3.0-6-gf8a5 From 57d07a308dfee6d16b49f7c009853b1789597e82 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 9 Sep 2023 08:17:44 -0300 Subject: data: withAlbumProperty -> withPropertyFromAlbum Also remove withAlbumProperties, since it's not used anywhere and mostly serves as reference code. --- src/data/things/track.js | 59 ++++++++---------------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index a307fda9..5e553b48 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -75,7 +75,7 @@ export class Track extends Thing { : continuation()), }, - withAlbumProperty({property: 'color'}), + withPropertyFromAlbum({property: 'color'}), exposeDependency({ dependency: '#album.color', @@ -103,7 +103,7 @@ export class Track extends Thing { exposeUpdateValueOrContinue(), // Expose album's trackCoverArtFileExtension if no update value set. - withAlbumProperty({property: 'trackCoverArtFileExtension'}), + withPropertyFromAlbum({property: 'trackCoverArtFileExtension'}), exposeDependencyOrContinue({dependency: '#album.trackCoverArtFileExtension'}), // Fallback to 'jpg'. @@ -123,7 +123,7 @@ export class Track extends Thing { exposeUpdateValueOrContinue(), - withAlbumProperty({property: 'trackArtDate'}), + withPropertyFromAlbum({property: 'trackArtDate'}), exposeDependency({ dependency: '#album.trackArtDate', update: {validate: isDate}, @@ -159,7 +159,7 @@ export class Track extends Thing { withResolvedContribs({from: '#updateValue', into: '#artistContribs'}), exposeDependencyOrContinue({dependency: '#artistContribs'}), - withAlbumProperty({property: 'artistContribs'}), + withPropertyFromAlbum({property: 'artistContribs'}), exposeDependency({ dependency: '#album.artistContribs', update: {validate: isContributionList}, @@ -187,7 +187,7 @@ export class Track extends Thing { withResolvedContribs({from: '#updateValue', into: '#coverArtistContribs'}), exposeDependencyOrContinue({dependency: '#coverArtistContribs'}), - withAlbumProperty({property: 'trackCoverArtistContribs'}), + withPropertyFromAlbum({property: 'trackCoverArtistContribs'}), exposeDependency({ dependency: '#album.trackCoverArtistContribs', update: {validate: isContributionList}, @@ -237,7 +237,7 @@ export class Track extends Thing { date: compositeFrom(`Track.date`, [ exposeDependencyOrContinue({dependency: 'dateFirstReleased'}), - withAlbumProperty({property: 'date'}), + withPropertyFromAlbum({property: 'date'}), exposeDependency({dependency: '#album.date'}), ]), @@ -424,56 +424,17 @@ function withAlbum({ // property name prefixed with '#album.' (by default). If the track's album // isn't available, then by default, the property will be provided as null; // set {notFoundMode: 'exit'} to early exit instead. -function withAlbumProperty({ +function withPropertyFromAlbum({ property, into = '#album.' + property, notFoundMode = 'null', }) { - return compositeFrom(`withAlbumProperty`, [ + return compositeFrom(`withPropertyFromAlbum`, [ withAlbum({notFoundMode}), withPropertyFromObject({object: '#album', property, into}), ]); } -// 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, then by default, the same -// dependency names will be provided as null; set {notFoundMode: 'exit'} -// to early exit instead. -function withAlbumProperties({ - properties, - prefix = '#album', - notFoundMode = 'null', -}) { - return compositeFrom(`withAlbumProperties`, [ - withAlbum({notFoundMode}), - - { - 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); - }, - }, - ]); -} - // Gets the track section containing this track from its album's track list. // If notFoundMode is set to 'exit', this will early exit if the album can't be // found or if none of its trackSections includes the track for some reason. @@ -486,7 +447,7 @@ function withContainingTrackSection({ } return compositeFrom(`withContainingTrackSection`, [ - withAlbumProperty({property: 'trackSections', notFoundMode}), + withPropertyFromAlbum({property: 'trackSections', notFoundMode}), { dependencies: ['this', '#album.trackSections'], @@ -585,7 +546,7 @@ function withHasUniqueCoverArt({ : continuation.raise({into: true})), }, - withAlbumProperty({property: 'trackCoverArtistContribs'}), + withPropertyFromAlbum({property: 'trackCoverArtistContribs'}), { dependencies: ['#album.trackCoverArtistContribs'], -- cgit 1.3.0-6-gf8a5 From ceaed5fef3ce2c5d59a6606a6318164b93294f2b Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 9 Sep 2023 09:01:09 -0300 Subject: data: clean up some track property implementations --- src/data/things/track.js | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index 5e553b48..25d316eb 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -61,22 +61,12 @@ export class Track extends Thing { color: compositeFrom(`Track.color`, [ exposeUpdateValueOrContinue(), - withContainingTrackSection(), - { - 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()), - }, + withContainingTrackSection(), + withPropertyFromObject({object: '#trackSection', property: 'color'}), + exposeDependencyOrContinue({dependency: '#trackSection.color'}), withPropertyFromAlbum({property: 'color'}), - exposeDependency({ dependency: '#album.color', update: {validate: isColor}, @@ -94,19 +84,13 @@ export class Track extends Thing { // of the album's main artwork. It does inherit trackCoverArtFileExtension, // if present on the album. coverArtFileExtension: compositeFrom(`Track.coverArtFileExtension`, [ - // No cover art file extension if the track doesn't have unique artwork - // in the first place. - withHasUniqueCoverArt(), - exitWithoutDependency({dependency: '#hasUniqueCoverArt', mode: 'falsy'}), + exitWithoutUniqueCoverArt(), - // Expose custom coverArtFileExtension update value first. exposeUpdateValueOrContinue(), - // Expose album's trackCoverArtFileExtension if no update value set. withPropertyFromAlbum({property: 'trackCoverArtFileExtension'}), exposeDependencyOrContinue({dependency: '#album.trackCoverArtFileExtension'}), - // Fallback to 'jpg'. exposeConstant({ value: 'jpg', update: {validate: isFileExtension}, @@ -175,13 +159,7 @@ export class Track extends Thing { // typically varies by release and isn't defined by the musical qualities // of the track. coverArtistContribs: compositeFrom(`Track.coverArtistContribs`, [ - { - dependencies: ['disableUniqueCoverArt'], - compute: ({disableUniqueCoverArt}, continuation) => - (disableUniqueCoverArt - ? null - : continuation()), - }, + exitWithoutUniqueCoverArt(), withUpdateValueAsDependency(), withResolvedContribs({from: '#updateValue', into: '#coverArtistContribs'}), @@ -559,6 +537,21 @@ function withHasUniqueCoverArt({ ]); } +// Shorthand for checking if the track has unique cover art and exposing a +// fallback value if it isn't. +function exitWithoutUniqueCoverArt({ + value = null, +} = {}) { + return compositeFrom(`exitWithoutUniqueCoverArt`, [ + withHasUniqueCoverArt(), + exitWithoutDependency({ + dependency: '#hasUniqueCoverArt', + mode: 'falsy', + value, + }), + ]); +} + function trackReverseReferenceList({ property: refListProperty, }) { -- cgit 1.3.0-6-gf8a5 From 7b32066dd9629bbb220c2e2425b5294070b5a0db Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 9 Sep 2023 09:16:50 -0300 Subject: infra, data: cut unneeded boilerplate from top-level compositions --- src/data/things/track.js | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'src/data/things/track.js') diff --git a/src/data/things/track.js b/src/data/things/track.js index 25d316eb..a8d59023 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -59,7 +59,7 @@ export class Track extends Thing { urls: urls(), dateFirstReleased: simpleDate(), - color: compositeFrom(`Track.color`, [ + color: [ exposeUpdateValueOrContinue(), withContainingTrackSection(), @@ -71,7 +71,7 @@ export class Track extends Thing { dependency: '#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 @@ -83,7 +83,7 @@ export class Track extends Thing { // 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: compositeFrom(`Track.coverArtFileExtension`, [ + coverArtFileExtension: [ exitWithoutUniqueCoverArt(), exposeUpdateValueOrContinue(), @@ -95,13 +95,13 @@ export class Track extends Thing { value: '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: compositeFrom(`Track.coverArtDate`, [ + coverArtDate: [ withHasUniqueCoverArt(), exitWithoutDependency({dependency: '#hasUniqueCoverArt', mode: 'falsy'}), @@ -112,7 +112,7 @@ export class Track extends Thing { dependency: '#album.trackArtDate', update: {validate: isDate}, }), - ]), + ], commentary: commentary(), lyrics: simpleString(), @@ -136,7 +136,7 @@ export class Track extends Thing { data: 'albumData', }), - artistContribs: compositeFrom(`Track.artistContribs`, [ + artistContribs: [ inheritFromOriginalRelease({property: 'artistContribs'}), withUpdateValueAsDependency(), @@ -148,17 +148,17 @@ export class Track extends Thing { dependency: '#album.artistContribs', update: {validate: isContributionList}, }), - ]), + ], - contributorContribs: compositeFrom(`Track.contributorContribs`, [ + contributorContribs: [ inheritFromOriginalRelease({property: 'contributorContribs'}), contributionList(), - ]), + ], // 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: compositeFrom(`Track.coverArtistContribs`, [ + coverArtistContribs: [ exitWithoutUniqueCoverArt(), withUpdateValueAsDependency(), @@ -170,25 +170,25 @@ export class Track extends Thing { dependency: '#album.trackCoverArtistContribs', update: {validate: isContributionList}, }), - ]), + ], - referencedTracks: compositeFrom(`Track.referencedTracks`, [ + referencedTracks: [ inheritFromOriginalRelease({property: 'referencedTracks'}), referenceList({ class: Track, find: find.track, data: 'trackData', }), - ]), + ], - sampledTracks: compositeFrom(`Track.sampledTracks`, [ + sampledTracks: [ inheritFromOriginalRelease({property: 'sampledTracks'}), referenceList({ class: Track, find: find.track, data: 'trackData', }), - ]), + ], artTags: referenceList({ class: ArtTag, @@ -208,16 +208,16 @@ export class Track extends Thing { commentatorArtists: commentatorArtists(), - album: compositeFrom(`Track.album`, [ + album: [ withAlbum(), exposeDependency({dependency: '#album'}), - ]), + ], - date: compositeFrom(`Track.date`, [ + date: [ exposeDependencyOrContinue({dependency: 'dateFirstReleased'}), withPropertyFromAlbum({property: 'date'}), exposeDependency({dependency: '#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 @@ -226,12 +226,12 @@ export class Track extends Thing { // or a placeholder. (This property is named hasUniqueCoverArt instead of // the usual hasCoverArt to emphasize that it does not inherit from the // album.) - hasUniqueCoverArt: compositeFrom(`Track.hasUniqueCoverArt`, [ + hasUniqueCoverArt: [ withHasUniqueCoverArt(), exposeDependency({dependency: '#hasUniqueCoverArt'}), - ]), + ], - otherReleases: compositeFrom(`Track.otherReleases`, [ + otherReleases: [ exitWithoutDependency({dependency: 'trackData', mode: 'empty'}), withOriginalRelease({selfIfOriginal: true}), @@ -253,7 +253,7 @@ export class Track extends Thing { track.originalReleaseTrack === originalRelease)), }, }, - ]), + ], // 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 -- cgit 1.3.0-6-gf8a5