diff --git a/src/Frigid.ts b/src/Frigid.ts index 2bb9a8c..b849a9d 100644 --- a/src/Frigid.ts +++ b/src/Frigid.ts @@ -1,6 +1,6 @@ import { existsSync, readFileSync, writeFileSync } from "fs"; import { reverseLookup } from "./reverseLookup.js"; -import Serializable from "./Serializable.js"; +import Serializable, { INVOKE_CTOR } from "./Serializable.js"; const PERSIST_LOCATION = Symbol('PERSIST_LOCATION'); @@ -36,6 +36,7 @@ export default class Frigid extends Serializable { } function walk(obj, transform, done = new Map()) { + if(obj === null || obj === undefined) return; if(obj instanceof Serializable) { transform(obj); } @@ -57,7 +58,7 @@ function finalze(instance, filename) { walk(instance, (obj) => { // console.log(obj instanceof Serializable) - (obj as any).ctor?.(); + obj[INVOKE_CTOR](); }); instance.sync(); diff --git a/src/Serializable.ts b/src/Serializable.ts index 00eb094..79bf4bf 100644 --- a/src/Serializable.ts +++ b/src/Serializable.ts @@ -2,11 +2,26 @@ import { existsSync, readFileSync, writeFileSync } from 'fs'; import { reverseLookup } from './reverseLookup.js'; +export const CTOR_CALLED = Symbol('CTOR_CALLED'); +export const INVOKE_CTOR = Symbol('INVOKE_CTOR'); + export default class Serializable { + [CTOR_CALLED] = false; + // takes as many args as it needs to (so subclasses can // define their own constructor, with any number of args) - constructor(...args) {} + constructor(...args) { + this[INVOKE_CTOR](); + } + + [INVOKE_CTOR] () { + const call = !this[CTOR_CALLED]; + this[CTOR_CALLED] = true; + if(call) { + (this as any).ctor?.(); + } + } // things that need to be stored only in cold // storage are keyed with a special prefix @@ -148,6 +163,7 @@ export default class Serializable { if(key === Serializable.CLASS_REFERENCE) delete obj[key]; const val = obj[key]; if(typeof val === 'object') { + if(val === null || val === undefined) return obj; if(Serializable.INSTANCE_REFERENCE in val) { const refId = val[Serializable.INSTANCE_REFERENCE]; if(instances.has(refId)) { diff --git a/test/Frigid.js b/test/Frigid.js index 200d7df..fbbcc27 100644 --- a/test/Frigid.js +++ b/test/Frigid.js @@ -16,8 +16,7 @@ class Sub extends Serializable { class Test extends Frigid { foo = 'bar'; - - test = new Sub(); + test = null; static serializationDependencies() { return [ Sub ]; @@ -30,6 +29,7 @@ class Test extends Frigid { ctor() { trackingData.ctor ++; + this.test ??= new Sub(); } } @@ -46,9 +46,9 @@ expect(test.sync.bind(test)).to.not.throw(); expect(existsSync(filepath)).to.be.true; expect(readFileSync(filepath).toString()).to.not.be.empty; +expect(trackingData.ctor).to.equal(1); expect(trackingData.constructorCalls).to.equal(1); expect(trackingData.subCtor).to.equal(1); -expect(trackingData.ctor).to.equal(1); const retest = Test.create(filepath);