UNPKG

@davidcal/fec-raptorq

Version:

Node.js wrapper for RaptorQ forward error correction

72 lines (61 loc) 1.92 kB
import { as_async } from "./as_async.js"; import { bind_callable } from "./bind_callable.js"; import { bind_self } from "./bind_self.js"; import { callable } from "./callable.js"; import { named_function } from "./named_function.js"; /** * @stability 2 - provisional * * Creates an async factory for a class such that its `_init` method is called and awaited before the instantiated object is returned. * * @example * * class Api { * constructor(foo, bar) { ... } * * async _init() { * await some_initialization_logic(); * } * * ... * } * * export const create_api = create_async_factory(Api); */ export const create_async_factory = (cls) => { if (cls.prototype._call !== undefined) { // This makes debugging nicer because the original object will be a function and so it will not wrapped by a function down the road (which is otherwise accomplished in `callable` using proxies). const orig_cls = cls; cls = named_function(orig_cls.name, function (...args) { const obj = new orig_cls(...args); const result = new Function(); Object.setPrototypeOf(result, cls.prototype); Object.assign(result, obj); return result; }); orig_cls.prototype.constructor = cls; cls.prototype = orig_cls.prototype; Object.setPrototypeOf(cls.prototype, Function.prototype); } return async (...args) => { const obj = new cls(...args); obj._init && await obj._init(...args); const adjusted_obj = obj._call !== undefined ? callable( obj, as_async(function(...args) { return obj._call(...args) }) ) : obj ; const result = new Proxy(adjusted_obj, { get(target, key) { if (typeof target[key] === "function") { return bind_callable(target[key], target); } return target[key]; }, }); return typeof result === "function" ? bind_self(result) : result; }; }; export const createAsyncFactory = create_async_factory;