@pawells/rxjs-events 1.0.1 → 1.0.3
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/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 +67 -10
- 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 +227 -0
- package/build/event-operators.js.map +1 -0
- package/build/event-pipeline.d.ts +91 -0
- package/build/event-pipeline.d.ts.map +1 -0
- package/build/event-pipeline.js +118 -0
- package/build/event-pipeline.js.map +1 -0
- package/build/handler.d.ts +30 -0
- package/build/handler.d.ts.map +1 -1
- package/build/handler.js +34 -0
- 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 +207 -0
- package/build/nestjs-pubsub.js.map +1 -0
- package/package.json +5 -4
|
@@ -183,7 +183,7 @@ export class AsyncObservable extends Observable {
|
|
|
183
183
|
subscription?.unsubscribe();
|
|
184
184
|
// Resolve all pending next() promises so callers are not left hanging.
|
|
185
185
|
handleComplete();
|
|
186
|
-
return Promise.resolve({ done: true, value:
|
|
186
|
+
return Promise.resolve({ done: true, value: undefined });
|
|
187
187
|
},
|
|
188
188
|
throw: (err) => {
|
|
189
189
|
subscription?.unsubscribe();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-observable.js","sourceRoot":"","sources":["../src/async-observable.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"async-observable.js","sourceRoot":"","sources":["../src/async-observable.ts"],"names":[],"mappings":"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"}
|
package/build/event-filter.d.ts
CHANGED
|
@@ -3,10 +3,15 @@ import { IFilterCriteria } from './filter-criteria.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Filters events based on payload property matching criteria.
|
|
5
5
|
* Performs strict equality comparison between event payload properties and filter arguments.
|
|
6
|
+
* Supports nested property paths using dot notation and predicate functions.
|
|
6
7
|
*
|
|
7
8
|
* @template TEvent - The event data type extending TEventData
|
|
8
9
|
* @param event - The event to filter, must have exactly one property representing the event type
|
|
9
|
-
* @param args - Filter criteria object with property-value pairs to match against the event payload
|
|
10
|
+
* @param args - Filter criteria object with property-value pairs to match against the event payload.
|
|
11
|
+
* Values can be:
|
|
12
|
+
* - Primitives: matched via strict equality
|
|
13
|
+
* - Functions: treated as predicates that must return true
|
|
14
|
+
* - Keys can use dot notation for nested paths (e.g., 'user.profile.role')
|
|
10
15
|
* @returns true if the event matches all filter criteria or if no filter is provided, false otherwise
|
|
11
16
|
*
|
|
12
17
|
* @throws {Error} 'No Event' - When event is null or undefined
|
|
@@ -20,20 +25,36 @@ import { IFilterCriteria } from './filter-criteria.js';
|
|
|
20
25
|
* userId: string;
|
|
21
26
|
* username: string;
|
|
22
27
|
* role: string;
|
|
28
|
+
* profile: {
|
|
29
|
+
* age: number;
|
|
30
|
+
* status: string;
|
|
31
|
+
* };
|
|
23
32
|
* };
|
|
24
33
|
* }
|
|
25
34
|
*
|
|
26
35
|
* const event: UserEvent = {
|
|
27
|
-
* UserCreated: {
|
|
36
|
+
* UserCreated: {
|
|
37
|
+
* userId: '123',
|
|
38
|
+
* username: 'john',
|
|
39
|
+
* role: 'admin',
|
|
40
|
+
* profile: { age: 30, status: 'active' }
|
|
41
|
+
* }
|
|
28
42
|
* };
|
|
29
43
|
*
|
|
30
44
|
* // Match by single property
|
|
31
45
|
* EventFilter(event, { role: 'admin' }); // true
|
|
32
46
|
* EventFilter(event, { role: 'user' }); // false
|
|
33
47
|
*
|
|
34
|
-
* // Match by
|
|
35
|
-
* EventFilter(event, {
|
|
36
|
-
* EventFilter(event, {
|
|
48
|
+
* // Match by nested path
|
|
49
|
+
* EventFilter(event, { 'profile.age': 30 }); // true
|
|
50
|
+
* EventFilter(event, { 'profile.status': 'active' }); // true
|
|
51
|
+
*
|
|
52
|
+
* // Match by predicate function
|
|
53
|
+
* EventFilter(event, { 'profile.age': (v) => v > 18 }); // true
|
|
54
|
+
* EventFilter(event, { role: (r) => r === 'admin' }); // true
|
|
55
|
+
*
|
|
56
|
+
* // Multiple criteria
|
|
57
|
+
* EventFilter(event, { role: 'admin', 'profile.age': (v) => v > 18 }); // true
|
|
37
58
|
*
|
|
38
59
|
* // No filter (always passes)
|
|
39
60
|
* EventFilter(event, null); // true
|
|
@@ -41,4 +62,27 @@ import { IFilterCriteria } from './filter-criteria.js';
|
|
|
41
62
|
* ```
|
|
42
63
|
*/
|
|
43
64
|
export declare function EventFilter<TEvent extends TEventData = TEventData>(event: TEvent, args: IFilterCriteria | null | undefined): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Partitions an event into matching and non-matching tuples based on filter criteria.
|
|
67
|
+
* Uses EventFilter internally to apply the filtering logic.
|
|
68
|
+
*
|
|
69
|
+
* @template TEvent - The event data type extending TEventData
|
|
70
|
+
* @param event - The event to partition
|
|
71
|
+
* @param args - Filter criteria (same as EventFilter)
|
|
72
|
+
* @returns Tuple of [matching event, non-matching event] where non-matching is null if event matches
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const event: UserEvent = {
|
|
77
|
+
* UserCreated: { userId: '123', username: 'john', role: 'admin' }
|
|
78
|
+
* };
|
|
79
|
+
*
|
|
80
|
+
* const [match, noMatch] = PartitionEventFilter(event, { role: 'admin' });
|
|
81
|
+
* // match = event, noMatch = null
|
|
82
|
+
*
|
|
83
|
+
* const [match2, noMatch2] = PartitionEventFilter(event, { role: 'user' });
|
|
84
|
+
* // match2 = null, noMatch2 = event
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function PartitionEventFilter<TEvent extends TEventData = TEventData>(event: TEvent, args: IFilterCriteria | null | undefined): [TEvent | null, TEvent | null];
|
|
44
88
|
//# sourceMappingURL=event-filter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-filter.d.ts","sourceRoot":"","sources":["../src/event-filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-filter.d.ts","sourceRoot":"","sources":["../src/event-filter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EACjE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACtC,OAAO,CAiCT;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EAC1E,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACtC,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAGhC"}
|
package/build/event-filter.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import { ObjectGetPropertyByPath } from '@pawells/typescript-common';
|
|
1
2
|
/**
|
|
2
3
|
* Filters events based on payload property matching criteria.
|
|
3
4
|
* Performs strict equality comparison between event payload properties and filter arguments.
|
|
5
|
+
* Supports nested property paths using dot notation and predicate functions.
|
|
4
6
|
*
|
|
5
7
|
* @template TEvent - The event data type extending TEventData
|
|
6
8
|
* @param event - The event to filter, must have exactly one property representing the event type
|
|
7
|
-
* @param args - Filter criteria object with property-value pairs to match against the event payload
|
|
9
|
+
* @param args - Filter criteria object with property-value pairs to match against the event payload.
|
|
10
|
+
* Values can be:
|
|
11
|
+
* - Primitives: matched via strict equality
|
|
12
|
+
* - Functions: treated as predicates that must return true
|
|
13
|
+
* - Keys can use dot notation for nested paths (e.g., 'user.profile.role')
|
|
8
14
|
* @returns true if the event matches all filter criteria or if no filter is provided, false otherwise
|
|
9
15
|
*
|
|
10
16
|
* @throws {Error} 'No Event' - When event is null or undefined
|
|
@@ -18,20 +24,36 @@
|
|
|
18
24
|
* userId: string;
|
|
19
25
|
* username: string;
|
|
20
26
|
* role: string;
|
|
27
|
+
* profile: {
|
|
28
|
+
* age: number;
|
|
29
|
+
* status: string;
|
|
30
|
+
* };
|
|
21
31
|
* };
|
|
22
32
|
* }
|
|
23
33
|
*
|
|
24
34
|
* const event: UserEvent = {
|
|
25
|
-
* UserCreated: {
|
|
35
|
+
* UserCreated: {
|
|
36
|
+
* userId: '123',
|
|
37
|
+
* username: 'john',
|
|
38
|
+
* role: 'admin',
|
|
39
|
+
* profile: { age: 30, status: 'active' }
|
|
40
|
+
* }
|
|
26
41
|
* };
|
|
27
42
|
*
|
|
28
43
|
* // Match by single property
|
|
29
44
|
* EventFilter(event, { role: 'admin' }); // true
|
|
30
45
|
* EventFilter(event, { role: 'user' }); // false
|
|
31
46
|
*
|
|
32
|
-
* // Match by
|
|
33
|
-
* EventFilter(event, {
|
|
34
|
-
* EventFilter(event, {
|
|
47
|
+
* // Match by nested path
|
|
48
|
+
* EventFilter(event, { 'profile.age': 30 }); // true
|
|
49
|
+
* EventFilter(event, { 'profile.status': 'active' }); // true
|
|
50
|
+
*
|
|
51
|
+
* // Match by predicate function
|
|
52
|
+
* EventFilter(event, { 'profile.age': (v) => v > 18 }); // true
|
|
53
|
+
* EventFilter(event, { role: (r) => r === 'admin' }); // true
|
|
54
|
+
*
|
|
55
|
+
* // Multiple criteria
|
|
56
|
+
* EventFilter(event, { role: 'admin', 'profile.age': (v) => v > 18 }); // true
|
|
35
57
|
*
|
|
36
58
|
* // No filter (always passes)
|
|
37
59
|
* EventFilter(event, null); // true
|
|
@@ -47,7 +69,7 @@ export function EventFilter(event, args) {
|
|
|
47
69
|
// Identify Payload Key
|
|
48
70
|
const eventKeys = Object.keys(event);
|
|
49
71
|
if (eventKeys.length === 0)
|
|
50
|
-
throw new Error('
|
|
72
|
+
throw new Error('Event object must have exactly one top-level key, but received an empty object ({}).');
|
|
51
73
|
if (eventKeys.length > 1)
|
|
52
74
|
throw new Error('More than one payload structure.');
|
|
53
75
|
const eventKey = eventKeys[0];
|
|
@@ -56,11 +78,46 @@ export function EventFilter(event, args) {
|
|
|
56
78
|
if (!payload)
|
|
57
79
|
throw new Error('No Payload');
|
|
58
80
|
for (const [key, filterValue] of Object.entries(args)) {
|
|
59
|
-
//
|
|
60
|
-
const payloadValue = payload
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
// Support nested paths using dot notation
|
|
82
|
+
const payloadValue = ObjectGetPropertyByPath(payload, key);
|
|
83
|
+
// Support predicate functions as filter values
|
|
84
|
+
if (typeof filterValue === 'function') {
|
|
85
|
+
const predicate = filterValue;
|
|
86
|
+
if (!predicate(payloadValue))
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Standard equality check
|
|
91
|
+
if (payloadValue !== filterValue)
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
63
94
|
}
|
|
64
95
|
return true;
|
|
65
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Partitions an event into matching and non-matching tuples based on filter criteria.
|
|
99
|
+
* Uses EventFilter internally to apply the filtering logic.
|
|
100
|
+
*
|
|
101
|
+
* @template TEvent - The event data type extending TEventData
|
|
102
|
+
* @param event - The event to partition
|
|
103
|
+
* @param args - Filter criteria (same as EventFilter)
|
|
104
|
+
* @returns Tuple of [matching event, non-matching event] where non-matching is null if event matches
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const event: UserEvent = {
|
|
109
|
+
* UserCreated: { userId: '123', username: 'john', role: 'admin' }
|
|
110
|
+
* };
|
|
111
|
+
*
|
|
112
|
+
* const [match, noMatch] = PartitionEventFilter(event, { role: 'admin' });
|
|
113
|
+
* // match = event, noMatch = null
|
|
114
|
+
*
|
|
115
|
+
* const [match2, noMatch2] = PartitionEventFilter(event, { role: 'user' });
|
|
116
|
+
* // match2 = null, noMatch2 = event
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export function PartitionEventFilter(event, args) {
|
|
120
|
+
const matches = EventFilter(event, args);
|
|
121
|
+
return matches ? [event, null] : [null, event];
|
|
122
|
+
}
|
|
66
123
|
//# sourceMappingURL=event-filter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-filter.js","sourceRoot":"","sources":["../src/event-filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-filter.js","sourceRoot":"","sources":["../src/event-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAKrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAM,UAAU,WAAW,CAC1B,KAAa,EACb,IAAwC;IAExC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IACxC,oEAAoE;IACpE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,uBAAuB;IACvB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAErC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;IACpI,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAE9E,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAiB,CAAC;IAE9C,mCAAmC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAiC,CAAC;IAEhE,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAE5C,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,0CAA0C;QAC1C,MAAM,YAAY,GAAG,uBAAuB,CAAC,OAAkC,EAAE,GAAG,CAAC,CAAC;QAEtF,+CAA+C;QAC/C,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,WAA0C,CAAC;YAC7D,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC5C,CAAC;aAAM,CAAC;YACP,0BAA0B;YAC1B,IAAI,YAAY,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAC;QAChD,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,oBAAoB,CACnC,KAAa,EACb,IAAwC;IAExC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { EventHandler } from './handler.js';
|
|
2
|
+
import { TEventData } from './event-data.js';
|
|
3
|
+
/**
|
|
4
|
+
* Collects events into batches of a specified size and yields each batch as an array.
|
|
5
|
+
* The final batch may be smaller if the total number of events is not a multiple of the batch size.
|
|
6
|
+
*
|
|
7
|
+
* @template TEvent - The event type
|
|
8
|
+
* @param handler - EventHandler to collect events from
|
|
9
|
+
* @param size - Size of each batch (must be > 0)
|
|
10
|
+
* @returns AsyncIterableIterator that yields arrays of events
|
|
11
|
+
*
|
|
12
|
+
* @throws {RangeError} When size is <= 0
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const handler = new EventHandler<MessageData, MessageEvent>('Message');
|
|
17
|
+
*
|
|
18
|
+
* // Batch events in groups of 5
|
|
19
|
+
* for await (const batch of ChunkEvents(handler, 5)) {
|
|
20
|
+
* console.log(`Processing batch of ${batch.length} events`);
|
|
21
|
+
* batch.forEach(event => processEvent(event));
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function ChunkEvents<TEvent extends TEventData = TEventData>(handler: EventHandler<any, TEvent>, size: number): AsyncIterableIterator<TEvent[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Partitions an event stream into two separate async iterators: one for matching events and one for non-matching.
|
|
28
|
+
* The predicate function determines which iterator receives each event.
|
|
29
|
+
*
|
|
30
|
+
* @template TEvent - The event type
|
|
31
|
+
* @param handler - EventHandler to partition events from
|
|
32
|
+
* @param predicate - Function that determines if an event matches (true = matching, false = non-matching)
|
|
33
|
+
* @returns Tuple of [matching iterator, non-matching iterator]
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const handler = new EventHandler<UserEvent, UserEvent>('UserCreated');
|
|
38
|
+
*
|
|
39
|
+
* // Split events by admin status
|
|
40
|
+
* const [admins, users] = PartitionEvents(handler, (event) => {
|
|
41
|
+
* return 'UserCreated' in event && event.UserCreated.role === 'admin';
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* // Process matching (admin) events
|
|
45
|
+
* for await (const event of admins) {
|
|
46
|
+
* console.log('Admin created:', event);
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* // Process non-matching (regular user) events in parallel
|
|
50
|
+
* for await (const event of users) {
|
|
51
|
+
* console.log('User created:', event);
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function PartitionEvents<TEvent extends TEventData = TEventData>(handler: EventHandler<any, TEvent>, predicate: (event: TEvent) => boolean): [AsyncIterableIterator<TEvent>, AsyncIterableIterator<TEvent>];
|
|
56
|
+
/**
|
|
57
|
+
* Groups events by a key function and yields each group as a Map when the group reaches a specified size.
|
|
58
|
+
* Groups are keyed by the result of applying the key function to each event.
|
|
59
|
+
*
|
|
60
|
+
* @template TEvent - The event type
|
|
61
|
+
* @template TKey - The type of the grouping key
|
|
62
|
+
* @param handler - EventHandler to group events from
|
|
63
|
+
* @param keyFn - Function that extracts the grouping key from an event
|
|
64
|
+
* @param flushSize - Number of events needed to trigger a flush of a group
|
|
65
|
+
* @returns AsyncIterableIterator that yields Maps of grouped events
|
|
66
|
+
*
|
|
67
|
+
* @throws {RangeError} When flushSize is <= 0
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* interface UserEvent extends TEventData {
|
|
72
|
+
* UserActivity: {
|
|
73
|
+
* userId: string;
|
|
74
|
+
* action: string;
|
|
75
|
+
* timestamp: number;
|
|
76
|
+
* };
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* const handler = new EventHandler<any, UserEvent>('UserActivity');
|
|
80
|
+
*
|
|
81
|
+
* // Group events by userId, flush each group after 10 events
|
|
82
|
+
* for await (const groups of GroupEventsByPayload(handler, (event) => {
|
|
83
|
+
* return 'UserActivity' in event ? event.UserActivity.userId : 'unknown';
|
|
84
|
+
* }, 10)) {
|
|
85
|
+
* groups.forEach((events, userId) => {
|
|
86
|
+
* console.log(`User ${userId} has ${events.length} events`);
|
|
87
|
+
* });
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function GroupEventsByPayload<TEvent extends TEventData = TEventData, TKey = string>(handler: EventHandler<any, TEvent>, keyFn: (event: TEvent) => TKey, flushSize: number): AsyncIterableIterator<Map<TKey, TEvent[]>>;
|
|
92
|
+
//# sourceMappingURL=event-operators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-operators.d.ts","sourceRoot":"","sources":["../src/event-operators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EACjE,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAClC,IAAI,EAAE,MAAM,GACV,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAsBjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EACrE,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAClC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GACnC,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,CA+FhE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EAAE,IAAI,GAAG,MAAM,EACzF,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAClC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC9B,SAAS,EAAE,MAAM,GACf,qBAAqB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAmC5C"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collects events into batches of a specified size and yields each batch as an array.
|
|
3
|
+
* The final batch may be smaller if the total number of events is not a multiple of the batch size.
|
|
4
|
+
*
|
|
5
|
+
* @template TEvent - The event type
|
|
6
|
+
* @param handler - EventHandler to collect events from
|
|
7
|
+
* @param size - Size of each batch (must be > 0)
|
|
8
|
+
* @returns AsyncIterableIterator that yields arrays of events
|
|
9
|
+
*
|
|
10
|
+
* @throws {RangeError} When size is <= 0
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const handler = new EventHandler<MessageData, MessageEvent>('Message');
|
|
15
|
+
*
|
|
16
|
+
* // Batch events in groups of 5
|
|
17
|
+
* for await (const batch of ChunkEvents(handler, 5)) {
|
|
18
|
+
* console.log(`Processing batch of ${batch.length} events`);
|
|
19
|
+
* batch.forEach(event => processEvent(event));
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function ChunkEvents(handler, size) {
|
|
24
|
+
if (size <= 0) {
|
|
25
|
+
throw new RangeError('Batch size must be greater than 0');
|
|
26
|
+
}
|
|
27
|
+
return (async function* () {
|
|
28
|
+
const batch = [];
|
|
29
|
+
for await (const event of handler) {
|
|
30
|
+
batch.push(event);
|
|
31
|
+
if (batch.length === size) {
|
|
32
|
+
yield [...batch];
|
|
33
|
+
batch.length = 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Yield any remaining events in the final batch
|
|
37
|
+
if (batch.length > 0) {
|
|
38
|
+
yield batch;
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Partitions an event stream into two separate async iterators: one for matching events and one for non-matching.
|
|
44
|
+
* The predicate function determines which iterator receives each event.
|
|
45
|
+
*
|
|
46
|
+
* @template TEvent - The event type
|
|
47
|
+
* @param handler - EventHandler to partition events from
|
|
48
|
+
* @param predicate - Function that determines if an event matches (true = matching, false = non-matching)
|
|
49
|
+
* @returns Tuple of [matching iterator, non-matching iterator]
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const handler = new EventHandler<UserEvent, UserEvent>('UserCreated');
|
|
54
|
+
*
|
|
55
|
+
* // Split events by admin status
|
|
56
|
+
* const [admins, users] = PartitionEvents(handler, (event) => {
|
|
57
|
+
* return 'UserCreated' in event && event.UserCreated.role === 'admin';
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* // Process matching (admin) events
|
|
61
|
+
* for await (const event of admins) {
|
|
62
|
+
* console.log('Admin created:', event);
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // Process non-matching (regular user) events in parallel
|
|
66
|
+
* for await (const event of users) {
|
|
67
|
+
* console.log('User created:', event);
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function PartitionEvents(handler, predicate) {
|
|
72
|
+
const matchingQueue = [];
|
|
73
|
+
const nonMatchingQueue = [];
|
|
74
|
+
let matchingResolve;
|
|
75
|
+
let nonMatchingResolve;
|
|
76
|
+
let handlerComplete = false;
|
|
77
|
+
// Subscribe to the handler and distribute events to appropriate queues
|
|
78
|
+
const subscriptionId = handler.Subscribe((event) => {
|
|
79
|
+
if (predicate(event)) {
|
|
80
|
+
matchingQueue.push(event);
|
|
81
|
+
if (matchingResolve) {
|
|
82
|
+
matchingResolve();
|
|
83
|
+
matchingResolve = undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
nonMatchingQueue.push(event);
|
|
88
|
+
if (nonMatchingResolve) {
|
|
89
|
+
nonMatchingResolve();
|
|
90
|
+
nonMatchingResolve = undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const createIterator = (queue) => {
|
|
95
|
+
let closed = false;
|
|
96
|
+
return {
|
|
97
|
+
async next() {
|
|
98
|
+
if (closed) {
|
|
99
|
+
return { done: true, value: undefined };
|
|
100
|
+
}
|
|
101
|
+
while (queue.length === 0 && !handlerComplete) {
|
|
102
|
+
await new Promise((resolve) => {
|
|
103
|
+
if (queue === matchingQueue) {
|
|
104
|
+
matchingResolve = resolve;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
nonMatchingResolve = resolve;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (queue.length > 0) {
|
|
112
|
+
const event = queue.shift();
|
|
113
|
+
return { done: false, value: event };
|
|
114
|
+
}
|
|
115
|
+
return { done: true, value: undefined };
|
|
116
|
+
},
|
|
117
|
+
[Symbol.asyncIterator]() {
|
|
118
|
+
return this;
|
|
119
|
+
},
|
|
120
|
+
async return() {
|
|
121
|
+
await Promise.resolve();
|
|
122
|
+
closed = true;
|
|
123
|
+
handler.Unsubscribe(subscriptionId);
|
|
124
|
+
return { done: true, value: undefined };
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
// Create iterators that share the same queues and handler
|
|
129
|
+
const matchingIterator = createIterator(matchingQueue);
|
|
130
|
+
const nonMatchingIterator = createIterator(nonMatchingQueue);
|
|
131
|
+
// Add destroy handlers to both iterators to clean up when iteration is done
|
|
132
|
+
Promise.allSettled([
|
|
133
|
+
(async () => {
|
|
134
|
+
try {
|
|
135
|
+
for await (const _ of matchingIterator) {
|
|
136
|
+
// Consumer will iterate; we just need to wait for completion
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
handlerComplete = true;
|
|
141
|
+
if (nonMatchingResolve)
|
|
142
|
+
nonMatchingResolve();
|
|
143
|
+
}
|
|
144
|
+
})(),
|
|
145
|
+
(async () => {
|
|
146
|
+
try {
|
|
147
|
+
for await (const _ of nonMatchingIterator) {
|
|
148
|
+
// Consumer will iterate; we just need to wait for completion
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
handlerComplete = true;
|
|
153
|
+
if (matchingResolve)
|
|
154
|
+
matchingResolve();
|
|
155
|
+
}
|
|
156
|
+
})(),
|
|
157
|
+
]).catch(() => {
|
|
158
|
+
// Silently handle any errors to avoid unhandled rejection warnings
|
|
159
|
+
});
|
|
160
|
+
return [matchingIterator, nonMatchingIterator];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Groups events by a key function and yields each group as a Map when the group reaches a specified size.
|
|
164
|
+
* Groups are keyed by the result of applying the key function to each event.
|
|
165
|
+
*
|
|
166
|
+
* @template TEvent - The event type
|
|
167
|
+
* @template TKey - The type of the grouping key
|
|
168
|
+
* @param handler - EventHandler to group events from
|
|
169
|
+
* @param keyFn - Function that extracts the grouping key from an event
|
|
170
|
+
* @param flushSize - Number of events needed to trigger a flush of a group
|
|
171
|
+
* @returns AsyncIterableIterator that yields Maps of grouped events
|
|
172
|
+
*
|
|
173
|
+
* @throws {RangeError} When flushSize is <= 0
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* interface UserEvent extends TEventData {
|
|
178
|
+
* UserActivity: {
|
|
179
|
+
* userId: string;
|
|
180
|
+
* action: string;
|
|
181
|
+
* timestamp: number;
|
|
182
|
+
* };
|
|
183
|
+
* }
|
|
184
|
+
*
|
|
185
|
+
* const handler = new EventHandler<any, UserEvent>('UserActivity');
|
|
186
|
+
*
|
|
187
|
+
* // Group events by userId, flush each group after 10 events
|
|
188
|
+
* for await (const groups of GroupEventsByPayload(handler, (event) => {
|
|
189
|
+
* return 'UserActivity' in event ? event.UserActivity.userId : 'unknown';
|
|
190
|
+
* }, 10)) {
|
|
191
|
+
* groups.forEach((events, userId) => {
|
|
192
|
+
* console.log(`User ${userId} has ${events.length} events`);
|
|
193
|
+
* });
|
|
194
|
+
* }
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function GroupEventsByPayload(handler, keyFn, flushSize) {
|
|
198
|
+
if (flushSize <= 0) {
|
|
199
|
+
throw new RangeError('Flush size must be greater than 0');
|
|
200
|
+
}
|
|
201
|
+
return (async function* () {
|
|
202
|
+
const groups = new Map();
|
|
203
|
+
let totalCount = 0;
|
|
204
|
+
for await (const event of handler) {
|
|
205
|
+
const key = keyFn(event);
|
|
206
|
+
if (!groups.has(key)) {
|
|
207
|
+
groups.set(key, []);
|
|
208
|
+
}
|
|
209
|
+
const group = groups.get(key);
|
|
210
|
+
if (group) {
|
|
211
|
+
group.push(event);
|
|
212
|
+
totalCount++;
|
|
213
|
+
// Flush all groups when any reaches the flush size
|
|
214
|
+
if (group.length >= flushSize) {
|
|
215
|
+
yield new Map(groups);
|
|
216
|
+
groups.clear();
|
|
217
|
+
totalCount = 0;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Yield any remaining groups
|
|
222
|
+
if (totalCount > 0) {
|
|
223
|
+
yield groups;
|
|
224
|
+
}
|
|
225
|
+
})();
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=event-operators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-operators.js","sourceRoot":"","sources":["../src/event-operators.ts"],"names":[],"mappings":"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"}
|