UNPKG

4.8 kBTypeScriptView Raw
1/// <reference types="node" />
2import { EventEmitter } from 'events';
3import { Context } from './context';
4import { ContextEvent, ContextEventListener } from './context-event';
5import { ContextEventObserver, ContextObserver } from './context-observer';
6/**
7 * Subscription of context events. It's modeled after
8 * https://github.com/tc39/proposal-observable.
9 */
10export interface Subscription {
11 /**
12 * unsubscribe
13 */
14 unsubscribe(): void;
15 /**
16 * Is the subscription closed?
17 */
18 closed: boolean;
19}
20/**
21 * Event data for observer notifications
22 */
23export interface Notification extends ContextEvent {
24 /**
25 * A snapshot of observers when the original event is emitted
26 */
27 observers: Set<ContextEventObserver>;
28}
29/**
30 * Manager for context observer subscriptions
31 */
32export declare class ContextSubscriptionManager extends EventEmitter {
33 protected readonly context: Context;
34 /**
35 * A listener to watch parent context events
36 */
37 protected _parentContextEventListener?: ContextEventListener;
38 /**
39 * A list of registered context observers. The Set will be created when the
40 * first observer is added.
41 */
42 protected _observers: Set<ContextEventObserver> | undefined;
43 /**
44 * Internal counter for pending notification events which are yet to be
45 * processed by observers.
46 */
47 private pendingNotifications;
48 /**
49 * Queue for background notifications for observers
50 */
51 private notificationQueue;
52 constructor(context: Context);
53 /**
54 * @internal
55 */
56 get parentContextEventListener(): ContextEventListener | undefined;
57 /**
58 * @internal
59 */
60 get observers(): Set<ContextEventObserver> | undefined;
61 /**
62 * Wrap the debug statement so that it always print out the context name
63 * as the prefix
64 * @param args - Arguments for the debug
65 */
66 private _debug;
67 /**
68 * Set up an internal listener to notify registered observers asynchronously
69 * upon `bind` and `unbind` events. This method will be called lazily when
70 * the first observer is added.
71 */
72 private setupEventHandlersIfNeeded;
73 private handleParentEvent;
74 /**
75 * A strongly-typed method to emit context events
76 * @param type Event type
77 * @param event Context event
78 */
79 private emitEvent;
80 /**
81 * Emit an `error` event
82 * @param err Error
83 */
84 private emitError;
85 /**
86 * Start a background task to listen on context events and notify observers
87 */
88 private startNotificationTask;
89 /**
90 * Publish an event to the registered observers. Please note the
91 * notification is queued and performed asynchronously so that we allow fluent
92 * APIs such as `ctx.bind('key').to(...).tag(...);` and give observers the
93 * fully populated binding.
94 *
95 * @param event - Context event
96 * @param observers - Current set of context observers
97 */
98 protected notifyObservers(event: ContextEvent, observers?: Set<ContextEventObserver> | undefined): Promise<void>;
99 /**
100 * Process notification events as they arrive on the queue
101 */
102 private processNotifications;
103 /**
104 * Listen on given event types and emit `notification` event. This method
105 * merge multiple event types into one for notification.
106 * @param eventTypes - Context event types
107 */
108 private setupNotification;
109 /**
110 * Wait until observers are notified for all of currently pending notification
111 * events.
112 *
113 * This method is for test only to perform assertions after observers are
114 * notified for relevant events.
115 */
116 waitUntilPendingNotificationsDone(timeout?: number): Promise<void>;
117 /**
118 * Add a context event observer to the context
119 * @param observer - Context observer instance or function
120 */
121 subscribe(observer: ContextEventObserver): Subscription;
122 /**
123 * Remove the context event observer from the context
124 * @param observer - Context event observer
125 */
126 unsubscribe(observer: ContextEventObserver): boolean;
127 /**
128 * Check if an observer is subscribed to this context
129 * @param observer - Context observer
130 */
131 isSubscribed(observer: ContextObserver): boolean;
132 /**
133 * Handle errors caught during the notification of observers
134 * @param err - Error
135 */
136 private handleNotificationError;
137 /**
138 * Close the context: clear observers, stop notifications, and remove event
139 * listeners from its parent context.
140 *
141 * @remarks
142 * This method MUST be called to avoid memory leaks once a context object is
143 * no longer needed and should be recycled. An example is the `RequestContext`,
144 * which is created per request.
145 */
146 close(): void;
147}