streaming
Version:
Transforms and other streaming helpers
91 lines (90 loc) • 3.25 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.VM = void 0;
var vm_1 = require("vm");
var stream_1 = require("stream");
var __null = {
toJSON: function () {
return null;
},
valueOf: function () {
return null;
},
};
/**
code: string
Two important facts about this code:
1. It should process a global variable, `$in`, which represents the
current object in the stream.
2. It should set the global variable `$out`, which represents the
object that will be returned and sent downstream.
context?: any = {}
Results and side effects are tracked in this global context object.
filename?: string = 'streaming.vm'
Used in stack traces.
*/
var VM = /** @class */ (function (_super) {
__extends(VM, _super);
function VM(code, context, filename) {
if (context === void 0) { context = {}; }
if (filename === void 0) { filename = 'streaming.vm'; }
var _this = _super.call(this, { objectMode: true }) || this;
_this.context = context;
_this.filename = filename;
// should new Script(...) be called inside a try-catch?
_this.script = new vm_1.Script(code, { filename: filename });
return _this;
}
/**
each chunk should be a discrete object
encoding should be null
*/
VM.prototype._transform = function (chunk, encoding, callback) {
this.context.$in = chunk;
this.context.$out = undefined;
try {
// I'm not sure why this is not called script.runInContext()
this.script.runInNewContext(this.context);
}
catch (error) {
this.emit('error', error);
}
var result = this.context.$out;
if (result === undefined) {
// skip it; undefined denotes no output
}
else if (result === null) {
// We have to wrap a pure JSON null, because `push(null)` means EOF to streams.
// It's kind of a hack, but it works nicely when we JSON.stringify downstream.
this.push(__null);
}
else {
this.push(result);
}
callback();
};
/**
Run a bit of code once using the streaming.VM's global context.
*/
VM.prototype.run = function (code) {
var filename = this.filename;
return (0, vm_1.runInNewContext)(code, this.context, { filename: filename });
};
return VM;
}(stream_1.Transform));
exports.VM = VM;