UNPKG

kobp

Version:
102 lines 3.52 kB
import { AsyncLocalStorage } from 'async_hooks'; import { env } from './env'; const isDebug = env.b('KOBP_DEBUG', false); const _storage = new AsyncLocalStorage(); const _roomRegistries = {}; if (isDebug) { console.log('RCTX initialized, >>>>>>>>>>>>>>>>>>> this should appear only ONCE. >>>>>>>>>>>>>>>>>>>'); } /** * Marking any class to be available when resource is being created. * * - Automatically register to `RequestContextCreator` * * Once registered the class will automaticall enabled by the `keyName` provided. * which can be accessed through: * * `RequestRoomProvider.shared.currentInstance(keyName or classConstructor)` */ export function RequestContextEnabled(keyName) { return function (constructor) { constructor.prototype.__rctx_enabled = keyName; if (isDebug) { console.log(`RCTX RequestContextEnabled (decorator) registered: ${keyName} with`, constructor); } _roomRegistries[keyName] = constructor; }; } export class KobpRequestRoom { constructor(context) { this.id = KobpRequestRoom.counter++; // FIXME: Enhance this to a lazy context using ProxyObject. this.data = new Map(); for (const regKey in _roomRegistries) { const cnstr = _roomRegistries[regKey]; this.set(regKey, new cnstr(context)); } if (isDebug) { console.log(`RCTX KobpRequestRoom #${this.id} created with data of size: ${this.data.size}`); } } get(key) { const v = this.data[key]; if (isDebug) { console.log(`RCTX KobpRequestRoom #${this.id} get(${key}) ${v}.`); } return v; } set(key, data) { if (isDebug) { console.log(`RCTX KobpRequestRoom #${this.id} has been set with ${key}. ${data}`); } this.data[key] = data; } free() { if (isDebug) { console.log(`RCTX KobpRequestRoom #${this.id} of size ${[...this.data.keys()].join(', ')} has been freed.`); } this.data.clear(); } } KobpRequestRoom.counter = 1; /** * A factory for `KobpRequestRoom` */ export class RequestRoomProvider { constructor() { if (isDebug) { console.log(`RCTX RoomProvider. This should be called only once. If you see this message multiple times. Then something is wrong..`); } } static get shared() { return this._instance ?? (this._instance = new RequestRoomProvider()); } // Entry point for Middleware (Koa) to call. createAsync(_ctx, next) { const rctx = new KobpRequestRoom(_ctx); if (isDebug) { console.log(`RCTX RoomProvider.createAsync. RoomContext created.`); } return _storage.run(rctx, next).finally(rctx.free.bind(rctx)); } current() { if (isDebug) { console.log(`RCTX RoomProvider.current(). _storage.getStore()`, _storage.getStore()); } return _storage.getStore(); } static instanceOf(keyOrCnstr) { return RequestRoomProvider.shared.currentInstance(keyOrCnstr); } currentInstance(key) { if (typeof key === 'string') { return this.current()?.get(key); } const cnstrEnabledKey = key.prototype.__rctx_enabled; if (!cnstrEnabledKey) { throw new Error('Class does not decorated as RequestContextEnabled'); } return this.current()?.get(cnstrEnabledKey); } } //# sourceMappingURL=RequestContext.js.map