frigid ctor

master
Valerie 2021-06-12 15:11:53 -04:00
parent f9cace7815
commit 394e08c55a
5 changed files with 74 additions and 46 deletions

View File

@ -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",

View File

@ -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();
}

View File

@ -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<number, object> = 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<number, object> = new Map()) {
return this.fromJson(obj, instances);
}
}

View File

@ -1,2 +1,2 @@
export {default as Serializable} from './Serializable.js';
export {default as Frigid, RESTORE} from './Frigid.js'
export {default as Frigid} from './Frigid.js'

View File

@ -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)