« 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
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/things')
-rw-r--r--src/data/things/thing.js20
-rw-r--r--src/data/things/track.js4
2 files changed, 17 insertions, 7 deletions
diff --git a/src/data/things/thing.js b/src/data/things/thing.js
index 2af06904..2adba5c4 100644
--- a/src/data/things/thing.js
+++ b/src/data/things/thing.js
@@ -1116,9 +1116,11 @@ export default class Thing extends CacheableObject {
 
     // Exposes a dependency exactly as it is; this is typically the base of a
     // composition which was created to serve as one property's descriptor.
-    // Since this serves as a base, specify {update: true} to indicate that
-    // the property as a whole updates (and some previous compositional step
-    // works with that update value).
+    // Since this serves as a base, specify a value for {update} to indicate
+    // that the property as a whole updates (and some previous compositional
+    // step works with that update value). Set {update: true} to only enable
+    // the update flag, or set update to an object to specify a descriptor
+    // (e.g. for custom value validation).
     //
     // Please note that this *doesn't* verify that the dependency exists, so
     // if you provide the wrong name or it hasn't been set by a previous
@@ -1127,17 +1129,23 @@ export default class Thing extends CacheableObject {
     //
     expose: (dependency, {update = false} = {}) => ({
       annotation: `Thing.composite.expose`,
-      flags: {expose: true, update},
+      flags: {expose: true, update: !!update},
 
       expose: {
         mapDependencies: {dependency},
         compute: ({dependency}) => dependency,
       },
+
+      update:
+        (typeof update === 'object'
+          ? update
+          : null),
     }),
 
     // Exposes the update value of an {update: true} property, or continues if
     // it's unavailable. By default, "unavailable" means value === null, but
-    // set {mode: 'empty'} to
+    // set {mode: 'empty'} to check with empty() instead, continuing for empty
+    // arrays also.
     exposeUpdateValueOrContinue({mode = 'null'} = {}) {
       if (mode !== 'null' && mode !== 'empty') {
         throw new TypeError(`Expected mode to be null or empty`);
@@ -1156,7 +1164,7 @@ export default class Thing extends CacheableObject {
                 : value === null);
 
             if (shouldContinue) {
-              return continuation();
+              return continuation(value);
             } else {
               return continuation.exit(value);
             }
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 15a48bb4..8d0a7ad4 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -47,7 +47,9 @@ export class Track extends Thing {
     color: Thing.composite.from(`Track.color`, [
       Thing.composite.exposeUpdateValueOrContinue(),
       Track.composite.withAlbumProperty('color'),
-      Thing.composite.expose('#album.color', {update: true}),
+      Thing.composite.expose('#album.color', {
+        update: {validate: isColor},
+      }),
     ]),
 
     // Disables presenting the track as though it has its own unique artwork.