From 394e08c55a3d310a8810875b27fecaf1cb479f5b Mon Sep 17 00:00:00 2001 From: Valerie Date: Sat, 12 Jun 2021 15:11:53 -0400 Subject: [PATCH] frigid ctor --- package.json | 2 +- src/Frigid.ts | 63 +++++++++++++++++++++++++++++++-------------- src/Serializable.ts | 22 +++++----------- src/index.ts | 2 +- test/Frigid.js | 31 +++++++++++++++------- 5 files changed, 74 insertions(+), 46 deletions(-) diff --git a/package.json b/package.json index e9860a1..a0e9813 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frigid", - "version": "1.2.0", + "version": "1.3.0", "main": "out/index.js", "types": "out/index.d.ts", "license": "MIT", diff --git a/src/Frigid.ts b/src/Frigid.ts index 96dd64b..2026b04 100644 --- a/src/Frigid.ts +++ b/src/Frigid.ts @@ -2,30 +2,28 @@ import { existsSync, readFileSync, writeFileSync } from "fs"; import Serializable from "./Serializable.js"; const PERSIST_LOCATION = Symbol('PERSIST_LOCATION'); -export const RESTORE = Symbol('RESTORE'); export default class Frigid extends Serializable { + + ctor() {} + + constructor(...args) { + super(...args); + } + static create(filename: string, ...args: any[]) { - if(existsSync(filename)) { - const instance = new this(...args); - const instanceStuff = this.deserialize(readFileSync(filename)); - for(const key of Object.keys(instanceStuff)) { - instance[key] = instanceStuff[key] + + const instance = (() => { + if(existsSync(filename)) { + return this.deserialize(readFileSync(filename)); + } else { + return new this(...args); } - // TS is plain and simply wrong... symbols can be used to index object... - // @ts-ignore - instance[PERSIST_LOCATION] = filename; - instance[RESTORE]?.(); - return instance; - } else { - const instance = new this(...args); - // again... TS is wrong... - // @ts-ignore - instance[PERSIST_LOCATION] = filename; - instance[RESTORE]?.(); - instance.sync(); - return instance; - } + })(); + + finalze(instance, filename); + + return instance; } sync() { @@ -34,4 +32,29 @@ export default class Frigid extends Serializable { // @ts-ignore writeFileSync(this[PERSIST_LOCATION], data); } +} + +function walk(obj, transform) { + if(obj instanceof Serializable) { + transform(obj); + } + for(const key of Object.keys(obj)) { + const val = obj[key]; + if(typeof obj === 'object') { + walk(val, transform); + } + } +} + +function finalze(instance, filename) { + // TS is plain and simply wrong... symbols can be used to index object... + // @ts-ignore + instance[PERSIST_LOCATION] = filename; + + walk(instance, (obj) => { + // console.log(obj instanceof Serializable) + (obj as any).ctor?.(); + }); + + instance.sync(); } \ No newline at end of file diff --git a/src/Serializable.ts b/src/Serializable.ts index 740b111..00eb094 100644 --- a/src/Serializable.ts +++ b/src/Serializable.ts @@ -4,7 +4,9 @@ import { reverseLookup } from './reverseLookup.js'; export default class Serializable { - constructor(...args: any[]) {} + // takes as many args as it needs to (so subclasses can + // define their own constructor, with any number of args) + constructor(...args) {} // things that need to be stored only in cold // storage are keyed with a special prefix @@ -23,8 +25,8 @@ export default class Serializable { return JSON.stringify(this.toSerializableObject(), null, 2); } - static fromJson(str: string) { - return this.fromSerializableObject(JSON.parse(str)); + static fromJson(str: string, instances: Map = new Map()) { + return this.fromSerializableObject(JSON.parse(str), instances); } // this doesnt operate recursively, it doesnt need to, because @@ -180,17 +182,7 @@ export default class Serializable { } - static deserialize(obj: any, { - encoding = 'json' - } = {}) { - - switch(encoding) { - case 'json': return this.fromJson(obj); - case 'ubjson': - // case 'ubj': return this.fromUbj(obj); - default: { - throw new TypeError('Unknown encoding: ' + encoding); - } - } + static deserialize(obj: any, instances: Map = new Map()) { + return this.fromJson(obj, instances); } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index ee3c06f..656a6e1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ export {default as Serializable} from './Serializable.js'; -export {default as Frigid, RESTORE} from './Frigid.js' \ No newline at end of file +export {default as Frigid} from './Frigid.js' \ No newline at end of file diff --git a/test/Frigid.js b/test/Frigid.js index 766f4bf..200d7df 100644 --- a/test/Frigid.js +++ b/test/Frigid.js @@ -1,24 +1,35 @@ -import {Frigid, RESTORE} from '../out/index.js'; +import { Frigid, Serializable } from '../out/index.js'; import { existsSync, readFileSync, unlinkSync } from 'fs'; import { expect } from 'chai'; const trackingData = { constructorCalls: 0, - restoreCalls: 0 + ctor: 0, + subCtor: 0 +} + +class Sub extends Serializable { + ctor() { + trackingData.subCtor ++; + } } class Test extends Frigid { foo = 'bar'; + test = new Sub(); + + static serializationDependencies() { + return [ Sub ]; + } + constructor() { super(); trackingData.constructorCalls ++; - console.log('construct') } - [RESTORE]() { - trackingData.restoreCalls ++; - console.log('restore') + ctor() { + trackingData.ctor ++; } } @@ -36,11 +47,13 @@ expect(existsSync(filepath)).to.be.true; expect(readFileSync(filepath).toString()).to.not.be.empty; expect(trackingData.constructorCalls).to.equal(1); -expect(trackingData.restoreCalls).to.equal(1); +expect(trackingData.subCtor).to.equal(1); +expect(trackingData.ctor).to.equal(1); const retest = Test.create(filepath); -expect(trackingData.constructorCalls).to.equal(2); -expect(trackingData.restoreCalls).to.equal(2); +expect(trackingData.constructorCalls).to.equal(1); +expect(trackingData.subCtor).to.equal(2); +expect(trackingData.ctor).to.equal(2); unlinkSync(filepath) \ No newline at end of file