UNPKG

@jplorg/jpl

Version:
72 lines (65 loc) 2.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _fatal = _interopRequireDefault(require("./errors/fatal")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** Runtime signal for managing execution lifecycle */ class JPLRuntimeSignal { constructor(parent) { this._parent = parent; this._exited = false; this._subscriptions = {}; this._nextSubscriptionKey = 0; } /** Return the signal's parent */ get parent() { return this._parent; } /** Check whether the current runtime area has been requested to be exited */ get exited() { this._exited ||= this.parent?.exited ?? false; return this._exited; } /** Check that the current runtime area has not been requested to be exited and throw a fatal error otherwise */ checkHealth() { if (this.exited) throw new _fatal.default('execution aborted'); } /** * Request the current runtime area to be exited. * This also involves all child areas (introduced using `JPLRuntimeSignal.next`). */ exit = () => { if (this.exited) return; this._exited = true; Object.values(this._subscriptions).forEach(subscription => { subscription(); }); this._subscriptions = {}; }; /** * Subscribe for when the current runtime area is requested to be exited. * This also involves all parent areas. * The function returns an unsubscription hook which must be called when completed in order to prevent memory leaks. * If the area has already been exited when subscribing, the callback is called immediately after the current event cycle. */ subscribe = cb => { if (this.exited) { setTimeout(cb); return () => {}; } const key = this._nextSubscriptionKey; this._nextSubscriptionKey += 1; this._subscriptions[key] = cb; const unsubscribeParent = (this.parent?.subscribe ?? (() => () => {}))(cb); const unsubscribe = () => { delete this._subscriptions[key]; unsubscribeParent(); }; return unsubscribe; }; /** Inherit the next child area for the current one */ next = () => new JPLRuntimeSignal(this); } var _default = exports.default = JPLRuntimeSignal;