UNPKG

@ima/core

Version:

IMA.js framework for isomorphic javascript application

123 lines (122 loc) 4.16 kB
import { Observable } from './Observable'; import { RouterEvents } from '../router/RouterEvents'; const MAX_HISTORY_LENGTH = 10; /** * An Observable is a class that manages event listeners and allows distributing * events to the registered listeners. It maintains a history of events and supports * persistent events that are not cleared during route changes. * * @remarks * - The Observable class relies on a Dispatcher to handle the actual event distribution. * - It maintains a history of events, which can be limited by a maximum history length. */ export class ObservableImpl extends Observable { _dispatcher; _observers; _activityHistory; _persistentEvents; _settings; static $dependencies = [ '$Dispatcher', '?$Settings.$Observable' ]; /** * Creates an instance of Observable. * * @param dispatcher - The dispatcher responsible for managing event listeners. * @param settings - Optional settings for the Observable instance. */ constructor(dispatcher, settings){ super(); this._dispatcher = dispatcher; this._observers = new Map(); this._activityHistory = new Map(); this._persistentEvents = new Set(); this._settings = settings; } /** * @inheritDoc */ init() { this.clear(); this._dispatcher.listenAll(this._handleDispatcherEvent, this); return this; } /** * @inheritDoc */ destroy() { this.clear(); this._dispatcher.unlistenAll(this._handleDispatcherEvent, this); return this; } /** * @inheritDoc */ clear() { this._persistentEvents.clear(); this._observers.clear(); this._activityHistory.clear(); return this; } /** * @inheritDoc */ registerPersistenEvent(event) { this._persistentEvents.add(event); return this; } /** * @inheritDoc */ subscribe(event, observer, scope) { if (!this._observers.has(event)) { this._observers.set(event, new Map()); } if (!this._observers.get(event).has(observer)) { this._observers.get(event).set(observer, new Set()); } this._observers.get(event).get(observer).add(scope); if (this._activityHistory.has(event)) { this._activityHistory.get(event).forEach((data)=>observer.bind(scope)(data)); } return this; } /** * @inheritDoc */ unsubscribe(event, observer, scope) { if (!this._observers.has(event)) { return this; } if (!this._observers.get(event).has(observer)) { return this; } this._observers.get(event).get(observer).delete(scope); if (this._observers.get(event).get(observer).size === 0) { this._observers.get(event).delete(observer); } return this; } /** * Handles dispatcher events by updating the activity history and notifying observers. * It also resets the activity history for non-persistent events on `BEFORE_HANDLE_ROUTE` ecvent. * * @param event - The name of the event being dispatched. * @param data - The data associated with the event. */ _handleDispatcherEvent(event, data) { if (event === RouterEvents.BEFORE_HANDLE_ROUTE) { for (const [eventKey] of this._activityHistory){ if (!this._persistentEvents.has(eventKey)) { this._activityHistory.delete(eventKey); } } } if (!this._activityHistory.has(event)) { this._activityHistory.set(event, []); } this._activityHistory.get(event).push(data); this._activityHistory.set(event, this._activityHistory.get(event).splice(-(this._settings?.maxHistoryLength || MAX_HISTORY_LENGTH))); if (!this._observers.has(event)) { return; } for (const [observer, scopes] of this._observers.get(event).entries()){ for (const scope of scopes){ observer.bind(scope)(data); } } } } //# sourceMappingURL=ObservableImpl.js.map