« 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/thing.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/thing.js')
-rw-r--r--src/data/thing.js31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/data/thing.js b/src/data/thing.js
index 32eff4d1..0a6e3be4 100644
--- a/src/data/thing.js
+++ b/src/data/thing.js
@@ -23,7 +23,6 @@ export default class Thing extends CacheableObject {
   static reverseSpecs = Symbol.for('Thing.reverseSpecs');
 
   static yamlDocumentSpec = Symbol.for('Thing.yamlDocumentSpec');
-  static getYamlLoadingSpec = Symbol.for('Thing.getYamlLoadingSpec');
 
   static yamlSourceFilename = Symbol.for('Thing.yamlSourceFilename');
   static yamlSourceDocument = Symbol.for('Thing.yamlSourceDocument');
@@ -82,9 +81,37 @@ export default class Thing extends CacheableObject {
       (reference ? ` (${reference})` : ''));
   }
 
+  static clone(source, {as = null} = {}) {
+    if (!(source instanceof this)) {
+      throw new TypeError(
+        `Passed thing is ${source.constructor.name}, ` +
+        `which is not a subclass of ${this.name}`);
+    }
+
+    if (as && !(as.prototype instanceof this)) {
+      throw new TypeError(
+        `Passed constructor is ${as.name}, ` +
+        `which is not a subclass of ${this.name}`);
+    }
+
+    let clone;
+
+    if (as) {
+      clone = Reflect.construct(as, []);
+    } else {
+      clone = Reflect.construct(source.constructor, []);
+    }
+
+    CacheableObject.copyUpdateValuesOnto(source, clone);
+
+    return clone;
+  }
+
   static getReference(thing) {
     if (!thing.constructor[Thing.referenceType]) {
-      throw TypeError(`Passed Thing is ${thing.constructor.name}, which provides no [Thing.referenceType]`);
+      throw TypeError(
+        `Passed Thing is ${thing.constructor.name}, ` +
+        `which provides no [Thing.referenceType]`);
     }
 
     if (!thing.directory) {