From 24467f479ae684ce5135b95a3920bf46802fcadc Mon Sep 17 00:00:00 2001 From: Valerie Date: Sat, 22 May 2021 13:18:01 -0400 Subject: [PATCH] lots of potential issues, but definitely Closes #21 --- package.json | 2 +- src/Instance.ts | 96 ++++++++++++++++++++++++++++++------------ src/Module.ts | 4 +- src/System.ts | 108 +++++++++++++++++++++++++++++++++++++++++------- vogue-0.0.1.tgz | Bin 30409 -> 0 bytes 5 files changed, 165 insertions(+), 45 deletions(-) delete mode 100644 vogue-0.0.1.tgz diff --git a/package.json b/package.json index 7fae617..453cd61 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "test": "node --enable-source-maps --unhandled-rejections=strict out/run.js test", "debug": "cross-env DEBUG=vogue:* yarn test", - "debug:watch": "cross-env DEBUG=vogue:* supervisor -w out,test,lib -n exit --exec yarn -- test", + "debug:watch": "cross-env DEBUG=vogue:* supervisor -w out,test/**/*.v,lib -n exit --exec yarn -- test", "postinstall": "yarn compile && cd test && yarn", "postcompile:watch": "echo DONE", "compile": "tsc", diff --git a/src/Instance.ts b/src/Instance.ts index 567fc49..9ce88dd 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -2,7 +2,7 @@ import debug from 'debug'; import _ from 'lodash'; const log = debug('vogue:instance'); import vm from 'vm'; -import Module, { Link, Variable } from './Module.js'; +import Module, { LinkDescription, Variable } from './Module.js'; import System from './System.js'; import * as uuid from 'uuid'; /** @@ -10,6 +10,8 @@ import * as uuid from 'uuid'; * @typedef {import('./Module.js').default} Module */ +export type Link = any; // BUT PROXY + export type SerializedInstance = { type: string, links: { @@ -25,38 +27,49 @@ export default class Instance { module: Module; links = {} system: System; - context: vm.Context; + context: vm.Context | null = null; locals = []; internalFunctions = {}; _link: Instance; location: string; _id: string; + initialContext: any = {}; + + get currentContext(): any { + return this.context ?? this.initialContext; + } + + sync() { + this.system.saveInstance(this); + } createContext(): vm.Context { if(this.context) return this.context; + const initialContext: any = {}; // system globals! // TODO turn this into its own vogue module! system.create/instance.create // TODO request context from system... - initialContext.create = this.system.newInstance.bind(this.system); + initialContext.create = this.system.newLink.bind(this.system); initialContext.process = process; - for(const name in this.system.staticInstances) - initialContext[name] = this.system.staticInstances[name]; + for(const name in this.system.staticLinks) { + log('creating context with static link: ' + name); + initialContext[name] = this.system.staticLinks[name]; + } // local links! // optional arrays // TODO maybe make these property accessors to allow for some automation - for(const link of this.module.links.filter((v: Link) => v.array && !v.required)) + for(const link of this.module.links.filter((v: LinkDescription) => v.array && !v.required)) initialContext[link.name] = []; - for(const link of this.module.links.filter((v: Link) => !v.array && !v.required)) + for(const link of this.module.links.filter((v: LinkDescription) => !v.array && !v.required)) initialContext[link.name] = null; - for(const variable of this.module.variables) { - attachHookedProperty(initialContext, variable.name, null, () => { - this.system.saveInstance(this); - }) - } + for(const variable of this.module.variables) + attachHookedProperty(initialContext, variable.name, null, this.sync.bind(this)) + for(const name in this.initialContext) + initialContext[name] = this.initialContext[name] for(const name in this.module.imports) initialContext[name] = this.module.imports[name]; @@ -68,41 +81,70 @@ export default class Instance { // user defined functions for(const name in this.module.functions) { const { code, parameters, async } = this.module.functions[name]; - const injectedScript = -` -var ${name} = ${async ? 'async' : ''} function ${name}(${parameters.join(', ')}) ${code} -${name} = ${name}.bind(this); -`; + const injectedScript = ` + var ${name} = ${async ? 'async ' : ''}function ${name}(${parameters.join(', ')}) ${code} + ${name} = ${name}.bind(this);`.trim(); + // log('injecting function...') + // log(injectedScript) vm.runInContext(injectedScript, context, {}); } + log('context created! ' + Object.keys(context)); + // log(context); + return context; }; - constructor(module: Module, location: string, parameters: {[name: string]: any}, system: System) { + setMember(name: string, value: any) { + log('setMember: ' + this.toString() + '.' + name + ' => ' + value); + this.currentContext[name] = value; + } + + setLink(name: string, value: Link) { + log('setLink: ' + this.toString() + '.' + name + ' => ' + value.__link__); + this.currentContext[name] = value; + } + + constructor( + module: Module, + location: string, + parameters: {[name: string]: any}, + system: System, + options?: { + id?: string + } + ) { this.module = module; this.location = location; this.system = system; - this.context = this.createContext(); - this._id = uuid.v4(); + // this.context = this.createContext(); + this._id = options?.id ?? uuid.v4(); this._link = new Proxy(this, { get(target: Instance, prop: string, receiver) { - log(`getting ${target.module.name.full}.${prop}: (${target.module.identifiers[prop]}|${typeof target.context[prop]})`); + log(`getting ${target.module.name.full}.${prop.toString()}: (${target.module.identifiers[prop]}|${typeof target.context?.[prop]})`); + + if(target.context === null) + target.restore(); + const DNEText = `${target.module.name.full}.${prop.toString()} either does not exist, or is not accessible`; if(prop === 'restore') throw new Error(DNEText); if(prop === '__link__') return target._id; if(prop in target.module.functions) { - return target.context[prop]; + return target.context?.[prop]; } throw new Error(DNEText); } }); + log('created ' + this); } restore() { - return this.context.restore?.(); + if(this.context === null) + this.context = this.createContext(); + + return this.context?.restore?.(); } get link () { @@ -112,9 +154,9 @@ ${name} = ${name}.bind(this); toSerializableObject(): SerializedInstance { const obj: any = {}; obj.type = this.module.name.full; - obj.links = Object.fromEntries(this.module.links.map((link: Link): [string, string] => { + obj.links = Object.fromEntries(this.module.links.map((link: LinkDescription): [string, string] => { const name = link.name; - const linkId = this.context[name]?.__link__; + const linkId = this.context?.[name]?.__link__; return [name, linkId]; })); obj.members = Object.fromEntries( @@ -124,7 +166,7 @@ ${name} = ${name}.bind(this); }) .map((member: Variable): [string, any] => { const name = member.name; - const value = this.context[name]; + const value = this.context?.[name]; return [name, value]; }) ); @@ -134,7 +176,7 @@ ${name} = ${name}.bind(this); } toString() { - return this.module.name.full + '(' + this._id + ')'; + return this.module.name.full + '(' + this._id.substr(0, 4) + ')'; } } diff --git a/src/Module.ts b/src/Module.ts index 5e9f3a7..c36c14e 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -14,7 +14,7 @@ import { createRequire } from 'module'; import { pathToFileURL } from 'url'; const log = debug('vogue:module'); -export type Link = { +export type LinkDescription = { name: string, array: boolean, required: boolean @@ -26,7 +26,7 @@ export type Variable = { } export default class Module { - links: Link[] = []; + links: LinkDescription[] = []; globals = []; functions: { [name: string]: { diff --git a/src/System.ts b/src/System.ts index 79e85d6..503bb6c 100644 --- a/src/System.ts +++ b/src/System.ts @@ -1,8 +1,8 @@ -import Instance from './Instance.js'; +import Instance, { Link, SerializedInstance } from './Instance.js'; import _ from 'lodash'; import Module from './Module.js'; import debug from 'debug'; -import { writeFileSync } from 'fs'; +import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'fs'; import { resolve } from 'path'; import { ensureDirSync } from 'fs-extra'; const log = debug('vogue:system') @@ -16,11 +16,11 @@ type ModuleNamespaceMap = { type ModuleName = string; class System { - instances: Instance[] = []; + instances: Map = new Map(); modules: Module[]; namespace: ModuleNamespaceMap = {}; - staticInstances: { - [key: string]: Instance + staticLinks: { + [key: string]: Link } = {}; rootDir: string; @@ -28,16 +28,87 @@ class System { this.rootDir = rootDir; this.modules = modules; this.createNamespace(); + + const vault = readdirSync(resolve(this.rootDir, '.system')).map(v => resolve(this.rootDir, '.system', v)); + const serializedInstances: SerializedInstance[] = vault.map((v) => JSON.parse(readFileSync(v).toString())); + + log('injecting serialized instances...'); + for(const serializedInstance of serializedInstances) + this.injectSerializedInstance(serializedInstance); + log('linking serialized instances...'); + for(const serializedInstance of serializedInstances) + this.linkSerializedInstance(serializedInstance); + + log('restoring static instances...'); + for(const [,instance] of this.instances) { + if(!!instance.module.static) { + instance.restore(); + } + } + + log('restoring boot instances...'); + for(const [,instance] of this.instances) { + if(!!instance.module.singleton) { + instance.restore(); + } + } + // this.inject(serializedInstance); + + + if (vault.length !== 0) { + return this; + } + + // TODO future workflow notes + // pull jsons into boots + // filter json boots + // create static / singletons into boots + // boot boots! + + const bootModules = this.deriveBootModules(); this.createStaticInstances(); log('instantiating boot modules...'); for(const name of bootModules) { log(' ' + name); - this.newInstance(name); + this.newLink(name); } } + linkSerializedInstance(serializedInstance: SerializedInstance): void { + const instance = this.getInstanceById(serializedInstance.id); + for(const name in serializedInstance.links) { + const linkId = serializedInstance.links[name] + const linkedInstance = this.getInstanceById(linkId); + const linkedInstanceLink = linkedInstance.link; + instance.setLink(name, linkedInstanceLink); + } + } + + injectSerializedInstance(serializedInstance: SerializedInstance): void { + const instance = new Instance(this.getModule(serializedInstance.type), this.rootDir, {}, this, { + id: serializedInstance.id + }); + this.instances.set(instance._id, instance); + + for(const name in serializedInstance.members) { + instance.setMember(name, serializedInstance.members[name]); + } + + if(instance.module.static) { + log('injected static instance ' + instance.module.static + ': ' + instance.module.name.full); + this.staticLinks[instance.module.static] = instance.link; + } + } + + getInstanceById(id: string): Instance { + if(!this.instances.has(id)) + throw new Error(`${id} is not a valid instance link id`); + + return this.instances.get(id) as Instance; + } + createStaticInstances() { log('deriving static modules...'); const staticModules = this.modules.filter((module) => { @@ -50,8 +121,8 @@ class System { log('instantiating static modules...'); for(const module of staticModules) { log(' ' + module.static + ': ' + module.name.full); - this.staticInstances[module.static] = - this.newInstance(module.name.full, {}); + this.staticLinks[module.static] = + this.newLink(module.name.full, {}); } } @@ -81,16 +152,13 @@ class System { } saveInstance(instance: Instance): void { - log('saving ' + instance) const path = resolve(this.rootDir, '.system'); ensureDirSync(path); const file = instance._id + '.json'; const filepath = resolve(path, file); - log(filepath); + log('saving ' + instance + '...'); const json = JSON.stringify(instance.toSerializableObject(), null, 2) - log(json); writeFileSync(filepath, json); - log('synced ' + instance); } getModule(name: ModuleName): Module { @@ -100,12 +168,12 @@ class System { } createInstance(name: ModuleName, args = {}) { - const instance = new Instance(this.getModule(name), '', args, this); + const instance = new Instance(this.getModule(name), this.rootDir, args, this); this.saveInstance(instance); return instance; } - newInstance(name: ModuleName, args = {}) { + newLink(name: ModuleName, args = {}) { const instance = this.createInstance(name, args); const link = instance.link; instance.restore(); @@ -113,4 +181,14 @@ class System { } } -export default System; \ No newline at end of file +export default System; + +// class SerializedInstanceInjector { +// system: System; +// serializedInstances: SerializedInstance[]; + +// constructor(serializedInstances: SerializedInstance[], system: System) { +// this.serializedInstances = serializedInstances; +// this.system = system; +// } +// } \ No newline at end of file diff --git a/vogue-0.0.1.tgz b/vogue-0.0.1.tgz deleted file mode 100644 index 7b94f1e2e2771997cf2f16b5084a4d7e24f60eef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30409 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 E08u|%{r~^~