From 9466ed326cf6d36cbfa411ea5b8ef690c63b0c9c Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 4 Mar 2024 18:06:33 -0400 Subject: cacheable-object: define properties on symbol, allow symbol props This commit really does two separate things: * Move the definition for `propertyDescriptors` from that string key into `Symbol.for('CacheableObject.propertyDescriptors')` * Allow and support descriptors for key-based properties, by iterating over Reflect.ownKeys() instead of Object.entries() --- src/data/cacheable-object.js | 35 +++++++++++++++++++++++------------ src/data/things/index.js | 4 ++-- 2 files changed, 25 insertions(+), 14 deletions(-) (limited to 'src') 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) { -- cgit 1.3.0-6-gf8a5