103 lines
2.7 KiB
JavaScript
103 lines
2.7 KiB
JavaScript
|
|
import Serializable from './Serializable.js';
|
|
import minify from './minify.js';
|
|
import debug from 'debug';
|
|
import _ from 'lodash';
|
|
const log = debug('vogue:instance');
|
|
|
|
|
|
export default class Instance extends Serializable {
|
|
module = null;
|
|
links = {}
|
|
system = null;
|
|
context = null;
|
|
locals = [];
|
|
|
|
// reconstruct context when we need it...
|
|
createContext() {
|
|
let ctx = {};
|
|
for(const name in this.links) {
|
|
ctx[name] = this.links[name];
|
|
}
|
|
for(const name in this.module.imports) {
|
|
ctx[name] = this.module.imports[name];
|
|
this.locals.push(name);
|
|
}
|
|
ctx = {
|
|
...ctx,
|
|
...this.system.staticInstances
|
|
}
|
|
for(const identifier in this.system.staticInstances) {
|
|
this.locals.push(identifier);
|
|
}
|
|
ctx.create = this.system.newInstance.bind(this.system);
|
|
this.locals.push('create');
|
|
this.context = ctx;
|
|
};
|
|
|
|
ready = false;
|
|
|
|
constructor(module, location, parameters, system) {
|
|
super();
|
|
this.module = module;
|
|
this.location = location;
|
|
this.system = system;
|
|
for(const name of this.module.links.optional.arrays) this.links[name] = [];
|
|
for(const name of this.module.links.optional.single) this.links[name] = null;
|
|
this.createContext();
|
|
|
|
this._link = new Proxy(this, {
|
|
get(target, prop, receiver) {
|
|
if(prop === 'restore') return undefined;
|
|
if(prop in target.module.functions) {
|
|
return target.invokeInternal.bind(target, prop);
|
|
}
|
|
return undefined;
|
|
}
|
|
});
|
|
}
|
|
|
|
hasPublicFunction(name) {
|
|
return (name in this.module.functions);
|
|
}
|
|
|
|
invokeInternal(name, ...args) {
|
|
log('invoking', this.module.name.full + '.' + name, 'with args', args);
|
|
const content = this.module.functions[name].code;
|
|
const passingArguments = _.zipObject(this.module.functions[name].parameters, args);
|
|
log('arguments obj', passingArguments);
|
|
if(!content) throw new TypeError(name + ' is not a function!');
|
|
return evalInContext(content, this.context, this.locals, passingArguments);
|
|
}
|
|
|
|
get link () {
|
|
return this._link;
|
|
}
|
|
}
|
|
|
|
function evalInContext(js, context, locals, passingArguments) {
|
|
//# Return the results of the in-line anonymous function we .call with the passed context
|
|
log('='.repeat(80) + 'OG Block');
|
|
log(js);
|
|
log('='.repeat(80) + 'Arguments');
|
|
log(passingArguments);
|
|
const that = this;
|
|
return function() {
|
|
const preminJs =
|
|
`'use strict';
|
|
(() => {
|
|
${locals.map((k) => `const ${k} = this.${k};`).join('\n\t')}
|
|
${Object.keys(passingArguments).map(name => `let ${name} = passingArguments.${name};`).join('\n\t')}
|
|
${js}
|
|
})();`;
|
|
log('='.repeat(80) + 'preminjs');
|
|
log(preminJs);
|
|
const newJs = minify(preminJs);
|
|
log('='.repeat(80) + 'minjs');
|
|
log(newJs);
|
|
// newJs should inject into result...
|
|
let result;
|
|
eval(newJs);
|
|
return result;
|
|
}.call(context);
|
|
} |