« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/data/cacheable-object.js35
-rw-r--r--src/data/things/index.js4
2 files changed, 25 insertions, 14 deletions
diff --git a/src/data/cacheable-object.js b/src/data/cacheable-object.js
index 1e7c7aa8..addc225b 100644
--- a/src/data/cacheable-object.js
+++ b/src/data/cacheable-object.js
@@ -83,6 +83,8 @@ function inspect(value) {
 }
 
 export default class CacheableObject {
+  static propertyDescriptors = Symbol.for('CacheableObject.propertyDescriptors');
+
   #propertyUpdateValues = Object.create(null);
   #propertyUpdateCacheInvalidators = Object.create(null);
 
@@ -113,12 +115,21 @@ export default class CacheableObject {
     }
   }
 
+  #withEachPropertyDescriptor(callback) {
+    const {[CacheableObject.propertyDescriptors]: propertyDescriptors} =
+      this.constructor;
+
+    for (const property of Reflect.ownKeys(propertyDescriptors)) {
+      callback(property, propertyDescriptors[property]);
+    }
+  }
+
   #initializeUpdatingPropertyValues() {
-    for (const [property, descriptor] of Object.entries(this.constructor.propertyDescriptors)) {
+    this.#withEachPropertyDescriptor((property, descriptor) => {
       const {flags, update} = descriptor;
 
       if (!flags.update) {
-        continue;
+        return;
       }
 
       if (update?.default) {
@@ -126,15 +137,15 @@ export default class CacheableObject {
       } else {
         this[property] = null;
       }
-    }
+    });
   }
 
   #defineProperties() {
-    if (!this.constructor.propertyDescriptors) {
-      throw new Error(`Expected constructor ${this.constructor.name} to define propertyDescriptors`);
+    if (!this.constructor[CacheableObject.propertyDescriptors]) {
+      throw new Error(`Expected constructor ${this.constructor.name} to provide CacheableObject.propertyDescriptors`);
     }
 
-    for (const [property, descriptor] of Object.entries(this.constructor.propertyDescriptors)) {
+    this.#withEachPropertyDescriptor((property, descriptor) => {
       const {flags} = descriptor;
 
       const definition = {
@@ -151,7 +162,7 @@ export default class CacheableObject {
       }
 
       Object.defineProperty(this, property, definition);
-    }
+    });
 
     Object.seal(this);
   }
@@ -191,7 +202,7 @@ export default class CacheableObject {
   }
 
   #getPropertyDescriptor(property) {
-    return this.constructor.propertyDescriptors[property];
+    return this.constructor[CacheableObject.propertyDescriptors][property];
   }
 
   #invalidateCachesDependentUpon(property) {
@@ -311,16 +322,16 @@ export default class CacheableObject {
       return;
     }
 
-    const {propertyDescriptors} = obj.constructor;
+    const {[CacheableObject.propertyDescriptors]: propertyDescriptors} =
+      obj.constructor;
 
     if (!propertyDescriptors) {
       console.warn('Missing property descriptors:', obj);
       return;
     }
 
-    for (const [property, descriptor] of Object.entries(propertyDescriptors)) {
-      const {flags} = descriptor;
-
+    for (const property of Reflect.ownKeys(propertyDescriptors)) {
+      const {flags} = propertyDescriptors[property];
       if (!flags.expose) {
         continue;
       }
diff --git a/src/data/things/index.js b/src/data/things/index.js
index 3bf84091..01a8198b 100644
--- a/src/data/things/index.js
+++ b/src/data/things/index.js
@@ -2,10 +2,10 @@ import * as path from 'node:path';
 import {fileURLToPath} from 'node:url';
 
 import {openAggregate, showAggregate} from '#aggregate';
+import CacheableObject from '#cacheable-object';
 import {logError} from '#cli';
 import {compositeFrom} from '#composite';
 import * as serialize from '#serialize';
-
 import Thing from '#thing';
 
 import * as albumClasses from './album.js';
@@ -142,7 +142,7 @@ function evaluatePropertyDescriptors() {
         }
       }
 
-      constructor.propertyDescriptors = results;
+      constructor[CacheableObject.propertyDescriptors] = results;
     },
 
     showFailedClasses(failedClasses) {