UNPKG

8.47 kBTypeScriptView Raw
1/// <reference types="node" />
2import { EventEmitter } from 'events';
3import { Binding } from './binding';
4import { BindingFilter } from './binding-filter';
5import { BindingComparator } from './binding-sorter';
6import { Context } from './context';
7import { ContextEvent } from './context-event';
8import { ContextEventType, ContextObserver } from './context-observer';
9import { Subscription } from './context-subscription';
10import { Getter } from './inject';
11import { ResolutionOptions, ResolutionOptionsOrSession, ResolutionSession } from './resolution-session';
12import { ValueOrPromise } from './value-promise';
13/**
14 * An event emitted by a `ContextView`
15 */
16export interface ContextViewEvent<T> extends ContextEvent {
17 /**
18 * Optional cached value for an `unbind` event
19 */
20 cachedValue?: T;
21}
22/**
23 * `ContextView` provides a view for a given context chain to maintain a live
24 * list of matching bindings and their resolved values within the context
25 * hierarchy.
26 *
27 * This class is the key utility to implement dynamic extensions for extension
28 * points. For example, the RestServer can react to `controller` bindings even
29 * they are added/removed/updated after the application starts.
30 *
31 * `ContextView` is an event emitter that emits the following events:
32 * - 'bind': when a binding is added to the view
33 * - 'unbind': when a binding is removed from the view
34 * - 'close': when the view is closed (stopped observing context events)
35 * - 'refresh': when the view is refreshed as bindings are added/removed
36 * - 'resolve': when the cached values are resolved and updated
37 */
38export declare class ContextView<T = unknown> extends EventEmitter implements ContextObserver {
39 readonly context: Context;
40 readonly filter: BindingFilter;
41 readonly comparator?: BindingComparator | undefined;
42 private resolutionOptions?;
43 /**
44 * An array of cached bindings that matches the binding filter
45 */
46 protected _cachedBindings: Readonly<Binding<T>>[] | undefined;
47 /**
48 * A map of cached values by binding
49 */
50 protected _cachedValues: Map<Readonly<Binding<T>>, T> | undefined;
51 private _subscription;
52 /**
53 * Create a context view
54 * @param context - Context object to watch
55 * @param filter - Binding filter to match bindings of interest
56 * @param comparator - Comparator to sort the matched bindings
57 */
58 constructor(context: Context, filter: BindingFilter, comparator?: BindingComparator | undefined, resolutionOptions?: Omit<ResolutionOptions, "session"> | undefined);
59 /**
60 * Update the cached values keyed by binding
61 * @param values - An array of resolved values
62 */
63 private updateCachedValues;
64 /**
65 * Get an array of cached values
66 */
67 private getCachedValues;
68 /**
69 * Start listening events from the context
70 */
71 open(): Subscription | undefined;
72 /**
73 * Stop listening events from the context
74 */
75 close(): void;
76 /**
77 * Get the list of matched bindings. If they are not cached, it tries to find
78 * them from the context.
79 */
80 get bindings(): Readonly<Binding<T>>[];
81 /**
82 * Find matching bindings and refresh the cache
83 */
84 protected findBindings(): Readonly<Binding<T>>[];
85 /**
86 * Listen on `bind` or `unbind` and invalidate the cache
87 */
88 observe(event: ContextEventType, binding: Readonly<Binding<unknown>>, context: Context): void;
89 /**
90 * Refresh the view by invalidating its cache
91 */
92 refresh(): void;
93 /**
94 * Resolve values for the matching bindings
95 * @param session - Resolution session
96 */
97 resolve(session?: ResolutionOptionsOrSession): ValueOrPromise<T[]>;
98 /**
99 * Get the list of resolved values. If they are not cached, it tries to find
100 * and resolve them.
101 */
102 values(session?: ResolutionOptionsOrSession): Promise<T[]>;
103 /**
104 * As a `Getter` function
105 */
106 asGetter(session?: ResolutionOptionsOrSession): Getter<T[]>;
107 /**
108 * Get the single value
109 */
110 singleValue(session?: ResolutionOptionsOrSession): Promise<T | undefined>;
111 /**
112 * The "bind" event is emitted when a new binding is added to the view.
113 *
114 * @param eventName The name of the event - always `bind`.
115 * @param listener The listener function to call when the event is emitted.
116 */
117 on(eventName: 'bind', listener: <V>(event: ContextViewEvent<V>) => void): this;
118 /**
119 * The "unbind" event is emitted a new binding is removed from the view.
120 *
121 * @param eventName The name of the event - always `unbind`.
122 * @param listener The listener function to call when the event is emitted.
123 */
124 on(eventName: 'unbind', listener: <V>(event: ContextViewEvent<V> & {
125 cachedValue?: V;
126 }) => void): this;
127 /**
128 * The "refresh" event is emitted when the view is refreshed as bindings are
129 * added/removed.
130 *
131 * @param eventName The name of the event - always `refresh`.
132 * @param listener The listener function to call when the event is emitted.
133 */
134 on(eventName: 'refresh', listener: () => void): this;
135 /**
136 * The "resolve" event is emitted when the cached values are resolved and
137 * updated.
138 *
139 * @param eventName The name of the event - always `refresh`.
140 * @param listener The listener function to call when the event is emitted.
141 */
142 on(eventName: 'refresh', listener: <V>(result: V[]) => void): this;
143 /**
144 * The "close" event is emitted when the view is closed (stopped observing
145 * context events)
146 *
147 * @param eventName The name of the event - always `close`.
148 * @param listener The listener function to call when the event is emitted.
149 */
150 on(eventName: 'close', listener: () => void): this;
151 on(event: string | symbol, listener: (...args: any[]) => void): this;
152 /**
153 * The "bind" event is emitted when a new binding is added to the view.
154 *
155 * @param eventName The name of the event - always `bind`.
156 * @param listener The listener function to call when the event is emitted.
157 */
158 once(eventName: 'bind', listener: <V>(event: ContextViewEvent<V>) => void): this;
159 /**
160 * The "unbind" event is emitted a new binding is removed from the view.
161 *
162 * @param eventName The name of the event - always `unbind`.
163 * @param listener The listener function to call when the event is emitted.
164 */
165 once(eventName: 'unbind', listener: <V>(event: ContextViewEvent<V> & {
166 cachedValue?: V;
167 }) => void): this;
168 /**
169 * The "refresh" event is emitted when the view is refreshed as bindings are
170 * added/removed.
171 *
172 * @param eventName The name of the event - always `refresh`.
173 * @param listener The listener function to call when the event is emitted.
174 */
175 once(eventName: 'refresh', listener: () => void): this;
176 /**
177 * The "resolve" event is emitted when the cached values are resolved and
178 * updated.
179 *
180 * @param eventName The name of the event - always `refresh`.
181 * @param listener The listener function to call when the event is emitted.
182 */
183 once(eventName: 'refresh', listener: <V>(result: V[]) => void): this;
184 /**
185 * The "close" event is emitted when the view is closed (stopped observing
186 * context events)
187 *
188 * @param eventName The name of the event - always `close`.
189 * @param listener The listener function to call when the event is emitted.
190 */
191 once(eventName: 'close', listener: () => void): this;
192 once(event: string | symbol, listener: (...args: any[]) => void): this;
193}
194/**
195 * Create a context view as a getter with the given filter
196 * @param ctx - Context object
197 * @param bindingFilter - A function to match bindings
198 * @param session - Resolution session
199 */
200export declare function createViewGetter<T = unknown>(ctx: Context, bindingFilter: BindingFilter, session?: ResolutionSession): Getter<T[]>;
201/**
202 * Create a context view as a getter with the given filter and sort matched
203 * bindings by the comparator.
204 * @param ctx - Context object
205 * @param bindingFilter - A function to match bindings
206 * @param bindingComparator - A function to compare two bindings
207 * @param session - Resolution session
208 */
209export declare function createViewGetter<T = unknown>(ctx: Context, bindingFilter: BindingFilter, bindingComparator?: BindingComparator, session?: ResolutionOptionsOrSession): Getter<T[]>;