///
import { EventEmitter } from 'events';
import { Context } from './context';
import { ContextEvent, ContextEventListener } from './context-event';
import { ContextEventObserver, ContextObserver } from './context-observer';
/**
* Subscription of context events. It's modeled after
* https://github.com/tc39/proposal-observable.
*/
export interface Subscription {
/**
* unsubscribe
*/
unsubscribe(): void;
/**
* Is the subscription closed?
*/
closed: boolean;
}
/**
* Event data for observer notifications
*/
export interface Notification extends ContextEvent {
/**
* A snapshot of observers when the original event is emitted
*/
observers: Set;
}
/**
* Manager for context observer subscriptions
*/
export declare class ContextSubscriptionManager extends EventEmitter {
protected readonly context: Context;
/**
* A listener to watch parent context events
*/
protected _parentContextEventListener?: ContextEventListener;
/**
* A list of registered context observers. The Set will be created when the
* first observer is added.
*/
protected _observers: Set | undefined;
/**
* Internal counter for pending notification events which are yet to be
* processed by observers.
*/
private pendingNotifications;
/**
* Queue for background notifications for observers
*/
private notificationQueue;
constructor(context: Context);
/**
* @internal
*/
get parentContextEventListener(): ContextEventListener | undefined;
/**
* @internal
*/
get observers(): Set | undefined;
/**
* Wrap the debug statement so that it always print out the context name
* as the prefix
* @param args - Arguments for the debug
*/
private _debug;
/**
* Set up an internal listener to notify registered observers asynchronously
* upon `bind` and `unbind` events. This method will be called lazily when
* the first observer is added.
*/
private setupEventHandlersIfNeeded;
private handleParentEvent;
/**
* A strongly-typed method to emit context events
* @param type Event type
* @param event Context event
*/
private emitEvent;
/**
* Emit an `error` event
* @param err Error
*/
private emitError;
/**
* Start a background task to listen on context events and notify observers
*/
private startNotificationTask;
/**
* Publish an event to the registered observers. Please note the
* notification is queued and performed asynchronously so that we allow fluent
* APIs such as `ctx.bind('key').to(...).tag(...);` and give observers the
* fully populated binding.
*
* @param event - Context event
* @param observers - Current set of context observers
*/
protected notifyObservers(event: ContextEvent, observers?: Set | undefined): Promise;
/**
* Process notification events as they arrive on the queue
*/
private processNotifications;
/**
* Listen on given event types and emit `notification` event. This method
* merge multiple event types into one for notification.
* @param eventTypes - Context event types
*/
private setupNotification;
/**
* Wait until observers are notified for all of currently pending notification
* events.
*
* This method is for test only to perform assertions after observers are
* notified for relevant events.
*/
waitUntilPendingNotificationsDone(timeout?: number): Promise;
/**
* Add a context event observer to the context
* @param observer - Context observer instance or function
*/
subscribe(observer: ContextEventObserver): Subscription;
/**
* Remove the context event observer from the context
* @param observer - Context event observer
*/
unsubscribe(observer: ContextEventObserver): boolean;
/**
* Check if an observer is subscribed to this context
* @param observer - Context observer
*/
isSubscribed(observer: ContextObserver): boolean;
/**
* Handle errors caught during the notification of observers
* @param err - Error
*/
private handleNotificationError;
/**
* Close the context: clear observers, stop notifications, and remove event
* listeners from its parent context.
*
* @remarks
* This method MUST be called to avoid memory leaks once a context object is
* no longer needed and should be recycled. An example is the `RequestContext`,
* which is created per request.
*/
close(): void;
}