@loopback/context 1.23.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/binding-config.js +1 -1
  3. package/dist/binding-config.js.map +1 -1
  4. package/dist/binding-filter.d.ts +19 -1
  5. package/dist/binding-filter.js +40 -7
  6. package/dist/binding-filter.js.map +1 -1
  7. package/dist/binding-inspector.js +12 -11
  8. package/dist/binding-inspector.js.map +1 -1
  9. package/dist/binding-sorter.js +2 -2
  10. package/dist/binding-sorter.js.map +1 -1
  11. package/dist/binding.d.ts +42 -4
  12. package/dist/binding.js +40 -10
  13. package/dist/binding.js.map +1 -1
  14. package/dist/context-event.d.ts +23 -0
  15. package/dist/context-event.js +7 -0
  16. package/dist/context-event.js.map +1 -0
  17. package/dist/context-observer.d.ts +1 -36
  18. package/dist/context-subscription.d.ts +147 -0
  19. package/dist/context-subscription.js +336 -0
  20. package/dist/context-subscription.js.map +1 -0
  21. package/dist/context-tag-indexer.d.ts +42 -0
  22. package/dist/context-tag-indexer.js +134 -0
  23. package/dist/context-tag-indexer.js.map +1 -0
  24. package/dist/context-view.d.ts +2 -1
  25. package/dist/context-view.js +5 -2
  26. package/dist/context-view.js.map +1 -1
  27. package/dist/context.d.ts +35 -66
  28. package/dist/context.js +78 -250
  29. package/dist/context.js.map +1 -1
  30. package/dist/index.d.ts +5 -3
  31. package/dist/index.js +4 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/inject-config.js +3 -3
  34. package/dist/inject-config.js.map +1 -1
  35. package/dist/inject.d.ts +2 -2
  36. package/dist/inject.js +18 -11
  37. package/dist/inject.js.map +1 -1
  38. package/dist/interception-proxy.d.ts +15 -3
  39. package/dist/interception-proxy.js +20 -4
  40. package/dist/interception-proxy.js.map +1 -1
  41. package/dist/interceptor-chain.js +5 -2
  42. package/dist/interceptor-chain.js.map +1 -1
  43. package/dist/interceptor.d.ts +6 -0
  44. package/dist/interceptor.js +38 -12
  45. package/dist/interceptor.js.map +1 -1
  46. package/dist/invocation.d.ts +20 -2
  47. package/dist/invocation.js +14 -12
  48. package/dist/invocation.js.map +1 -1
  49. package/dist/keys.d.ts +6 -0
  50. package/dist/keys.js +6 -0
  51. package/dist/keys.js.map +1 -1
  52. package/dist/resolution-session.d.ts +1 -0
  53. package/dist/resolution-session.js +13 -6
  54. package/dist/resolution-session.js.map +1 -1
  55. package/dist/resolver.js +13 -8
  56. package/dist/resolver.js.map +1 -1
  57. package/dist/value-promise.d.ts +1 -3
  58. package/package.json +9 -9
  59. package/src/binding-config.ts +1 -1
  60. package/src/binding-filter.ts +61 -9
  61. package/src/binding-inspector.ts +6 -8
  62. package/src/binding-sorter.ts +2 -2
  63. package/src/binding.ts +73 -9
  64. package/src/context-event.ts +30 -0
  65. package/src/context-observer.ts +1 -38
  66. package/src/context-subscription.ts +403 -0
  67. package/src/context-tag-indexer.ts +149 -0
  68. package/src/context-view.ts +3 -6
  69. package/src/context.ts +94 -293
  70. package/src/index.ts +5 -3
  71. package/src/inject-config.ts +3 -3
  72. package/src/inject.ts +19 -10
  73. package/src/interception-proxy.ts +25 -3
  74. package/src/interceptor-chain.ts +1 -1
  75. package/src/interceptor.ts +34 -8
  76. package/src/invocation.ts +26 -7
  77. package/src/keys.ts +7 -0
  78. package/src/resolution-session.ts +9 -5
  79. package/src/resolver.ts +5 -5
  80. package/src/value-promise.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  import { Binding } from './binding';
2
2
  import { BindingFilter } from './binding-filter';
3
- import { ValueOrPromise } from './value-promise';
4
3
  import { Context } from './context';
4
+ import { ValueOrPromise } from './value-promise';
5
5
  /**
6
6
  * Context event types. We support `bind` and `unbind` for now but
7
7
  * keep it open for new types
@@ -34,38 +34,3 @@ export interface ContextObserver {
34
34
  * Context event observer type - An instance of `ContextObserver` or a function
35
35
  */
36
36
  export declare type ContextEventObserver = ContextObserver | ContextObserverFn;
37
- /**
38
- * Subscription of context events. It's modeled after
39
- * https://github.com/tc39/proposal-observable.
40
- */
41
- export interface Subscription {
42
- /**
43
- * unsubscribe
44
- */
45
- unsubscribe(): void;
46
- /**
47
- * Is the subscription closed?
48
- */
49
- closed: boolean;
50
- }
51
- /**
52
- * Event data for observer notifications
53
- */
54
- export declare type Notification = {
55
- /**
56
- * Context event type - bind/unbind
57
- */
58
- eventType: ContextEventType;
59
- /**
60
- * Binding added/removed
61
- */
62
- binding: Readonly<Binding<unknown>>;
63
- /**
64
- * Owner context for the binding
65
- */
66
- context: Context;
67
- /**
68
- * A snapshot of observers when the original event is emitted
69
- */
70
- observers: Set<ContextEventObserver>;
71
- };
@@ -0,0 +1,147 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { Context } from './context';
4
+ import { ContextEvent, ContextEventListener } from './context-event';
5
+ import { ContextEventObserver, ContextObserver } from './context-observer';
6
+ /**
7
+ * Subscription of context events. It's modeled after
8
+ * https://github.com/tc39/proposal-observable.
9
+ */
10
+ export 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
+ */
23
+ export 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
+ */
32
+ export 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
+ }
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2020. All Rights Reserved.
3
+ // Node module: @loopback/context
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
7
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
8
+ var m = o[Symbol.asyncIterator], i;
9
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
10
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
11
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const debug_1 = __importDefault(require("debug"));
18
+ const events_1 = require("events");
19
+ const debug = debug_1.default('loopback:context:subscription');
20
+ /**
21
+ * Polyfill Symbol.asyncIterator as required by TypeScript for Node 8.x.
22
+ * See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html
23
+ */
24
+ if (!Symbol.asyncIterator) {
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ Symbol.asyncIterator = Symbol.for('Symbol.asyncIterator');
27
+ }
28
+ /**
29
+ * WARNING: This following import must happen after the polyfill. The
30
+ * `auto-import` by an IDE such as VSCode may move the import before the
31
+ * polyfill. It must be then fixed manually.
32
+ */
33
+ const p_event_1 = require("p-event");
34
+ /**
35
+ * An implementation of `Subscription` interface for context events
36
+ */
37
+ class ContextSubscription {
38
+ constructor(context, observer) {
39
+ this.context = context;
40
+ this.observer = observer;
41
+ this._closed = false;
42
+ }
43
+ unsubscribe() {
44
+ this.context.unsubscribe(this.observer);
45
+ this._closed = true;
46
+ }
47
+ get closed() {
48
+ return this._closed;
49
+ }
50
+ }
51
+ /**
52
+ * Manager for context observer subscriptions
53
+ */
54
+ class ContextSubscriptionManager extends events_1.EventEmitter {
55
+ constructor(context) {
56
+ super();
57
+ this.context = context;
58
+ /**
59
+ * Internal counter for pending notification events which are yet to be
60
+ * processed by observers.
61
+ */
62
+ this.pendingNotifications = 0;
63
+ this.setMaxListeners(Infinity);
64
+ }
65
+ /**
66
+ * @internal
67
+ */
68
+ get parentContextEventListener() {
69
+ return this._parentContextEventListener;
70
+ }
71
+ /**
72
+ * @internal
73
+ */
74
+ get observers() {
75
+ return this._observers;
76
+ }
77
+ /**
78
+ * Wrap the debug statement so that it always print out the context name
79
+ * as the prefix
80
+ * @param args - Arguments for the debug
81
+ */
82
+ _debug(...args) {
83
+ /* istanbul ignore if */
84
+ if (!debug.enabled)
85
+ return;
86
+ const formatter = args.shift();
87
+ if (typeof formatter === 'string') {
88
+ debug(`[%s] ${formatter}`, this.context.name, ...args);
89
+ }
90
+ else {
91
+ debug('[%s] ', this.context.name, formatter, ...args);
92
+ }
93
+ }
94
+ /**
95
+ * Set up an internal listener to notify registered observers asynchronously
96
+ * upon `bind` and `unbind` events. This method will be called lazily when
97
+ * the first observer is added.
98
+ */
99
+ setupEventHandlersIfNeeded() {
100
+ if (this.notificationQueue != null)
101
+ return;
102
+ if (this.context.parent != null) {
103
+ /**
104
+ * Add an event listener to its parent context so that this context will
105
+ * be notified of parent events, such as `bind` or `unbind`.
106
+ */
107
+ this._parentContextEventListener = event => {
108
+ this.handleParentEvent(event);
109
+ };
110
+ // Listen on the parent context events
111
+ this.context.parent.on('bind', this._parentContextEventListener);
112
+ this.context.parent.on('unbind', this._parentContextEventListener);
113
+ }
114
+ // The following are two async functions. Returned promises are ignored as
115
+ // they are long-running background tasks.
116
+ this.startNotificationTask().catch(err => {
117
+ this.handleNotificationError(err);
118
+ });
119
+ let ctx = this.context.parent;
120
+ while (ctx) {
121
+ ctx.subscriptionManager.setupEventHandlersIfNeeded();
122
+ ctx = ctx.parent;
123
+ }
124
+ }
125
+ handleParentEvent(event) {
126
+ const { binding, context, type } = event;
127
+ // Propagate the event to this context only if the binding key does not
128
+ // exist in this context. The parent binding is shadowed if there is a
129
+ // binding with the same key in this one.
130
+ if (this.context.contains(binding.key)) {
131
+ this._debug('Event %s %s is not re-emitted from %s to %s', type, binding.key, context.name, this.context.name);
132
+ return;
133
+ }
134
+ this._debug('Re-emitting %s %s from %s to %s', type, binding.key, context.name, this.context.name);
135
+ this.context.emitEvent(type, event);
136
+ }
137
+ /**
138
+ * A strongly-typed method to emit context events
139
+ * @param type Event type
140
+ * @param event Context event
141
+ */
142
+ emitEvent(type, event) {
143
+ this.emit(type, event);
144
+ }
145
+ /**
146
+ * Emit an `error` event
147
+ * @param err Error
148
+ */
149
+ emitError(err) {
150
+ this.emit('error', err);
151
+ }
152
+ /**
153
+ * Start a background task to listen on context events and notify observers
154
+ */
155
+ startNotificationTask() {
156
+ // Set up listeners on `bind` and `unbind` for notifications
157
+ this.setupNotification('bind', 'unbind');
158
+ // Create an async iterator for the `notification` event as a queue
159
+ this.notificationQueue = p_event_1.iterator(this, 'notification');
160
+ return this.processNotifications();
161
+ }
162
+ /**
163
+ * Publish an event to the registered observers. Please note the
164
+ * notification is queued and performed asynchronously so that we allow fluent
165
+ * APIs such as `ctx.bind('key').to(...).tag(...);` and give observers the
166
+ * fully populated binding.
167
+ *
168
+ * @param event - Context event
169
+ * @param observers - Current set of context observers
170
+ */
171
+ async notifyObservers(event, observers = this._observers) {
172
+ if (!observers || observers.size === 0)
173
+ return;
174
+ const { type, binding, context } = event;
175
+ for (const observer of observers) {
176
+ if (typeof observer === 'function') {
177
+ await observer(type, binding, context);
178
+ }
179
+ else if (!observer.filter || observer.filter(binding)) {
180
+ await observer.observe(type, binding, context);
181
+ }
182
+ }
183
+ }
184
+ /**
185
+ * Process notification events as they arrive on the queue
186
+ */
187
+ async processNotifications() {
188
+ var e_1, _a;
189
+ const events = this.notificationQueue;
190
+ if (events == null)
191
+ return;
192
+ try {
193
+ for (var events_2 = __asyncValues(events), events_2_1; events_2_1 = await events_2.next(), !events_2_1.done;) {
194
+ const { type, binding, context, observers } = events_2_1.value;
195
+ // The loop will happen asynchronously upon events
196
+ try {
197
+ // The execution of observers happen in the Promise micro-task queue
198
+ await this.notifyObservers({ type, binding, context }, observers);
199
+ this.pendingNotifications--;
200
+ this._debug('Observers notified for %s of binding %s', type, binding.key);
201
+ this.emitEvent('observersNotified', { type, binding, context });
202
+ }
203
+ catch (err) {
204
+ this.pendingNotifications--;
205
+ this._debug('Error caught from observers', err);
206
+ // Errors caught from observers. Emit it to the current context.
207
+ // If no error listeners are registered, crash the process.
208
+ this.emitError(err);
209
+ }
210
+ }
211
+ }
212
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
213
+ finally {
214
+ try {
215
+ if (events_2_1 && !events_2_1.done && (_a = events_2.return)) await _a.call(events_2);
216
+ }
217
+ finally { if (e_1) throw e_1.error; }
218
+ }
219
+ }
220
+ /**
221
+ * Listen on given event types and emit `notification` event. This method
222
+ * merge multiple event types into one for notification.
223
+ * @param eventTypes - Context event types
224
+ */
225
+ setupNotification(...eventTypes) {
226
+ for (const type of eventTypes) {
227
+ this.context.on(type, ({ binding, context }) => {
228
+ // No need to schedule notifications if no observers are present
229
+ if (!this._observers || this._observers.size === 0)
230
+ return;
231
+ // Track pending events
232
+ this.pendingNotifications++;
233
+ // Take a snapshot of current observers to ensure notifications of this
234
+ // event will only be sent to current ones. Emit a new event to notify
235
+ // current context observers.
236
+ this.emitEvent('notification', {
237
+ type,
238
+ binding,
239
+ context,
240
+ observers: new Set(this._observers),
241
+ });
242
+ });
243
+ }
244
+ }
245
+ /**
246
+ * Wait until observers are notified for all of currently pending notification
247
+ * events.
248
+ *
249
+ * This method is for test only to perform assertions after observers are
250
+ * notified for relevant events.
251
+ */
252
+ async waitUntilPendingNotificationsDone(timeout) {
253
+ const count = this.pendingNotifications;
254
+ if (count === 0)
255
+ return;
256
+ await p_event_1.multiple(this, 'observersNotified', { count, timeout });
257
+ }
258
+ /**
259
+ * Add a context event observer to the context
260
+ * @param observer - Context observer instance or function
261
+ */
262
+ subscribe(observer) {
263
+ var _a;
264
+ this._observers = (_a = this._observers, (_a !== null && _a !== void 0 ? _a : new Set()));
265
+ this.setupEventHandlersIfNeeded();
266
+ this._observers.add(observer);
267
+ return new ContextSubscription(this.context, observer);
268
+ }
269
+ /**
270
+ * Remove the context event observer from the context
271
+ * @param observer - Context event observer
272
+ */
273
+ unsubscribe(observer) {
274
+ if (!this._observers)
275
+ return false;
276
+ return this._observers.delete(observer);
277
+ }
278
+ /**
279
+ * Check if an observer is subscribed to this context
280
+ * @param observer - Context observer
281
+ */
282
+ isSubscribed(observer) {
283
+ if (!this._observers)
284
+ return false;
285
+ return this._observers.has(observer);
286
+ }
287
+ /**
288
+ * Handle errors caught during the notification of observers
289
+ * @param err - Error
290
+ */
291
+ handleNotificationError(err) {
292
+ // Bubbling up the error event over the context chain
293
+ // until we find an error listener
294
+ let ctx = this.context;
295
+ while (ctx) {
296
+ if (ctx.listenerCount('error') === 0) {
297
+ // No error listener found, try its parent
298
+ ctx = ctx.parent;
299
+ continue;
300
+ }
301
+ this._debug('Emitting error to context %s', ctx.name, err);
302
+ ctx.emitError(err);
303
+ return;
304
+ }
305
+ // No context with error listeners found
306
+ this._debug('No error handler is configured for the context chain', err);
307
+ // Let it crash now by emitting an error event
308
+ this.context.emitError(err);
309
+ }
310
+ /**
311
+ * Close the context: clear observers, stop notifications, and remove event
312
+ * listeners from its parent context.
313
+ *
314
+ * @remarks
315
+ * This method MUST be called to avoid memory leaks once a context object is
316
+ * no longer needed and should be recycled. An example is the `RequestContext`,
317
+ * which is created per request.
318
+ */
319
+ close() {
320
+ this._observers = undefined;
321
+ if (this.notificationQueue != null) {
322
+ // Cancel the notification iterator
323
+ this.notificationQueue.return(undefined).catch(err => {
324
+ this.handleNotificationError(err);
325
+ });
326
+ this.notificationQueue = undefined;
327
+ }
328
+ if (this.context.parent && this._parentContextEventListener) {
329
+ this.context.parent.removeListener('bind', this._parentContextEventListener);
330
+ this.context.parent.removeListener('unbind', this._parentContextEventListener);
331
+ this._parentContextEventListener = undefined;
332
+ }
333
+ }
334
+ }
335
+ exports.ContextSubscriptionManager = ContextSubscriptionManager;
336
+ //# sourceMappingURL=context-subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-subscription.js","sourceRoot":"","sources":["../src/context-subscription.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { Binding, BindingTag } from './binding';
2
+ import { Context } from './context';
3
+ import { BoundValue } from './value-promise';
4
+ /**
5
+ * Indexer for context bindings by tag
6
+ */
7
+ export declare class ContextTagIndexer {
8
+ protected readonly context: Context;
9
+ /**
10
+ * Index for bindings by tag names
11
+ */
12
+ readonly bindingsIndexedByTag: Map<string, Set<Readonly<Binding<unknown>>>>;
13
+ /**
14
+ * A listener for binding events
15
+ */
16
+ private bindingEventListener;
17
+ /**
18
+ * A listener to maintain tag index for bindings
19
+ */
20
+ private tagIndexListener;
21
+ constructor(context: Context);
22
+ /**
23
+ * Set up context/binding listeners and refresh index for bindings by tag
24
+ */
25
+ private setupTagIndexForBindings;
26
+ /**
27
+ * Remove tag index for the given binding
28
+ * @param binding - Binding object
29
+ */
30
+ private removeTagIndexForBinding;
31
+ /**
32
+ * Update tag index for the given binding
33
+ * @param binding - Binding object
34
+ */
35
+ private updateTagIndexForBinding;
36
+ /**
37
+ * Find bindings by tag leveraging indexes
38
+ * @param tag - Tag name pattern or name/value pairs
39
+ */
40
+ findByTagIndex<ValueType = BoundValue>(tag: BindingTag | RegExp): Readonly<Binding<ValueType>>[];
41
+ close(): void;
42
+ }