@pawells/rxjs-events 1.0.1 → 1.1.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.
- package/README.md +17 -15
- package/build/async-observable.js +1 -1
- package/build/async-observable.js.map +1 -1
- package/build/event-filter.d.ts +49 -5
- package/build/event-filter.d.ts.map +1 -1
- package/build/event-filter.js +55 -13
- package/build/event-filter.js.map +1 -1
- package/build/event-operators.d.ts +92 -0
- package/build/event-operators.d.ts.map +1 -0
- package/build/event-operators.js +203 -0
- package/build/event-operators.js.map +1 -0
- package/build/event-pipeline.d.ts +96 -0
- package/build/event-pipeline.d.ts.map +1 -0
- package/build/event-pipeline.js +127 -0
- package/build/event-pipeline.js.map +1 -0
- package/build/handler.d.ts +37 -3
- package/build/handler.d.ts.map +1 -1
- package/build/handler.js +42 -4
- package/build/handler.js.map +1 -1
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/nestjs-pubsub.d.ts +171 -0
- package/build/nestjs-pubsub.d.ts.map +1 -0
- package/build/nestjs-pubsub.js +226 -0
- package/build/nestjs-pubsub.js.map +1 -0
- package/package.json +10 -8
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { EventHandler } from './handler.js';
|
|
2
|
+
import { TEventData } from './event-data.js';
|
|
3
|
+
/**
|
|
4
|
+
* Debounces event emission from an EventHandler.
|
|
5
|
+
* Events are delayed until `ms` milliseconds have passed without any new events.
|
|
6
|
+
* Useful for expensive operations triggered by high-frequency events.
|
|
7
|
+
*
|
|
8
|
+
* @template TObject - The object type for the handler
|
|
9
|
+
* @template TEvent - The event type
|
|
10
|
+
* @param handler - EventHandler to debounce events from
|
|
11
|
+
* @param ms - Debounce delay in milliseconds
|
|
12
|
+
* @returns A new EventHandler that emits debounced events
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const handler = new EventHandler<SearchQuery, SearchEvent>('Search');
|
|
17
|
+
* const debounced = DebounceEvents(handler, 300);
|
|
18
|
+
*
|
|
19
|
+
* // Subscribe to the debounced handler
|
|
20
|
+
* debounced.Subscribe((event) => {
|
|
21
|
+
* console.log('Search executed after 300ms of inactivity');
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* handler.Trigger({ query: 'a' });
|
|
25
|
+
* handler.Trigger({ query: 'ab' });
|
|
26
|
+
* handler.Trigger({ query: 'abc' }); // Only this final query will be debounced
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function DebounceEvents<TObject extends object = object, TEvent extends TEventData = TEventData>(handler: EventHandler<TObject, TEvent>, ms: number): EventHandler<TObject, TEvent>;
|
|
30
|
+
/**
|
|
31
|
+
* Throttles event emission from an EventHandler.
|
|
32
|
+
* Events are emitted at most once per `ms` milliseconds.
|
|
33
|
+
* Guarantees that the most recent event is eventually emitted.
|
|
34
|
+
*
|
|
35
|
+
* @template TObject - The object type for the handler
|
|
36
|
+
* @template TEvent - The event type
|
|
37
|
+
* @param handler - EventHandler to throttle events from
|
|
38
|
+
* @param ms - Throttle interval in milliseconds
|
|
39
|
+
* @returns A new EventHandler that emits throttled events
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const handler = new EventHandler<MouseEvent, PositionEvent>('MouseMove');
|
|
44
|
+
* const throttled = ThrottleEvents(handler, 100);
|
|
45
|
+
*
|
|
46
|
+
* throttled.Subscribe((event) => {
|
|
47
|
+
* console.log('Position updated (max once per 100ms)');
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* // High-frequency events will be throttled
|
|
51
|
+
* for (let i = 0; i < 100; i++) {
|
|
52
|
+
* handler.Trigger({ x: i, y: i });
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function ThrottleEvents<TObject extends object = object, TEvent extends TEventData = TEventData>(handler: EventHandler<TObject, TEvent>, ms: number): EventHandler<TObject, TEvent>;
|
|
57
|
+
/**
|
|
58
|
+
* Pipes event payloads through a series of transform functions.
|
|
59
|
+
* Each function receives the output of the previous function and must return a value
|
|
60
|
+
* that can be passed to the next function.
|
|
61
|
+
*
|
|
62
|
+
* @template TEvent - The input event type
|
|
63
|
+
* @template TResult - The final result type after all transforms
|
|
64
|
+
* @param handler - EventHandler to pipe events from
|
|
65
|
+
* @param fns - Transform functions to apply in sequence
|
|
66
|
+
* @returns AsyncIterableIterator of transformed results
|
|
67
|
+
*
|
|
68
|
+
* @remarks
|
|
69
|
+
* Due to the underlying Pipe utility from @pawells/typescript-common accepting `(arg: any) => any`,
|
|
70
|
+
* the transform functions must use implicit typing or explicit any casts. The first function
|
|
71
|
+
* receives the event, and subsequent functions receive the output of the previous function.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* interface MessageEvent extends TEventData {
|
|
76
|
+
* Message: {
|
|
77
|
+
* text: string;
|
|
78
|
+
* userId: string;
|
|
79
|
+
* };
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
* const handler = new EventHandler<any, MessageEvent>('Message');
|
|
83
|
+
*
|
|
84
|
+
* // Transform events through a pipeline: extract → uppercase → log
|
|
85
|
+
* for await (const result of PipeEvents(
|
|
86
|
+
* handler,
|
|
87
|
+
* (event: MessageEvent) => event.Message.text,
|
|
88
|
+
* (text: string) => text.toUpperCase(),
|
|
89
|
+
* (text: string) => `processed: ${text}`
|
|
90
|
+
* )) {
|
|
91
|
+
* console.log(result);
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function PipeEvents<TEvent extends TEventData = TEventData, TResult = any>(handler: EventHandler<any, TEvent>, ...fns: Array<(v: any) => any>): AsyncIterableIterator<TResult>;
|
|
96
|
+
//# sourceMappingURL=event-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-pipeline.d.ts","sourceRoot":"","sources":["../src/event-pipeline.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,EACrG,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,EAAE,EAAE,MAAM,GACR,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAS/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,EACrG,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EACtC,EAAE,EAAE,MAAM,GACR,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAS/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,UAAU,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,GAAG,GAAG,EAC/E,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAClC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC,GAC5B,qBAAqB,CAAC,OAAO,CAAC,CAahC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Debounce, Pipe, Throttle } from '@pawells/typescript-common';
|
|
2
|
+
import { EventHandler } from './handler.js';
|
|
3
|
+
/**
|
|
4
|
+
* Debounces event emission from an EventHandler.
|
|
5
|
+
* Events are delayed until `ms` milliseconds have passed without any new events.
|
|
6
|
+
* Useful for expensive operations triggered by high-frequency events.
|
|
7
|
+
*
|
|
8
|
+
* @template TObject - The object type for the handler
|
|
9
|
+
* @template TEvent - The event type
|
|
10
|
+
* @param handler - EventHandler to debounce events from
|
|
11
|
+
* @param ms - Debounce delay in milliseconds
|
|
12
|
+
* @returns A new EventHandler that emits debounced events
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const handler = new EventHandler<SearchQuery, SearchEvent>('Search');
|
|
17
|
+
* const debounced = DebounceEvents(handler, 300);
|
|
18
|
+
*
|
|
19
|
+
* // Subscribe to the debounced handler
|
|
20
|
+
* debounced.Subscribe((event) => {
|
|
21
|
+
* console.log('Search executed after 300ms of inactivity');
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* handler.Trigger({ query: 'a' });
|
|
25
|
+
* handler.Trigger({ query: 'ab' });
|
|
26
|
+
* handler.Trigger({ query: 'abc' }); // Only this final query will be debounced
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function DebounceEvents(handler, ms) {
|
|
30
|
+
const debouncedHandler = new EventHandler(handler.Name);
|
|
31
|
+
const debouncedTrigger = Debounce((event) => {
|
|
32
|
+
// Extract payload from the event object before triggering to avoid double-wrapping
|
|
33
|
+
const payload = event[handler.Name];
|
|
34
|
+
debouncedHandler.Trigger(payload);
|
|
35
|
+
}, ms);
|
|
36
|
+
handler.Subscribe((event) => debouncedTrigger(event));
|
|
37
|
+
return debouncedHandler;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Throttles event emission from an EventHandler.
|
|
41
|
+
* Events are emitted at most once per `ms` milliseconds.
|
|
42
|
+
* Guarantees that the most recent event is eventually emitted.
|
|
43
|
+
*
|
|
44
|
+
* @template TObject - The object type for the handler
|
|
45
|
+
* @template TEvent - The event type
|
|
46
|
+
* @param handler - EventHandler to throttle events from
|
|
47
|
+
* @param ms - Throttle interval in milliseconds
|
|
48
|
+
* @returns A new EventHandler that emits throttled events
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const handler = new EventHandler<MouseEvent, PositionEvent>('MouseMove');
|
|
53
|
+
* const throttled = ThrottleEvents(handler, 100);
|
|
54
|
+
*
|
|
55
|
+
* throttled.Subscribe((event) => {
|
|
56
|
+
* console.log('Position updated (max once per 100ms)');
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // High-frequency events will be throttled
|
|
60
|
+
* for (let i = 0; i < 100; i++) {
|
|
61
|
+
* handler.Trigger({ x: i, y: i });
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function ThrottleEvents(handler, ms) {
|
|
66
|
+
const throttledHandler = new EventHandler(handler.Name);
|
|
67
|
+
const throttledTrigger = Throttle((event) => {
|
|
68
|
+
// Extract payload from the event object before triggering to avoid double-wrapping
|
|
69
|
+
const payload = event[handler.Name];
|
|
70
|
+
throttledHandler.Trigger(payload);
|
|
71
|
+
}, ms);
|
|
72
|
+
handler.Subscribe((event) => throttledTrigger(event));
|
|
73
|
+
return throttledHandler;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Pipes event payloads through a series of transform functions.
|
|
77
|
+
* Each function receives the output of the previous function and must return a value
|
|
78
|
+
* that can be passed to the next function.
|
|
79
|
+
*
|
|
80
|
+
* @template TEvent - The input event type
|
|
81
|
+
* @template TResult - The final result type after all transforms
|
|
82
|
+
* @param handler - EventHandler to pipe events from
|
|
83
|
+
* @param fns - Transform functions to apply in sequence
|
|
84
|
+
* @returns AsyncIterableIterator of transformed results
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* Due to the underlying Pipe utility from @pawells/typescript-common accepting `(arg: any) => any`,
|
|
88
|
+
* the transform functions must use implicit typing or explicit any casts. The first function
|
|
89
|
+
* receives the event, and subsequent functions receive the output of the previous function.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* interface MessageEvent extends TEventData {
|
|
94
|
+
* Message: {
|
|
95
|
+
* text: string;
|
|
96
|
+
* userId: string;
|
|
97
|
+
* };
|
|
98
|
+
* }
|
|
99
|
+
*
|
|
100
|
+
* const handler = new EventHandler<any, MessageEvent>('Message');
|
|
101
|
+
*
|
|
102
|
+
* // Transform events through a pipeline: extract → uppercase → log
|
|
103
|
+
* for await (const result of PipeEvents(
|
|
104
|
+
* handler,
|
|
105
|
+
* (event: MessageEvent) => event.Message.text,
|
|
106
|
+
* (text: string) => text.toUpperCase(),
|
|
107
|
+
* (text: string) => `processed: ${text}`
|
|
108
|
+
* )) {
|
|
109
|
+
* console.log(result);
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export function PipeEvents(handler, ...fns) {
|
|
114
|
+
return (async function* () {
|
|
115
|
+
if (fns.length === 0) {
|
|
116
|
+
for await (const event of handler) {
|
|
117
|
+
yield event;
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const pipeline = Pipe(...fns);
|
|
122
|
+
for await (const event of handler) {
|
|
123
|
+
yield pipeline(event);
|
|
124
|
+
}
|
|
125
|
+
})();
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=event-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-pipeline.js","sourceRoot":"","sources":["../src/event-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAsC,EACtC,EAAU;IAEV,MAAM,gBAAgB,GAAG,IAAI,YAAY,CAAkB,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,KAAa,EAAE,EAAE;QACnD,mFAAmF;QACnF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAoB,CAAY,CAAC;QAC/D,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,OAAO,gBAAgB,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAsC,EACtC,EAAU;IAEV,MAAM,gBAAgB,GAAG,IAAI,YAAY,CAAkB,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,KAAa,EAAE,EAAE;QACnD,mFAAmF;QACnF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAoB,CAAY,CAAC;QAC/D,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,OAAO,gBAAgB,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,UAAU,CACzB,OAAkC,EAClC,GAAG,GAA2B;IAE9B,OAAO,CAAC,KAAK,SAAS,CAAC;QACtB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBACnC,MAAM,KAAuB,CAAC;YAC/B,CAAC;YACD,OAAO;QACR,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAI,GAAuB,CAAC,CAAC;QACnD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,QAAQ,CAAC,KAAK,CAAY,CAAC;QAClC,CAAC;IACF,CAAC,CAAC,EAAE,CAAC;AACN,CAAC"}
|
package/build/handler.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ import { TEventFunction } from './event-function.js';
|
|
|
8
8
|
* @template TObject - The type of data objects that can be triggered as events
|
|
9
9
|
* @template TEvent - The event data type extending TEventData that will be received by subscribers
|
|
10
10
|
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* **Error Handling:** Subscribe-based handlers log errors to console.error and stop receiving events.
|
|
13
|
+
* For in-band error propagation, use GetAsyncIterableIterator() instead, which throws on errors.
|
|
14
|
+
*
|
|
11
15
|
* @example
|
|
12
16
|
* ```typescript
|
|
13
17
|
* interface MessageData {
|
|
@@ -33,7 +37,7 @@ import { TEventFunction } from './event-function.js';
|
|
|
33
37
|
* // Unsubscribe
|
|
34
38
|
* handler.Unsubscribe(subscription);
|
|
35
39
|
*
|
|
36
|
-
* // Async iteration
|
|
40
|
+
* // Async iteration (propagates errors)
|
|
37
41
|
* for await (const event of handler.GetAsyncIterableIterator()) {
|
|
38
42
|
* console.log('Async event:', event.MessageReceived.text);
|
|
39
43
|
* break; // Important: break to avoid infinite loop
|
|
@@ -49,8 +53,8 @@ export declare class EventHandler<TObject extends object = object, TEvent extend
|
|
|
49
53
|
/**
|
|
50
54
|
* Creates a new EventHandler instance.
|
|
51
55
|
*
|
|
52
|
-
* @param name - The name of the event type to handle. Cannot be empty.
|
|
53
|
-
* @throws {Error} 'Event Name is Empty' - When the provided name is an empty string
|
|
56
|
+
* @param name - The name of the event type to handle. Cannot be empty or whitespace-only.
|
|
57
|
+
* @throws {Error} 'Event Name is Empty' - When the provided name is an empty string or contains only whitespace
|
|
54
58
|
*
|
|
55
59
|
* @example
|
|
56
60
|
* ```typescript
|
|
@@ -221,5 +225,35 @@ export declare class EventHandler<TObject extends object = object, TEvent extend
|
|
|
221
225
|
* ```
|
|
222
226
|
*/
|
|
223
227
|
Destroy(): void;
|
|
228
|
+
/**
|
|
229
|
+
* Gets the total count of active subscriptions.
|
|
230
|
+
*
|
|
231
|
+
* @returns The number of currently active subscriptions
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* const handler = new EventHandler('TestEvent');
|
|
236
|
+
* handler.Subscribe((event) => { });
|
|
237
|
+
* handler.Subscribe((event) => { });
|
|
238
|
+
* console.log(handler.GetSubscriptionCount()); // 2
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
GetSubscriptionCount(): number;
|
|
242
|
+
/**
|
|
243
|
+
* Gets all subscription IDs that are currently active.
|
|
244
|
+
* The returned array is a snapshot of active IDs at the time of the call.
|
|
245
|
+
*
|
|
246
|
+
* @returns Array of active subscription IDs
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* const handler = new EventHandler('TestEvent');
|
|
251
|
+
* const id1 = handler.Subscribe((event) => { });
|
|
252
|
+
* const id2 = handler.Subscribe((event) => { });
|
|
253
|
+
* const ids = handler.GetActiveSubscriptionIds();
|
|
254
|
+
* console.log(ids); // [0, 1] or similar
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
GetActiveSubscriptionIds(): number[];
|
|
224
258
|
}
|
|
225
259
|
//# sourceMappingURL=handler.d.ts.map
|
package/build/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,YAAY,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU;IAChG;;;OAGG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;;;;;;;;;;OAWG;gBACS,IAAI,EAAE,MAAM;IAKxB,oEAAoE;IACpE,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAmC;IAEtF;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAEhE,uEAAuE;IACvE,OAAO,CAAC,OAAO,CAAa;IAE5B,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IAEnE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACY,wBAAwB,IAAI,qBAAqB,CAAC,MAAM,CAAC;IAsExE;;;;;;;;;;;;;;;;;;OAkBG;IACI,gBAAgB,IAAI,aAAa,CAAC,MAAM,CAAC;IAIhD;;;;;;;;;;;OAWG;IACI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,MAAM,CAAC;IAI9D;;;;;;;;;;;;;;;;;OAiBG;IACI,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAKnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACI,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,MAAM;IA6BzD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAW9C;;;;;;;;;;OAUG;IACI,OAAO,IAAI,IAAI;IAatB;;;;;;;;;;;;OAYG;IACI,oBAAoB,IAAI,MAAM;IAIrC;;;;;;;;;;;;;;OAcG;IACI,wBAAwB,IAAI,MAAM,EAAE;CAG3C"}
|
package/build/handler.js
CHANGED
|
@@ -6,6 +6,10 @@ import { Subject } from 'rxjs';
|
|
|
6
6
|
* @template TObject - The type of data objects that can be triggered as events
|
|
7
7
|
* @template TEvent - The event data type extending TEventData that will be received by subscribers
|
|
8
8
|
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* **Error Handling:** Subscribe-based handlers log errors to console.error and stop receiving events.
|
|
11
|
+
* For in-band error propagation, use GetAsyncIterableIterator() instead, which throws on errors.
|
|
12
|
+
*
|
|
9
13
|
* @example
|
|
10
14
|
* ```typescript
|
|
11
15
|
* interface MessageData {
|
|
@@ -31,7 +35,7 @@ import { Subject } from 'rxjs';
|
|
|
31
35
|
* // Unsubscribe
|
|
32
36
|
* handler.Unsubscribe(subscription);
|
|
33
37
|
*
|
|
34
|
-
* // Async iteration
|
|
38
|
+
* // Async iteration (propagates errors)
|
|
35
39
|
* for await (const event of handler.GetAsyncIterableIterator()) {
|
|
36
40
|
* console.log('Async event:', event.MessageReceived.text);
|
|
37
41
|
* break; // Important: break to avoid infinite loop
|
|
@@ -47,8 +51,8 @@ export class EventHandler {
|
|
|
47
51
|
/**
|
|
48
52
|
* Creates a new EventHandler instance.
|
|
49
53
|
*
|
|
50
|
-
* @param name - The name of the event type to handle. Cannot be empty.
|
|
51
|
-
* @throws {Error} 'Event Name is Empty' - When the provided name is an empty string
|
|
54
|
+
* @param name - The name of the event type to handle. Cannot be empty or whitespace-only.
|
|
55
|
+
* @throws {Error} 'Event Name is Empty' - When the provided name is an empty string or contains only whitespace
|
|
52
56
|
*
|
|
53
57
|
* @example
|
|
54
58
|
* ```typescript
|
|
@@ -58,7 +62,7 @@ export class EventHandler {
|
|
|
58
62
|
*/
|
|
59
63
|
constructor(name) {
|
|
60
64
|
this.Name = name;
|
|
61
|
-
if (this.Name.length === 0)
|
|
65
|
+
if (this.Name.length === 0 || !this.Name.trim())
|
|
62
66
|
throw new Error('Event Name is Empty');
|
|
63
67
|
}
|
|
64
68
|
/** Internal map storing active subscriptions by their unique IDs */
|
|
@@ -337,5 +341,39 @@ export class EventHandler {
|
|
|
337
341
|
this._subscriptions.clear();
|
|
338
342
|
this._AvailableIds.clear();
|
|
339
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Gets the total count of active subscriptions.
|
|
346
|
+
*
|
|
347
|
+
* @returns The number of currently active subscriptions
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```typescript
|
|
351
|
+
* const handler = new EventHandler('TestEvent');
|
|
352
|
+
* handler.Subscribe((event) => { });
|
|
353
|
+
* handler.Subscribe((event) => { });
|
|
354
|
+
* console.log(handler.GetSubscriptionCount()); // 2
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
GetSubscriptionCount() {
|
|
358
|
+
return this._subscriptions.size;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Gets all subscription IDs that are currently active.
|
|
362
|
+
* The returned array is a snapshot of active IDs at the time of the call.
|
|
363
|
+
*
|
|
364
|
+
* @returns Array of active subscription IDs
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```typescript
|
|
368
|
+
* const handler = new EventHandler('TestEvent');
|
|
369
|
+
* const id1 = handler.Subscribe((event) => { });
|
|
370
|
+
* const id2 = handler.Subscribe((event) => { });
|
|
371
|
+
* const ids = handler.GetActiveSubscriptionIds();
|
|
372
|
+
* console.log(ids); // [0, 1] or similar
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
GetActiveSubscriptionIds() {
|
|
376
|
+
return Array.from(this._subscriptions.keys());
|
|
377
|
+
}
|
|
340
378
|
}
|
|
341
379
|
//# sourceMappingURL=handler.js.map
|
package/build/handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgB,MAAM,MAAM,CAAC;AAI7C
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgB,MAAM,MAAM,CAAC;AAI7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,OAAO,YAAY;IACxB;;;OAGG;IACa,IAAI,CAAS;IAE7B;;;;;;;;;;;OAWG;IACH,YAAY,IAAY;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzF,CAAC;IAED,oEAAoE;IAC1D,cAAc,GAA8B,IAAI,GAAG,EAAwB,CAAC;IAEtF;;;;;OAKG;IACc,aAAa,GAAgB,IAAI,GAAG,EAAU,CAAC;IAEhE,uEAAuE;IAC/D,OAAO,GAAW,CAAC,CAAC;IAE5B,mDAAmD;IAClC,QAAQ,GAAoB,IAAI,OAAO,EAAU,CAAC;IAEnE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,KAAK,CAAC,CAAE,wBAAwB;QACtC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,OAAiC,CAAC;QACtC,IAAI,MAAgD,CAAC;QACrD,IAAI,OAAkC,CAAC;QACvC,IAAI,KAAc,CAAC;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5C,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;gBACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClB,IAAI,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,CAAC;oBACV,OAAO,GAAG,SAAS,CAAC;oBACpB,MAAM,GAAG,SAAS,CAAC;oBACnB,OAAO,GAAG,SAAS,CAAC;gBACrB,CAAC;YACF,CAAC;YACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,GAAG,GAAG,CAAC;gBACZ,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO,GAAG,SAAS,CAAC;oBACpB,MAAM,GAAG,SAAS,CAAC;oBACnB,OAAO,GAAG,SAAS,CAAC;gBACrB,CAAC;YACF,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACd,IAAI,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,CAAC;oBACV,OAAO,GAAG,SAAS,CAAC;oBACpB,MAAM,GAAG,SAAS,CAAC;oBACnB,OAAO,GAAG,SAAS,CAAC;gBACrB,CAAC;YACF,CAAC;SACD,CAAC,CAAC;QAEH,IAAI,CAAC;YACJ,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;gBAC7B,IAAI,QAAQ,EAAE,CAAC;oBACd,MAAM,KAAK,CAAC;gBACb,CAAC;gBAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxB,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACxC,OAAO,GAAG,GAAG,CAAC;wBACd,MAAM,GAAG,GAAG,CAAC;oBACd,CAAC,CAAC,CAAC;oBACH,MAAM,OAAO,CAAC;gBACf,CAAC;gBAED,IAAI,QAAQ,EAAE,CAAC;oBACd,MAAM,KAAK,CAAC;gBACb,CAAC;gBAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;oBAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;wBACzB,MAAM,KAAK,CAAC;oBACb,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,MAAM;gBACP,CAAC;YACF,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,YAAY,CAAC,WAAW,EAAE,CAAC;QAC5B,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACI,gBAAgB;QACtB,OAAO,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;OAWG;IACI,CAAC,MAAM,CAAC,aAAa,CAAC;QAC5B,OAAO,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACxC,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACI,OAAO,CAAC,IAAa;QAC3B,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAY,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACI,SAAS,CAAC,OAA+B;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YACnC,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACd,6DAA6D;gBAC7D,wFAAwF;gBACxF,4DAA4D;gBAC5D,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;YACxD,CAAC;SACD,CAAC,CAAC;QAEH,4CAA4C;QAC5C,IAAI,EAAU,CAAC;QAEf,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACjC,yCAAyC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC7C,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAe,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,0CAA0C;YAC1C,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YAClB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACjC,OAAO,EAAE,CAAC;IACX,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,WAAW,CAAC,YAAoB;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG;YAAE,OAAO;QAEjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACzC,GAAG,CAAC,WAAW,EAAE,CAAC;QAElB,oEAAoE;QACpE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;;;;;OAUG;IACI,OAAO;QACb,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAEzB,uCAAuC;QACvC,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YACzD,YAAY,CAAC,WAAW,EAAE,CAAC;QAC5B,CAAC;QAED,4CAA4C;QAC5C,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,oBAAoB;QAC1B,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;IACjC,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACI,wBAAwB;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;CACD"}
|
package/build/index.d.ts
CHANGED
|
@@ -6,4 +6,7 @@ export * from './extract-event-payload.js';
|
|
|
6
6
|
export * from './event-filter.js';
|
|
7
7
|
export * from './handler.js';
|
|
8
8
|
export * from './async-observable.js';
|
|
9
|
+
export * from './event-operators.js';
|
|
10
|
+
export * from './event-pipeline.js';
|
|
11
|
+
export * from './nestjs-pubsub.js';
|
|
9
12
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,qBAAqB,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAElC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,qBAAqB,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAElC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -4,4 +4,7 @@ export * from './event-filter.js';
|
|
|
4
4
|
// IAsyncGeneratorESN is an implementation detail of AsyncObservable; not re-exported here.
|
|
5
5
|
export * from './handler.js';
|
|
6
6
|
export * from './async-observable.js';
|
|
7
|
+
export * from './event-operators.js';
|
|
8
|
+
export * from './event-pipeline.js';
|
|
9
|
+
export * from './nestjs-pubsub.js';
|
|
7
10
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,2FAA2F;AAC3F,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,2FAA2F;AAC3F,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PubSub engine interface compatible with NestJS GraphQL subscriptions.
|
|
3
|
+
* Defines the contract that must be implemented for GraphQL subscription handling.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* This interface is defined locally to avoid a dependency on the graphql-subscriptions package.
|
|
7
|
+
* It implements the standard PubSubEngine interface used by NestJS GraphQL.
|
|
8
|
+
*/
|
|
9
|
+
export interface IPubSubEngine {
|
|
10
|
+
/**
|
|
11
|
+
* Publishes a message to a specific trigger channel.
|
|
12
|
+
* @param triggerName - The name of the trigger to publish to
|
|
13
|
+
* @param payload - The payload to publish
|
|
14
|
+
*/
|
|
15
|
+
publish(triggerName: string, payload: any): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribes to messages on a trigger channel.
|
|
18
|
+
* @param triggerName - The name of the trigger to subscribe to
|
|
19
|
+
* @param onMessage - Callback function when a message is received
|
|
20
|
+
* @param options - Optional subscription options
|
|
21
|
+
* @returns A subscription ID that can be used to unsubscribe
|
|
22
|
+
*/
|
|
23
|
+
subscribe(triggerName: string, onMessage: (payload: any) => void, options?: Record<string, unknown>): Promise<number>;
|
|
24
|
+
/**
|
|
25
|
+
* Unsubscribes from a trigger channel using the subscription ID.
|
|
26
|
+
* @param subId - The subscription ID returned from subscribe()
|
|
27
|
+
*/
|
|
28
|
+
unsubscribe(subId: number): void;
|
|
29
|
+
/**
|
|
30
|
+
* Creates an async iterator for one or more trigger channels.
|
|
31
|
+
* Used by GraphQL subscriptions to iterate over published values.
|
|
32
|
+
* @param triggers - Single trigger name or array of trigger names to listen to
|
|
33
|
+
* @returns AsyncIterableIterator that yields published payloads
|
|
34
|
+
*/
|
|
35
|
+
asyncIterator<T = any>(triggers: string | string[]): AsyncIterableIterator<T>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Adapter that makes EventHandler compatible with NestJS GraphQL @Subscription() decorators.
|
|
39
|
+
* Implements the IPubSubEngine interface for pub/sub messaging patterns.
|
|
40
|
+
*
|
|
41
|
+
* This adapter bridges EventHandler with GraphQL subscriptions by maintaining a map of
|
|
42
|
+
* EventHandlers (one per trigger name) and coordinating subscription/publication.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* - No external dependencies required (graphql-subscriptions not needed)
|
|
46
|
+
* - Each trigger name gets its own EventHandler for isolation
|
|
47
|
+
* - Thread-safe subscription ID management
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* // In your NestJS GraphQL module:
|
|
52
|
+
* import { EventHandlerPubSub } from '@pawells/rxjs-events';
|
|
53
|
+
*
|
|
54
|
+
* const pubSub = new EventHandlerPubSub();
|
|
55
|
+
*
|
|
56
|
+
* // In a GraphQL resolver:
|
|
57
|
+
* @Subscription(() => MessagePayload, {
|
|
58
|
+
* resolve: (payload) => payload,
|
|
59
|
+
* })
|
|
60
|
+
* messageSent(): AsyncIterableIterator<MessagePayload> {
|
|
61
|
+
* return pubSub.asyncIterator<MessagePayload>('MESSAGE_SENT');
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* // In a mutation:
|
|
65
|
+
* @Mutation(() => MessagePayload)
|
|
66
|
+
* sendMessage(@Args('text') text: string): MessagePayload {
|
|
67
|
+
* const payload = { text, timestamp: Date.now() };
|
|
68
|
+
* pubSub.publish('MESSAGE_SENT', payload);
|
|
69
|
+
* return payload;
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare class EventHandlerPubSub implements IPubSubEngine {
|
|
74
|
+
/**
|
|
75
|
+
* Map storing EventHandlers indexed by trigger name.
|
|
76
|
+
* Each trigger maintains its own handler for event isolation.
|
|
77
|
+
*/
|
|
78
|
+
private readonly _handlers;
|
|
79
|
+
/**
|
|
80
|
+
* Map storing handler subscriptions and their IDs for cleanup.
|
|
81
|
+
* Maps subscription ID to [handler, subscription ID within handler].
|
|
82
|
+
*/
|
|
83
|
+
private readonly _subscriptions;
|
|
84
|
+
/**
|
|
85
|
+
* Counter for generating unique subscription IDs across all triggers.
|
|
86
|
+
*/
|
|
87
|
+
private _nextSubscriptionId;
|
|
88
|
+
/**
|
|
89
|
+
* Gets or creates an EventHandler for a specific trigger name.
|
|
90
|
+
*
|
|
91
|
+
* @param triggerName - The trigger channel name
|
|
92
|
+
* @returns The EventHandler for this trigger
|
|
93
|
+
*/
|
|
94
|
+
private _getOrCreateHandler;
|
|
95
|
+
/**
|
|
96
|
+
* Publishes a payload to all subscribers of a trigger.
|
|
97
|
+
*
|
|
98
|
+
* @param triggerName - The trigger channel name
|
|
99
|
+
* @param payload - The payload to publish
|
|
100
|
+
*/
|
|
101
|
+
publish(triggerName: string, payload: any): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Subscribes to a trigger channel and calls the callback when messages are published.
|
|
104
|
+
*
|
|
105
|
+
* @param triggerName - The trigger channel name
|
|
106
|
+
* @param onMessage - Callback function that receives the published payload
|
|
107
|
+
* @param _options - Optional subscription options (not used in current implementation)
|
|
108
|
+
* @returns Unique subscription ID for later unsubscription
|
|
109
|
+
*/
|
|
110
|
+
subscribe(triggerName: string, onMessage: (payload: any) => void, _options?: Record<string, unknown>): Promise<number>;
|
|
111
|
+
/**
|
|
112
|
+
* Unsubscribes from a trigger channel.
|
|
113
|
+
*
|
|
114
|
+
* @param subId - The subscription ID returned from subscribe()
|
|
115
|
+
*/
|
|
116
|
+
unsubscribe(subId: number): void;
|
|
117
|
+
/**
|
|
118
|
+
* Creates an async iterator for one or more trigger channels.
|
|
119
|
+
* Useful for GraphQL subscription resolvers.
|
|
120
|
+
*
|
|
121
|
+
* @template T - The type of values yielded by the iterator
|
|
122
|
+
* @param triggers - Single trigger name or array of trigger names
|
|
123
|
+
* @returns AsyncIterableIterator that yields published payloads
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* // Subscribe to a single trigger
|
|
128
|
+
* const iterator = pubSub.asyncIterator('USER_CREATED');
|
|
129
|
+
*
|
|
130
|
+
* // Subscribe to multiple triggers
|
|
131
|
+
* const iterator = pubSub.asyncIterator(['USER_CREATED', 'USER_UPDATED']);
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
asyncIterator<T = any>(triggers: string | string[]): AsyncIterableIterator<T>;
|
|
135
|
+
/**
|
|
136
|
+
* Merges async iterators from multiple trigger handlers.
|
|
137
|
+
* Events from any trigger are yielded as they arrive.
|
|
138
|
+
*
|
|
139
|
+
* @template T - The type of values yielded
|
|
140
|
+
* @param triggers - Array of trigger names
|
|
141
|
+
* @returns Merged async iterator that yields events from all triggers concurrently
|
|
142
|
+
*/
|
|
143
|
+
private _mergeAsyncIterators;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Wraps an async iterator with a filter predicate for use with GraphQL subscriptions.
|
|
147
|
+
* Mirrors the withFilter helper from graphql-subscriptions.
|
|
148
|
+
*
|
|
149
|
+
* @template T - The type of values in the iterator
|
|
150
|
+
* @param asyncIteratorFn - Function that returns an async iterator
|
|
151
|
+
* @param filterFn - Predicate function that determines which values to yield (async functions supported)
|
|
152
|
+
* @returns Filtered async iterator
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const pubSub = new EventHandlerPubSub();
|
|
157
|
+
*
|
|
158
|
+
* // In a GraphQL resolver:
|
|
159
|
+
* @Subscription(() => UserPayload)
|
|
160
|
+
* userUpdated(
|
|
161
|
+
* @Args('userId') userId: string
|
|
162
|
+
* ): AsyncIterableIterator<UserPayload> {
|
|
163
|
+
* return WithFilter(
|
|
164
|
+
* () => pubSub.asyncIterator<UserPayload>('USER_UPDATED'),
|
|
165
|
+
* (payload: UserPayload) => payload.userId === userId
|
|
166
|
+
* );
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export declare function WithFilter<T>(asyncIteratorFn: () => AsyncIterableIterator<T>, filterFn: (payload: T) => boolean | Promise<boolean>): AsyncIterableIterator<T>;
|
|
171
|
+
//# sourceMappingURL=nestjs-pubsub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs-pubsub.d.ts","sourceRoot":"","sources":["../src/nestjs-pubsub.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtH;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;;;;OAKG;IACH,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;CAC9E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACvD;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;IAE5E;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4D;IAE3F;;OAEG;IACH,OAAO,CAAC,mBAAmB,CAAK;IAEhC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;;;OAKG;IACU,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE;;;;;;;OAOG;IACU,SAAS,CACrB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,MAAM,CAAC;IAYlB;;;;OAIG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IASvC;;;;;;;;;;;;;;;;OAgBG;IACI,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,qBAAqB,CAAC,CAAC,CAAC;IAoBpF;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;CA6C5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC3B,eAAe,EAAE,MAAM,qBAAqB,CAAC,CAAC,CAAC,EAC/C,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAClD,qBAAqB,CAAC,CAAC,CAAC,CAa1B"}
|