UNPKG

@skyway-sdk/common

Version:

The official Next Generation JavaScript SDK for SkyWay

138 lines 4.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventDisposer = exports.Events = exports.Event = void 0; const logger_1 = require("./logger"); const log = new logger_1.Logger('packages/common/src/event.ts'); class Event { /**@internal */ constructor(_onSetListener = () => { }) { this._onSetListener = _onSetListener; this._stack = []; this._eventIndex = 0; /**@internal */ this.emit = (arg) => { for (const task of this._stack) { try { task.execute(arg); } catch (error) { log.error('task throws error', error); } } }; /**@internal */ this.removeAllListeners = () => { this._stack = []; }; /**@internal */ this.pipe = (event) => { return this.add((arg) => event.emit(arg)); }; /** * イベントが起きた時に実行する関数を登録する。 * 戻り値として関数の登録を解除する関数が帰ってくる */ this.add = (callback) => { const id = this._eventIndex; this._stack.push({ execute: callback, id }); this._eventIndex++; const removeListener = () => { this._stack = this._stack.filter((item) => item.id !== id && item); }; const disposer = (disposer) => { disposer.push(removeListener); }; this._onSetListener(); return { removeListener, disposer }; }; /**イベントが起きた時に一度だけ実行される関数を登録する */ this.once = (callback) => { const off = this.add((arg) => { off.removeListener(); callback(arg); }); return off; }; /** * イベントが起きた時に Promise が resolve される * @param timeLimit ms */ this.asPromise = (timeLimit) => new Promise((resolve, reject) => { const timeout = timeLimit && setTimeout(() => { reject(new SerializableError('Event asPromise timeout : ' + timeLimit)); }, timeLimit); this.once((arg) => { if (timeout) clearTimeout(timeout); resolve(arg); }); }); /** * イベントが起きた時に実行される boolean を返す関数を登録する。 * 登録した関数が true を返した時に Promise が resolve される * */ this.watch = (callback, /**ms */ timeLimit) => new Promise((resolve, reject) => { const timeout = timeLimit && setTimeout(() => { reject(new SerializableError('Event watch timeout : ' + timeLimit)); }, timeLimit); const { removeListener } = this.add((arg) => { const done = callback(arg); if (done) { if (timeout) clearTimeout(timeout); removeListener(); resolve(arg); } }); }); } /**@internal */ get length() { return this._stack.length; } } exports.Event = Event; /**@internal */ class Events { constructor() { this.events = []; } make() { const event = new Event(); this.events.push(event); return event; } dispose() { this.events.forEach((event) => event.removeAllListeners()); this.events = []; } } exports.Events = Events; /**@internal */ class EventDisposer { constructor() { this._disposer = []; } push(disposer) { this._disposer.push(disposer); } dispose() { this._disposer.forEach((d) => d()); this._disposer = []; } } exports.EventDisposer = EventDisposer; class SerializableError extends Error { toJSON() { return { name: this.name, message: this.message, stack: this.stack, }; } } //# sourceMappingURL=event.js.map