call ctor on new Serializables

master
Valerie 2021-06-12 17:35:37 -04:00
parent 45d938874d
commit 3fe83325ff
3 changed files with 23 additions and 6 deletions

View File

@ -1,6 +1,6 @@
import { existsSync, readFileSync, writeFileSync } from "fs"; import { existsSync, readFileSync, writeFileSync } from "fs";
import { reverseLookup } from "./reverseLookup.js"; import { reverseLookup } from "./reverseLookup.js";
import Serializable from "./Serializable.js"; import Serializable, { INVOKE_CTOR } from "./Serializable.js";
const PERSIST_LOCATION = Symbol('PERSIST_LOCATION'); const PERSIST_LOCATION = Symbol('PERSIST_LOCATION');
@ -36,6 +36,7 @@ export default class Frigid extends Serializable {
} }
function walk(obj, transform, done = new Map()) { function walk(obj, transform, done = new Map()) {
if(obj === null || obj === undefined) return;
if(obj instanceof Serializable) { if(obj instanceof Serializable) {
transform(obj); transform(obj);
} }
@ -57,7 +58,7 @@ function finalze(instance, filename) {
walk(instance, (obj) => { walk(instance, (obj) => {
// console.log(obj instanceof Serializable) // console.log(obj instanceof Serializable)
(obj as any).ctor?.(); obj[INVOKE_CTOR]();
}); });
instance.sync(); instance.sync();

View File

@ -2,11 +2,26 @@
import { existsSync, readFileSync, writeFileSync } from 'fs'; import { existsSync, readFileSync, writeFileSync } from 'fs';
import { reverseLookup } from './reverseLookup.js'; import { reverseLookup } from './reverseLookup.js';
export const CTOR_CALLED = Symbol('CTOR_CALLED');
export const INVOKE_CTOR = Symbol('INVOKE_CTOR');
export default class Serializable { export default class Serializable {
[CTOR_CALLED] = false;
// takes as many args as it needs to (so subclasses can // takes as many args as it needs to (so subclasses can
// define their own constructor, with any number of args) // 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 // things that need to be stored only in cold
// storage are keyed with a special prefix // storage are keyed with a special prefix
@ -148,6 +163,7 @@ export default class Serializable {
if(key === Serializable.CLASS_REFERENCE) delete obj[key]; if(key === Serializable.CLASS_REFERENCE) delete obj[key];
const val = obj[key]; const val = obj[key];
if(typeof val === 'object') { if(typeof val === 'object') {
if(val === null || val === undefined) return obj;
if(Serializable.INSTANCE_REFERENCE in val) { if(Serializable.INSTANCE_REFERENCE in val) {
const refId = val[Serializable.INSTANCE_REFERENCE]; const refId = val[Serializable.INSTANCE_REFERENCE];
if(instances.has(refId)) { if(instances.has(refId)) {

View File

@ -16,8 +16,7 @@ class Sub extends Serializable {
class Test extends Frigid { class Test extends Frigid {
foo = 'bar'; foo = 'bar';
test = null;
test = new Sub();
static serializationDependencies() { static serializationDependencies() {
return [ Sub ]; return [ Sub ];
@ -30,6 +29,7 @@ class Test extends Frigid {
ctor() { ctor() {
trackingData.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(existsSync(filepath)).to.be.true;
expect(readFileSync(filepath).toString()).to.not.be.empty; expect(readFileSync(filepath).toString()).to.not.be.empty;
expect(trackingData.ctor).to.equal(1);
expect(trackingData.constructorCalls).to.equal(1); expect(trackingData.constructorCalls).to.equal(1);
expect(trackingData.subCtor).to.equal(1); expect(trackingData.subCtor).to.equal(1);
expect(trackingData.ctor).to.equal(1);
const retest = Test.create(filepath); const retest = Test.create(filepath);