repos / starfx

a micro-mvc framework for react apps
git clone https://github.com/neurosnap/starfx.git

starfx / src / fx
Eric Bower  ·  2025-06-06

race.ts

 1import type { Callable, Operation, Task } from "effection";
 2import { action, call, resource, spawn } from "effection";
 3
 4interface OpMap<T = unknown> {
 5  [key: string]: Callable<T>;
 6}
 7
 8export function raceMap<T>(opMap: OpMap): Operation<{
 9  [K in keyof OpMap<T>]: OpMap[K] extends (...args: any[]) => any
10    ? ReturnType<OpMap[K]>
11    : OpMap[K];
12}> {
13  return resource(function* Race(provide) {
14    const keys = Object.keys(opMap);
15    const taskMap: { [key: string]: Task<unknown> } = {};
16    const resultMap: { [key: keyof OpMap]: OpMap[keyof OpMap] } = {};
17
18    const winner = yield* action<Task<unknown>>(function* (resolve) {
19      for (let i = 0; i < keys.length; i += 1) {
20        const key = keys[i];
21        yield* spawn(function* () {
22          const task = yield* spawn(function* () {
23            yield* call(opMap[key] as any);
24          });
25          taskMap[key] = task;
26          (resultMap as any)[key] = yield* task;
27          resolve(task);
28        });
29      }
30    });
31
32    for (let i = 0; i < keys.length; i += 1) {
33      const key = keys[i];
34      const task = taskMap[key];
35      if (task === winner) {
36        continue;
37      }
38
39      yield* spawn(() => task.halt());
40    }
41
42    yield* provide(resultMap);
43  });
44}