« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/aggregate.js5
-rw-r--r--src/data/cacheable-object.js86
-rw-r--r--src/data/composite.js3
-rw-r--r--src/data/composite/data/helpers/property-from-helpers.js6
-rw-r--r--src/data/composite/things/album/withCoverArtDate.js6
-rw-r--r--src/data/composite/things/art-tag/withAllDescendantArtTags.js4
-rw-r--r--src/data/composite/things/artwork/withArtTags.js2
-rw-r--r--src/data/composite/things/artwork/withDate.js2
-rw-r--r--src/data/composite/things/content/withAnnotationParts.js4
-rw-r--r--src/data/composite/things/contribution/withContainingReverseContributionList.js2
-rw-r--r--src/data/composite/things/language/withStrings.js2
-rw-r--r--src/data/composite/things/track-section/withStartCountingFrom.js2
-rw-r--r--src/data/composite/things/track/alwaysReferenceByDirectory.js2
-rw-r--r--src/data/composite/things/track/withCoverArtistContribs.js2
-rw-r--r--src/data/composite/things/track/withHasUniqueCoverArt.js6
-rw-r--r--src/data/composite/things/track/withMainRelease.js2
-rw-r--r--src/data/composite/things/track/withMainReleaseTrack.js6
-rw-r--r--src/data/composite/things/track/withSuffixDirectoryFromAlbum.js8
-rw-r--r--src/data/composite/things/track/withTrackArtDate.js2
-rw-r--r--src/data/composite/wiki-data/gobbleSoupyFind.js2
-rw-r--r--src/data/composite/wiki-data/gobbleSoupyReverse.js2
-rw-r--r--src/data/composite/wiki-data/helpers/withSimpleDirectory.js2
-rw-r--r--src/data/composite/wiki-data/withDirectory.js4
-rw-r--r--src/data/composite/wiki-data/withResolvedContribs.js4
-rw-r--r--src/data/composite/wiki-properties/referencedArtworkList.js2
-rw-r--r--src/data/things/album.js70
-rw-r--r--src/data/things/content.js2
-rw-r--r--src/data/things/group.js12
-rw-r--r--src/data/things/index.js10
-rw-r--r--src/data/things/track.js6
-rw-r--r--src/data/things/wiki-info.js2
31 files changed, 152 insertions, 118 deletions
diff --git a/src/aggregate.js b/src/aggregate.js
index 3ff1846b..23a67d20 100644
--- a/src/aggregate.js
+++ b/src/aggregate.js
@@ -417,6 +417,7 @@ export function showAggregate(topError, {
   pathToFileURL = f => f,
   showTraces = true,
   showTranslucent = showTraces,
+  showClasses = showTraces,
   print = true,
 } = {}) {
   const getTranslucency = error =>
@@ -569,10 +570,10 @@ export function showAggregate(topError, {
       message || `(no message)`;
 
     const kindPart =
-      kind || `unnamed kind`;
+      kind || `unnamed class`;
 
     let headerPart =
-      (showTraces
+      (showClasses
         ? `[${kindPart}] ${messagePart}`
      : errors
         ? `[${messagePart}]`
diff --git a/src/data/cacheable-object.js b/src/data/cacheable-object.js
index 3aa3ecf7..dead009a 100644
--- a/src/data/cacheable-object.js
+++ b/src/data/cacheable-object.js
@@ -120,18 +120,14 @@ export default class CacheableObject {
 
           const dependencies = Object.create(null);
           for (const key of expose.dependencies ?? []) {
-            switch (key) {
-              case 'this':
-                dependencies.this = this;
-                break;
-
-              case 'thisProperty':
-                dependencies.thisProperty = property;
-                break;
-
-              default:
-                dependencies[key] = this[CacheableObject.updateValue][key];
-                break;
+            if (key === 'this') {
+              dependencies.this = this;
+            } else if (key === 'thisProperty') {
+              dependencies.thisProperty = property;
+            } else if (key.startsWith('_')) {
+              dependencies[key] = this[CacheableObject.updateValue][key.slice(1)];
+            } else {
+              dependencies[key] = this[key];
             }
           }
 
@@ -150,27 +146,11 @@ export default class CacheableObject {
       if (flags.expose) recordAsDependant: {
         const dependantsMap = this[CacheableObject.propertyDependants];
 
-        if (flags.update && expose?.transform) {
-          if (dependantsMap[property]) {
-            dependantsMap[property].push(property);
+        for (const dependency of dependenciesOf(property, propertyDescriptors)) {
+          if (dependantsMap[dependency]) {
+            dependantsMap[dependency].push(dependency);
           } else {
-            dependantsMap[property] = [property];
-          }
-        }
-
-        for (const dependency of expose?.dependencies ?? []) {
-          switch (dependency) {
-            case 'this':
-            case 'thisProperty':
-              continue;
-
-            default: {
-              if (dependantsMap[dependency]) {
-                dependantsMap[dependency].push(property);
-              } else {
-                dependantsMap[dependency] = [property];
-              }
-            }
+            dependantsMap[dependency] = [dependency];
           }
         }
       }
@@ -261,6 +241,7 @@ export class CacheableObjectPropertyValueError extends Error {
 }
 
 // good ol' module-scope utility functions
+
 function validatePropertyValue(property, oldValue, newValue, update) {
   try {
     const result = update.validate(newValue);
@@ -274,3 +255,44 @@ function validatePropertyValue(property, oldValue, newValue, update) {
       property, oldValue, newValue, {cause: caughtError});
   }
 }
+
+function* dependenciesOf(property, propertyDescriptors, cycle = []) {
+  const descriptor = propertyDescriptors[property];
+
+  if (descriptor?.flags?.update && descriptor?.expose?.transform) {
+    yield property;
+  }
+
+  const dependencies = descriptor?.expose?.dependencies;
+  if (!dependencies) return;
+
+  for (const dependency of dependencies) {
+    if (dependency === 'this') continue;
+    if (dependency === 'thisProperty') continue;
+
+    if (dependency.startsWith('_')) {
+      yield dependency.slice(1);
+      continue;
+    }
+
+    if (dependency === property) {
+      throw new Error(
+        `property ${dependency} directly depends on its own computed value`);
+    }
+
+    if (cycle.includes(dependency)) {
+      const subcycle = cycle.slice(cycle.indexOf(dependency));
+      const supercycle = cycle.slice(0, cycle.indexOf(dependency));
+      throw new Error(
+        `property ${dependency} indirectly depends on its own computed value\n` +
+        `  via: ` + subcycle.map(p => p + ' -> ').join('') + property + ' -> ' + dependency +
+        (supercycle.length
+          ? '\n   in: ' + supercycle.join(' -> ')
+          : ''));
+    }
+
+    cycle.push(property);
+    yield* dependenciesOf(dependency, propertyDescriptors, cycle);
+    cycle.pop();
+  }
+}
diff --git a/src/data/composite.js b/src/data/composite.js
index 3dad52f2..b70dbcaf 100644
--- a/src/data/composite.js
+++ b/src/data/composite.js
@@ -713,8 +713,9 @@ export function compositeFrom(description) {
       stepExposeDescriptions
         .flatMap(expose => expose?.dependencies ?? [])
         .map(dependency => {
-          if (typeof dependency === 'string')
+          if (typeof dependency === 'string') {
             return (dependency.startsWith('#') ? null : dependency);
+          }
 
           const tokenShape = getInputTokenShape(dependency);
           const tokenValue = getInputTokenValue(dependency);
diff --git a/src/data/composite/data/helpers/property-from-helpers.js b/src/data/composite/data/helpers/property-from-helpers.js
index 3d1e12a5..00251f3b 100644
--- a/src/data/composite/data/helpers/property-from-helpers.js
+++ b/src/data/composite/data/helpers/property-from-helpers.js
@@ -2,7 +2,11 @@ export function getOutputName({property, from, prefix = null}) {
   if (property && prefix) {
     return `${prefix}.${property}`;
   } else if (property && from) {
-    return `${from}.${property}`;
+    if (from.startsWith('_')) {
+      return `${from.slice(1)}.${property}`;
+    } else {
+      return `${from}.${property}`;
+    }
   } else {
     if (!property) throw new Error(`guard property outside getOutputName(), c'mon`);
     if (!from) throw new Error(`guard from in getOutputName(), c'mon`);
diff --git a/src/data/composite/things/album/withCoverArtDate.js b/src/data/composite/things/album/withCoverArtDate.js
index 978f566a..c006fab9 100644
--- a/src/data/composite/things/album/withCoverArtDate.js
+++ b/src/data/composite/things/album/withCoverArtDate.js
@@ -10,7 +10,7 @@ export default templateCompositeFrom({
   inputs: {
     from: input({
       validate: isDate,
-      defaultDependency: 'coverArtDate',
+      defaultDependency: '_coverArtDate',
       acceptsNull: true,
     }),
   },
@@ -19,8 +19,8 @@ export default templateCompositeFrom({
 
   steps: () => [
     withHasArtwork({
-      contribs: 'coverArtistContribs',
-      artworks: 'coverArtworks',
+      contribs: '_coverArtistContribs',
+      artworks: '_coverArtworks',
     }),
 
     raiseOutputWithoutDependency({
diff --git a/src/data/composite/things/art-tag/withAllDescendantArtTags.js b/src/data/composite/things/art-tag/withAllDescendantArtTags.js
index 795f96cd..934999a3 100644
--- a/src/data/composite/things/art-tag/withAllDescendantArtTags.js
+++ b/src/data/composite/things/art-tag/withAllDescendantArtTags.js
@@ -18,13 +18,13 @@ export default templateCompositeFrom({
 
   steps: () => [
     raiseOutputWithoutDependency({
-      dependency: 'directDescendantArtTags',
+      dependency: '_directDescendantArtTags',
       mode: input.value('empty'),
       output: input.value({'#allDescendantArtTags': []})
     }),
 
     withResolvedReferenceList({
-      list: 'directDescendantArtTags',
+      list: '_directDescendantArtTags',
       find: soupyFind.input('artTag'),
     }),
 
diff --git a/src/data/composite/things/artwork/withArtTags.js b/src/data/composite/things/artwork/withArtTags.js
index 1fed3c31..1f605d68 100644
--- a/src/data/composite/things/artwork/withArtTags.js
+++ b/src/data/composite/things/artwork/withArtTags.js
@@ -16,7 +16,7 @@ export default templateCompositeFrom({
     from: input({
       type: 'array',
       acceptsNull: true,
-      defaultDependency: 'artTags',
+      defaultDependency: '_artTags',
     }),
   },
 
diff --git a/src/data/composite/things/artwork/withDate.js b/src/data/composite/things/artwork/withDate.js
index 5e05b814..4666ff1b 100644
--- a/src/data/composite/things/artwork/withDate.js
+++ b/src/data/composite/things/artwork/withDate.js
@@ -8,7 +8,7 @@ export default templateCompositeFrom({
 
   inputs: {
     from: input({
-      defaultDependency: 'date',
+      defaultDependency: '_date',
       acceptsNull: true,
     }),
   },
diff --git a/src/data/composite/things/content/withAnnotationParts.js b/src/data/composite/things/content/withAnnotationParts.js
index 0c5a0294..15eb74a5 100644
--- a/src/data/composite/things/content/withAnnotationParts.js
+++ b/src/data/composite/things/content/withAnnotationParts.js
@@ -19,12 +19,12 @@ export default templateCompositeFrom({
 
   steps: () => [
     raiseOutputWithoutDependency({
-      dependency: 'annotation',
+      dependency: '_annotation',
       output: input.value({'#annotationParts': []}),
     }),
 
     withContentNodes({
-      from: 'annotation',
+      from: '_annotation',
     }),
 
     splitContentNodesAround({
diff --git a/src/data/composite/things/contribution/withContainingReverseContributionList.js b/src/data/composite/things/contribution/withContainingReverseContributionList.js
index 175d6cbb..7f226ff1 100644
--- a/src/data/composite/things/contribution/withContainingReverseContributionList.js
+++ b/src/data/composite/things/contribution/withContainingReverseContributionList.js
@@ -16,7 +16,7 @@ export default templateCompositeFrom({
 
   inputs: {
     artistProperty: input({
-      defaultDependency: 'artistProperty',
+      defaultDependency: '_artistProperty',
       acceptsNull: true,
     }),
   },
diff --git a/src/data/composite/things/language/withStrings.js b/src/data/composite/things/language/withStrings.js
index 3b8d46b3..761e7506 100644
--- a/src/data/composite/things/language/withStrings.js
+++ b/src/data/composite/things/language/withStrings.js
@@ -9,7 +9,7 @@ export default templateCompositeFrom({
   annotation: `withStrings`,
 
   inputs: {
-    from: input({defaultDependency: 'strings'}),
+    from: input({defaultDependency: '_strings'}),
   },
 
   outputs: ['#strings'],
diff --git a/src/data/composite/things/track-section/withStartCountingFrom.js b/src/data/composite/things/track-section/withStartCountingFrom.js
index 20e18edb..6cf03802 100644
--- a/src/data/composite/things/track-section/withStartCountingFrom.js
+++ b/src/data/composite/things/track-section/withStartCountingFrom.js
@@ -9,7 +9,7 @@ export default templateCompositeFrom({
   inputs: {
     from: input({
       type: 'number',
-      defaultDependency: 'startCountingFrom',
+      defaultDependency: '_startCountingFrom',
       acceptsNull: true,
     }),
   },
diff --git a/src/data/composite/things/track/alwaysReferenceByDirectory.js b/src/data/composite/things/track/alwaysReferenceByDirectory.js
index a342d38b..7b72865b 100644
--- a/src/data/composite/things/track/alwaysReferenceByDirectory.js
+++ b/src/data/composite/things/track/alwaysReferenceByDirectory.js
@@ -40,7 +40,7 @@ export default templateCompositeFrom({
     }),
 
     exitWithoutDependency({
-      dependency: 'mainRelease',
+      dependency: '_mainRelease',
       value: input.value(false),
     }),
 
diff --git a/src/data/composite/things/track/withCoverArtistContribs.js b/src/data/composite/things/track/withCoverArtistContribs.js
index 9057cfeb..313d4552 100644
--- a/src/data/composite/things/track/withCoverArtistContribs.js
+++ b/src/data/composite/things/track/withCoverArtistContribs.js
@@ -18,7 +18,7 @@ export default templateCompositeFrom({
 
   inputs: {
     from: input({
-      defaultDependency: 'coverArtistContribs',
+      defaultDependency: '_coverArtistContribs',
       validate: isContributionList,
       acceptsNull: true,
     }),
diff --git a/src/data/composite/things/track/withHasUniqueCoverArt.js b/src/data/composite/things/track/withHasUniqueCoverArt.js
index 85d3b92a..c52abb98 100644
--- a/src/data/composite/things/track/withHasUniqueCoverArt.js
+++ b/src/data/composite/things/track/withHasUniqueCoverArt.js
@@ -37,7 +37,7 @@ export default templateCompositeFrom({
     },
 
     withResultOfAvailabilityCheck({
-      from: 'coverArtistContribs',
+      from: '_coverArtistContribs',
       mode: input.value('empty'),
     }),
 
@@ -76,13 +76,13 @@ export default templateCompositeFrom({
     },
 
     raiseOutputWithoutDependency({
-      dependency: 'trackArtworks',
+      dependency: '_trackArtworks',
       mode: input.value('empty'),
       output: input.value({'#hasUniqueCoverArt': false}),
     }),
 
     withPropertyFromList({
-      list: 'trackArtworks',
+      list: '_trackArtworks',
       property: input.value('artistContribs'),
       internal: input.value(true),
     }),
diff --git a/src/data/composite/things/track/withMainRelease.js b/src/data/composite/things/track/withMainRelease.js
index 67a312ae..fb1342ec 100644
--- a/src/data/composite/things/track/withMainRelease.js
+++ b/src/data/composite/things/track/withMainRelease.js
@@ -18,7 +18,7 @@ export default templateCompositeFrom({
 
   inputs: {
     from: input({
-      defaultDependency: 'mainRelease',
+      defaultDependency: '_mainRelease',
       acceptsNull: true,
     }),
 
diff --git a/src/data/composite/things/track/withMainReleaseTrack.js b/src/data/composite/things/track/withMainReleaseTrack.js
index 6371e895..70d55dd4 100644
--- a/src/data/composite/things/track/withMainReleaseTrack.js
+++ b/src/data/composite/things/track/withMainReleaseTrack.js
@@ -35,7 +35,7 @@ export default templateCompositeFrom({
 
   steps: () => [
     withResultOfAvailabilityCheck({
-      from: 'mainRelease',
+      from: '_mainRelease',
     }),
 
     {
@@ -85,10 +85,10 @@ export default templateCompositeFrom({
     },
 
     {
-      dependencies: ['name', 'directory'],
+      dependencies: ['name', '_directory'],
       compute: (continuation, {
         ['name']: ownName,
-        ['directory']: ownDirectory,
+        ['_directory']: ownDirectory,
       }) => {
         const ownNameKebabed = getKebabCase(ownName);
 
diff --git a/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js b/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js
index 047077fd..b9d8848d 100644
--- a/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js
+++ b/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js
@@ -8,7 +8,7 @@ export default templateCompositeFrom({
 
   inputs: {
     flagValue: input({
-      defaultDependency: 'suffixDirectoryFromAlbum',
+      defaultDependency: '_suffixDirectoryFromAlbum',
       acceptsNull: true,
     }),
   },
@@ -17,18 +17,18 @@ export default templateCompositeFrom({
 
   steps: () => [
     withResultOfAvailabilityCheck({
-      from: 'suffixDirectoryFromAlbum',
+      from: input('flagValue'),
     }),
 
     {
       dependencies: [
         '#availability',
-        'suffixDirectoryFromAlbum'
+        input('flagValue'),
       ],
 
       compute: (continuation, {
         ['#availability']: availability,
-        ['suffixDirectoryFromAlbum']: flagValue,
+        [input('flagValue')]: flagValue,
       }) =>
         (availability
           ? continuation.raiseOutput({['#suffixDirectoryFromAlbum']: flagValue})
diff --git a/src/data/composite/things/track/withTrackArtDate.js b/src/data/composite/things/track/withTrackArtDate.js
index 9b7b61c7..f524afb9 100644
--- a/src/data/composite/things/track/withTrackArtDate.js
+++ b/src/data/composite/things/track/withTrackArtDate.js
@@ -13,7 +13,7 @@ export default templateCompositeFrom({
   inputs: {
     from: input({
       validate: isDate,
-      defaultDependency: 'coverArtDate',
+      defaultDependency: '_coverArtDate',
       acceptsNull: true,
     }),
   },
diff --git a/src/data/composite/wiki-data/gobbleSoupyFind.js b/src/data/composite/wiki-data/gobbleSoupyFind.js
index aec3f5b1..98d5f5c9 100644
--- a/src/data/composite/wiki-data/gobbleSoupyFind.js
+++ b/src/data/composite/wiki-data/gobbleSoupyFind.js
@@ -30,7 +30,7 @@ export default templateCompositeFrom({
     },
 
     withPropertyFromObject({
-      object: 'find',
+      object: '_find',
       property: '#key',
     }).outputs({
       '#value': '#find',
diff --git a/src/data/composite/wiki-data/gobbleSoupyReverse.js b/src/data/composite/wiki-data/gobbleSoupyReverse.js
index 86a1061c..26052f28 100644
--- a/src/data/composite/wiki-data/gobbleSoupyReverse.js
+++ b/src/data/composite/wiki-data/gobbleSoupyReverse.js
@@ -30,7 +30,7 @@ export default templateCompositeFrom({
     },
 
     withPropertyFromObject({
-      object: 'reverse',
+      object: '_reverse',
       property: '#key',
     }).outputs({
       '#value': '#reverse',
diff --git a/src/data/composite/wiki-data/helpers/withSimpleDirectory.js b/src/data/composite/wiki-data/helpers/withSimpleDirectory.js
index 08ca3bfc..0b225847 100644
--- a/src/data/composite/wiki-data/helpers/withSimpleDirectory.js
+++ b/src/data/composite/wiki-data/helpers/withSimpleDirectory.js
@@ -15,7 +15,7 @@ export default templateCompositeFrom({
   inputs: {
     directory: input({
       validate: isDirectory,
-      defaultDependency: 'directory',
+      defaultDependency: '_directory',
       acceptsNull: true,
     }),
 
diff --git a/src/data/composite/wiki-data/withDirectory.js b/src/data/composite/wiki-data/withDirectory.js
index f3bedf2e..e7c3960e 100644
--- a/src/data/composite/wiki-data/withDirectory.js
+++ b/src/data/composite/wiki-data/withDirectory.js
@@ -17,13 +17,13 @@ export default templateCompositeFrom({
   inputs: {
     directory: input({
       validate: isDirectory,
-      defaultDependency: 'directory',
+      defaultDependency: '_directory',
       acceptsNull: true,
     }),
 
     name: input({
       validate: isName,
-      defaultDependency: 'name',
+      defaultDependency: '_name',
       acceptsNull: true,
     }),
 
diff --git a/src/data/composite/wiki-data/withResolvedContribs.js b/src/data/composite/wiki-data/withResolvedContribs.js
index 838c991f..60b5d4c6 100644
--- a/src/data/composite/wiki-data/withResolvedContribs.js
+++ b/src/data/composite/wiki-data/withResolvedContribs.js
@@ -110,7 +110,7 @@ export default templateCompositeFrom({
         '#thingProperty',
         input('artistProperty'),
         input.myself(),
-        'find',
+        '_find',
       ],
 
       compute: (continuation, {
@@ -118,7 +118,7 @@ export default templateCompositeFrom({
         ['#thingProperty']: thingProperty,
         [input('artistProperty')]: artistProperty,
         [input.myself()]: myself,
-        ['find']: find,
+        ['_find']: find,
       }) => continuation({
         ['#contributions']:
           details.map(details => {
diff --git a/src/data/composite/wiki-properties/referencedArtworkList.js b/src/data/composite/wiki-properties/referencedArtworkList.js
index 4f243493..278f063d 100644
--- a/src/data/composite/wiki-properties/referencedArtworkList.js
+++ b/src/data/composite/wiki-properties/referencedArtworkList.js
@@ -22,7 +22,7 @@ export default templateCompositeFrom({
     annotatedReferenceList({
       referenceType: input.value(['album', 'track']),
 
-      data: 'artworkData',
+      data: '_artworkData',
       find: '#find',
 
       thing: input.value('artwork'),
diff --git a/src/data/things/album.js b/src/data/things/album.js
index defb8a87..594046b9 100644
--- a/src/data/things/album.js
+++ b/src/data/things/album.js
@@ -155,7 +155,7 @@ export class Album extends Thing {
     // > Update & expose - Credits and contributors
 
     artistContribs: contributionList({
-      date: 'date',
+      date: '_date',
       artistProperty: input.value('albumArtistContributions'),
     }),
 
@@ -166,7 +166,7 @@ export class Album extends Thing {
         from: input.updateValue({validate: isContributionList}),
         thingProperty: input.thisProperty(),
         artistProperty: input.value('albumTrackArtistContributions'),
-        date: 'date',
+        date: '_date',
       }).outputs({
         '#resolvedContribs': '#trackArtistContribs',
       }),
@@ -177,7 +177,7 @@ export class Album extends Thing {
       }),
 
       withResolvedContribs({
-        from: 'artistContribs',
+        from: '_artistContribs',
         thingProperty: input.thisProperty(),
         artistProperty: input.value('albumTrackArtistContributions'),
         date: 'date',
@@ -209,13 +209,9 @@ export class Album extends Thing {
     // > Update & expose - Artworks
 
     coverArtworks: [
-      // This works, lol, because this array describes `expose.transform` for
-      // the coverArtworks property, and compositions generally access the
-      // update value, not what's exposed by property access out in the open.
-      // There's no recursion going on here.
       exitWithoutArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
         value: input.value([]),
       }),
 
@@ -244,8 +240,8 @@ export class Album extends Thing {
 
     coverArtFileExtension: [
       exitWithoutArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
       }),
 
       fileExtension('jpg'),
@@ -253,8 +249,8 @@ export class Album extends Thing {
 
     coverArtDimensions: [
       exitWithoutArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
       }),
 
       dimensions(),
@@ -262,8 +258,8 @@ export class Album extends Thing {
 
     artTags: [
       exitWithoutArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
         value: input.value([]),
       }),
 
@@ -275,8 +271,8 @@ export class Album extends Thing {
 
     referencedArtworks: [
       exitWithoutArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
         value: input.value([]),
       }),
 
@@ -286,7 +282,7 @@ export class Album extends Thing {
     trackCoverArtistContribs: contributionList({
       // May be null, indicating cover art was added for tracks on the date
       // each track specifies, or else the track's own release date.
-      date: 'trackArtDate',
+      date: '_trackArtDate',
 
       // This is the "correct" value, but it gets overwritten - with the same
       // value - regardless.
@@ -301,7 +297,7 @@ export class Album extends Thing {
 
     wallpaperArtwork: [
       exitWithoutDependency({
-        dependency: 'wallpaperArtistContribs',
+        dependency: '_wallpaperArtistContribs',
         mode: input.value('empty'),
         value: input.value(null),
       }),
@@ -321,8 +317,8 @@ export class Album extends Thing {
 
     wallpaperFileExtension: [
       exitWithoutArtwork({
-        contribs: 'wallpaperArtistContribs',
-        artwork: 'wallpaperArtwork',
+        contribs: '_wallpaperArtistContribs',
+        artwork: '_wallpaperArtwork',
       }),
 
       fileExtension('jpg'),
@@ -330,8 +326,8 @@ export class Album extends Thing {
 
     wallpaperStyle: [
       exitWithoutArtwork({
-        contribs: 'wallpaperArtistContribs',
-        artwork: 'wallpaperArtwork',
+        contribs: '_wallpaperArtistContribs',
+        artwork: '_wallpaperArtwork',
       }),
 
       simpleString(),
@@ -340,8 +336,8 @@ export class Album extends Thing {
     wallpaperParts: [
       // kinda nonsensical or at least unlikely lol, but y'know
       exitWithoutArtwork({
-        contribs: 'wallpaperArtistContribs',
-        artwork: 'wallpaperArtwork',
+        contribs: '_wallpaperArtistContribs',
+        artwork: '_wallpaperArtwork',
         value: input.value([]),
       }),
 
@@ -350,7 +346,7 @@ export class Album extends Thing {
 
     bannerArtwork: [
       exitWithoutDependency({
-        dependency: 'bannerArtistContribs',
+        dependency: '_bannerArtistContribs',
         mode: input.value('empty'),
         value: input.value(null),
       }),
@@ -370,8 +366,8 @@ export class Album extends Thing {
 
     bannerFileExtension: [
       exitWithoutArtwork({
-        contribs: 'bannerArtistContribs',
-        artwork: 'bannerArtwork',
+        contribs: '_bannerArtistContribs',
+        artwork: '_bannerArtwork',
       }),
 
       fileExtension('jpg'),
@@ -379,8 +375,8 @@ export class Album extends Thing {
 
     bannerDimensions: [
       exitWithoutArtwork({
-        contribs: 'bannerArtistContribs',
-        artwork: 'bannerArtwork',
+        contribs: '_bannerArtistContribs',
+        artwork: '_bannerArtwork',
       }),
 
       dimensions(),
@@ -388,8 +384,8 @@ export class Album extends Thing {
 
     bannerStyle: [
       exitWithoutArtwork({
-        contribs: 'bannerArtistContribs',
-        artwork: 'bannerArtwork',
+        contribs: '_bannerArtistContribs',
+        artwork: '_bannerArtwork',
       }),
 
       simpleString(),
@@ -445,15 +441,15 @@ export class Album extends Thing {
 
     hasCoverArt: [
       withHasArtwork({
-        contribs: 'coverArtistContribs',
-        artworks: 'coverArtworks',
+        contribs: '_coverArtistContribs',
+        artworks: '_coverArtworks',
       }),
 
       exposeDependency({dependency: '#hasArtwork'}),
     ],
 
-    hasWallpaperArt: contribsPresent({contribs: 'wallpaperArtistContribs'}),
-    hasBannerArt: contribsPresent({contribs: 'bannerArtistContribs'}),
+    hasWallpaperArt: contribsPresent({contribs: '_wallpaperArtistContribs'}),
+    hasBannerArt: contribsPresent({contribs: '_bannerArtistContribs'}),
 
     tracks: [
       withTracks(),
@@ -1087,7 +1083,7 @@ export class TrackSection extends Thing {
       }),
 
       withDirectory({
-        directory: 'unqualifiedDirectory',
+        directory: '_unqualifiedDirectory',
       }).outputs({
         '#directory': '#unqualifiedDirectory',
       }),
diff --git a/src/data/things/content.js b/src/data/things/content.js
index 95836abd..21ee88f8 100644
--- a/src/data/things/content.js
+++ b/src/data/things/content.js
@@ -51,7 +51,7 @@ export class ContentEntry extends Thing {
 
     accessKind: [
       exitWithoutDependency({
-        dependency: 'accessDate',
+        dependency: '_accessDate',
       }),
 
       exposeUpdateValueOrContinue({
diff --git a/src/data/things/group.js b/src/data/things/group.js
index ac051343..076f0c8f 100644
--- a/src/data/things/group.js
+++ b/src/data/things/group.js
@@ -119,8 +119,8 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'reverse'],
-        compute: ({this: group, reverse}) =>
+        dependencies: ['this', '_reverse'],
+        compute: ({this: group, _reverse: reverse}) =>
           reverse.albumsWhoseGroupsInclude(group),
       },
     },
@@ -129,8 +129,8 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'reverse'],
-        compute: ({this: group, reverse}) =>
+        dependencies: ['this', '_reverse'],
+        compute: ({this: group, _reverse: reverse}) =>
           reverse.groupCategoriesWhichInclude(group, {unique: true})
             ?.color,
       },
@@ -140,8 +140,8 @@ export class Group extends Thing {
       flags: {expose: true},
 
       expose: {
-        dependencies: ['this', 'reverse'],
-        compute: ({this: group, reverse}) =>
+        dependencies: ['this', '_reverse'],
+        compute: ({this: group, _reverse: reverse}) =>
           reverse.groupCategoriesWhichInclude(group, {unique: true}) ??
           null,
       },
diff --git a/src/data/things/index.js b/src/data/things/index.js
index 1e9a5e52..09765fd2 100644
--- a/src/data/things/index.js
+++ b/src/data/things/index.js
@@ -58,6 +58,7 @@ const __dirname = path.dirname(
 function niceShowAggregate(error, ...opts) {
   showAggregate(error, {
     pathToFileURL: (f) => path.relative(__dirname, fileURLToPath(f)),
+    showClasses: false,
     ...opts,
   });
 }
@@ -152,6 +153,15 @@ function descriptorAggregateHelper({
   } catch (error) {
     niceShowAggregate(error);
     showFailedClasses(failedClasses);
+
+    /*
+    if (error.errors) {
+      for (const sub of error.errors) {
+        console.error(sub);
+      }
+    }
+    */
+
     return false;
   }
 }
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 4a24a9e0..ff27e665 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -209,7 +209,7 @@ export class Track extends Thing {
       }),
 
       exposeDependencyOrContinue({
-        dependency: 'artistText',
+        dependency: '_artistText',
       }),
 
       withPropertyFromAlbum({
@@ -318,13 +318,13 @@ export class Track extends Thing {
       }),
 
       exitWithoutDependency({
-        dependency: 'lyrics',
+        dependency: '_lyrics',
         mode: input.value('empty'),
         value: input.value(false),
       }),
 
       withPropertyFromList({
-        list: 'lyrics',
+        list: '_lyrics',
         property: input.value('helpNeeded'),
       }),
 
diff --git a/src/data/things/wiki-info.js b/src/data/things/wiki-info.js
index 89248d11..73470b7d 100644
--- a/src/data/things/wiki-info.js
+++ b/src/data/things/wiki-info.js
@@ -92,7 +92,7 @@ export class WikiInfo extends Thing {
 
     enableSearch: [
       exitWithoutDependency({
-        dependency: 'searchDataAvailable',
+        dependency: '_searchDataAvailable',
         mode: input.value('falsy'),
         value: input.value(false),
       }),