diff --git a/package.json b/package.json index 4efdf8f..26b457e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frigid", - "version": "1.3.7", + "version": "1.3.8", "main": "out/index.js", "types": "out/index.d.ts", "license": "MIT", diff --git a/src/Serializable.ts b/src/Serializable.ts index 69f6dd1..327baa4 100644 --- a/src/Serializable.ts +++ b/src/Serializable.ts @@ -1,11 +1,12 @@ // import { Ubjson } from '@shelacek/ubjson'; -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 const DEBUG = Symbol('DEBUG'); +type SerializableClass = typeof Serializable; + export default class Serializable { [DEBUG] = false; @@ -34,7 +35,7 @@ export default class Serializable { static INSTANCE_DECLARATION = '$$INSTANCE_ID'; static INSTANCE_REFERENCE = '$$INSTANCE_REF'; - static serializationDependencies(): any[] { + static serializationDependencies(): SerializableClass[] { return []; } @@ -101,8 +102,21 @@ export default class Serializable { return transformObject(this); } - static fromSerializableObject(obj: any, instances: Map = new Map()) { + static fromSerializableObject(obj: any, instances: Map = new Map(), classes: Set = new Set()) { if(obj[Serializable.CLASS_REFERENCE] !== this.name) return null; + + + if(classes.size === 0) { + function descendDeps(ctx: SerializableClass) { + for(const child of ctx.serializationDependencies?.() ?? []) { + if(!classes.has(child)) { + classes.add(child) + descendDeps(child); + } + } + } + descendDeps(this); + } const transformValue = (val: any): any => { if(Array.isArray(val)) { @@ -111,12 +125,11 @@ export default class Serializable { return val; } else if(typeof val === 'object') { if(Serializable.CLASS_REFERENCE in val) { - const classes = this.serializationDependencies(); - const matchingClasses = classes.filter((classObject) => { + const matchingClasses = [...classes].filter((classObject) => { return classObject.name === val[Serializable.CLASS_REFERENCE] }); if(matchingClasses.length === 1) { - return matchingClasses[0].fromSerializableObject(val, instances); + return matchingClasses[0].fromSerializableObject(val, instances, classes); } else { throw new Error('Unknown class ' + val[Serializable.CLASS_REFERENCE] + '!\n' + 'Did you forget to add ' + val[Serializable.CLASS_REFERENCE] + ` to ${this.name}.serializationDependencies?`); @@ -187,8 +200,6 @@ export default class Serializable { const parse = secondPass(clone); - // clone.restore?.(); - return parse; } diff --git a/yarn.lock b/yarn.lock index 37bae2c..0ede9e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,52 +1,62 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/node@^15.12.2": - version "15.12.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - -chai@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - dependencies: - type-detect "^4.0.0" - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - -typescript@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" - -yarn@^1.22.10: - version "1.22.10" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c" +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^15.12.2": + "integrity" "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz" + "version" "15.12.2" + +"assertion-error@^1.1.0": + "integrity" "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + "resolved" "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + "version" "1.1.0" + +"chai@^4.3.4": + "integrity" "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==" + "resolved" "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz" + "version" "4.3.4" + dependencies: + "assertion-error" "^1.1.0" + "check-error" "^1.0.2" + "deep-eql" "^3.0.1" + "get-func-name" "^2.0.0" + "pathval" "^1.1.1" + "type-detect" "^4.0.5" + +"check-error@^1.0.2": + "integrity" "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + "resolved" "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + "version" "1.0.2" + +"deep-eql@^3.0.1": + "integrity" "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==" + "resolved" "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "type-detect" "^4.0.0" + +"get-func-name@^2.0.0": + "integrity" "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + "resolved" "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + "version" "2.0.0" + +"pathval@^1.1.1": + "integrity" "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" + "resolved" "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" + "version" "1.1.1" + +"type-detect@^4.0.0", "type-detect@^4.0.5": + "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + "version" "4.0.8" + +"typescript@^4.3.2": + "integrity" "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" + "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz" + "version" "4.3.2" + +"yarn@^1.22.10": + "integrity" "sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==" + "resolved" "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz" + "version" "1.22.10"