Skip to content

Commit 0162552

Browse files
authored
Merge pull request #586 from underctrl-io/copilot/add-instant-parallel-event-handlers
feat: add support for instant and parallel event function handlers
2 parents fab88cb + 9d177f4 commit 0162552

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

packages/commandkit/src/app/handlers/AppEventsHandler.ts

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { CommandKitErrorCodes, isErrorType } from '../../utils/error-codes';
1414
export type EventListener = {
1515
handler: ListenerFunction;
1616
once: boolean;
17+
parallel: boolean;
1718
};
1819

1920
/**
@@ -111,6 +112,7 @@ export class AppEventsHandler {
111112
listeners.push({
112113
handler: handler.default,
113114
once: !!handler.once,
115+
parallel: !!handler.parallel,
114116
});
115117
}
116118

@@ -164,6 +166,20 @@ export class AppEventsHandler {
164166
const onceListeners = listeners.filter((listener) => listener.once);
165167
const onListeners = listeners.filter((listener) => !listener.once);
166168

169+
// Further separate into parallel and sequential groups
170+
const onParallelListeners = onListeners.filter(
171+
(listener) => listener.parallel,
172+
);
173+
const onSequentialListeners = onListeners.filter(
174+
(listener) => !listener.parallel,
175+
);
176+
const onceParallelListeners = onceListeners.filter(
177+
(listener) => listener.parallel,
178+
);
179+
const onceSequentialListeners = onceListeners.filter(
180+
(listener) => !listener.parallel,
181+
);
182+
167183
// Initialize set to track executed once listeners
168184
const executedOnceListeners = new Set<ListenerFunction>();
169185

@@ -200,7 +216,24 @@ export class AppEventsHandler {
200216
variables: new Map(),
201217
},
202218
async () => {
203-
for (const listener of onListeners) {
219+
// Execute parallel listeners first using Promise.all
220+
if (onParallelListeners.length > 0) {
221+
await Promise.all(
222+
onParallelListeners.map(async (listener) => {
223+
try {
224+
await listener.handler(...args, client, this.commandkit);
225+
} catch (e) {
226+
// Log errors but don't stop other parallel listeners
227+
Logger.error`Error handling event ${name}${
228+
namespace ? ` of namespace ${namespace}` : ''
229+
}: ${e}`;
230+
}
231+
}),
232+
);
233+
}
234+
235+
// Execute sequential listeners in order
236+
for (const listener of onSequentialListeners) {
204237
try {
205238
await listener.handler(...args, client, this.commandkit);
206239
} catch (e) {
@@ -248,7 +281,40 @@ export class AppEventsHandler {
248281
})
249282
.catch(Object);
250283

251-
for (const listener of onceListeners) {
284+
// Execute parallel once listeners first using Promise.all
285+
if (onceParallelListeners.length > 0) {
286+
await Promise.all(
287+
onceParallelListeners.map(async (listener) => {
288+
return runInEventWorkerContext(
289+
{
290+
event: name,
291+
namespace: namespace ?? null,
292+
data: data.event,
293+
commandkit: this.commandkit,
294+
arguments: args,
295+
variables: new Map(),
296+
},
297+
async () => {
298+
try {
299+
// Skip if already executed
300+
if (executedOnceListeners.has(listener.handler)) return;
301+
302+
await listener.handler(...args, client, this.commandkit);
303+
executedOnceListeners.add(listener.handler);
304+
} catch (e) {
305+
// Log errors but don't stop other parallel listeners
306+
Logger.error`Error handling event ${name}${
307+
namespace ? ` of namespace ${namespace}` : ''
308+
}: ${e}`;
309+
}
310+
},
311+
);
312+
}),
313+
);
314+
}
315+
316+
// Execute sequential once listeners in order
317+
for (const listener of onceSequentialListeners) {
252318
if (broken) break; // Stop executing remaining listeners if propagation was stopped
253319

254320
await runInEventWorkerContext(
@@ -307,7 +373,7 @@ export class AppEventsHandler {
307373
...data,
308374
mainListener:
309375
onListeners.length > 0
310-
? { handler: mainHandler, once: false }
376+
? { handler: mainHandler, once: false, parallel: false }
311377
: undefined,
312378
executedOnceListeners,
313379
});
@@ -332,7 +398,7 @@ export class AppEventsHandler {
332398
Logger.info(
333399
`🔌 Registered event ${name}${
334400
namespace ? ` of namespace ${namespace}` : ''
335-
} (${onListeners.length} regular, ${onceListeners.length} once-only)`,
401+
} (${onSequentialListeners.length} sequential, ${onParallelListeners.length} parallel, ${onceSequentialListeners.length} once-sequential, ${onceParallelListeners.length} once-parallel)`,
336402
);
337403
}
338404
}

0 commit comments

Comments
 (0)