@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.
@@ -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: null });
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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"}
@@ -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: { userId: '123', username: 'john', role: 'admin' }
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 multiple properties
35
- * EventFilter(event, { username: 'john', role: 'admin' }); // true
36
- * EventFilter(event, { username: 'john', role: 'user' }); // false
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,EACjE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACtC,OAAO,CA0BT"}
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"}
@@ -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: { userId: '123', username: 'john', role: 'admin' }
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 multiple properties
33
- * EventFilter(event, { username: 'john', role: 'admin' }); // true
34
- * EventFilter(event, { username: 'john', role: 'user' }); // false
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('No payload structure.');
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
- // Type-safe property access with proper unknown handling
60
- const payloadValue = payload[key];
61
- if (payloadValue !== filterValue)
62
- return false;
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":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;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,uBAAuB,CAAC,CAAC;IACrE,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,yDAAyD;QACzD,MAAM,YAAY,GAAI,OAAmC,CAAC,GAAG,CAAC,CAAC;QAE/D,IAAI,YAAY,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}
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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"}