diff options
-rw-r--r-- | src/data/thing.js | 2 | ||||
-rw-r--r-- | src/find.js | 31 |
2 files changed, 31 insertions, 2 deletions
diff --git a/src/data/thing.js b/src/data/thing.js index 29f50d23..78ad3642 100644 --- a/src/data/thing.js +++ b/src/data/thing.js @@ -14,6 +14,8 @@ export default class Thing extends CacheableObject { static getSerializeDescriptors = Symbol.for('Thing.getSerializeDescriptors'); static findSpecs = Symbol.for('Thing.findSpecs'); + static findThisThingOnly = Symbol.for('Thing.findThisThingOnly'); + static yamlDocumentSpec = Symbol.for('Thing.yamlDocumentSpec'); static getYamlLoadingSpec = Symbol.for('Thing.getYamlLoadingSpec'); diff --git a/src/find.js b/src/find.js index 8b6bca74..995f7368 100644 --- a/src/find.js +++ b/src/find.js @@ -161,6 +161,26 @@ const hardcodedFindSpecs = { }, }; +export function postprocessFindSpec(spec, {thingConstructor}) { + const newSpec = {...spec}; + + // Default behavior is to find only instances of the constructor. + // This symbol field lets a spec opt out. + if (spec[Symbol.for('Thing.findThisThingOnly')] !== false) { + if (spec.include) { + const oldInclude = spec.include; + newSpec.include = thing => + thing instanceof thingConstructor && + oldInclude(thing); + } else { + newSpec.include = thing => + thing instanceof thingConstructor; + } + } + + return newSpec; +} + export function getAllFindSpecs() { try { thingConstructors; @@ -174,7 +194,12 @@ export function getAllFindSpecs() { const thingFindSpecs = thingConstructor[Symbol.for('Thing.findSpecs')]; if (!thingFindSpecs) continue; - Object.assign(findSpecs, thingFindSpecs); + for (const [key, spec] of Object.entries(thingFindSpecs)) { + findSpecs[key] = + postprocessFindSpec(spec, { + thingConstructor, + }); + } } return findSpecs; @@ -196,7 +221,9 @@ export function findFindSpec(key) { if (!thingFindSpecs) continue; if (Object.hasOwn(thingFindSpecs, key)) { - return thingFindSpecs[key]; + return postprocessFindSpec(thingFindSpecs[key], { + thingConstructor, + }); } } |