MCPcopy Create free account
hub / github.com/anomalyco/opencode / make

Function make

packages/opencode/src/effect/runner.ts:39–215  ·  view source on GitHub ↗
(
  scope: Scope.Scope,
  opts?: {
    onIdle?: Effect.Effect<void>
    onBusy?: Effect.Effect<void>
    onInterrupt?: Effect.Effect<A, E>
  },
)

Source from the content-addressed store, hash-verified

37 | { readonly _tag: "ShellThenRun"; readonly shell: ShellHandle<A, E>; readonly run: PendingHandle<A, E> }
38
39export const make = <A, E = never>(
40 scope: Scope.Scope,
41 opts?: {
42 onIdle?: Effect.Effect<void>
43 onBusy?: Effect.Effect<void>
44 onInterrupt?: Effect.Effect<A, E>
45 },
46): Runner<A, E> => {
47 const ref = SynchronizedRef.makeUnsafe<State<A, E>>({ _tag: "Idle" })
48 const idle = opts?.onIdle ?? Effect.void
49 const onBusy = opts?.onBusy ?? Effect.void
50 const onInterrupt = opts?.onInterrupt
51 let ids = 0
52
53 const state = () => SynchronizedRef.getUnsafe(ref)
54 const next = () => {
55 ids += 1
56 return ids
57 }
58
59 const complete = (done: Deferred.Deferred<A, E | Cancelled>, exit: Exit.Exit<A, E>) =>
60 Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)
61 ? Deferred.fail(done, new Cancelled()).pipe(Effect.asVoid)
62 : Deferred.done(done, exit).pipe(Effect.asVoid)
63
64 const awaitDone = (done: Deferred.Deferred<A, E | Cancelled>) =>
65 Deferred.await(done).pipe(Effect.catchTag("RunnerCancelled", (e) => onInterrupt ?? Effect.die(e)))
66
67 const idleIfCurrent = () =>
68 SynchronizedRef.modify(ref, (st) => [st._tag === "Idle" ? idle : Effect.void, st] as const).pipe(Effect.flatten)
69
70 const finishRun = (id: number, done: Deferred.Deferred<A, E | Cancelled>, exit: Exit.Exit<A, E>) =>
71 SynchronizedRef.modify(
72 ref,
73 (st) =>
74 [
75 Effect.gen(function* () {
76 if (st._tag === "Running" && st.run.id === id) yield* idle
77 yield* complete(done, exit)
78 }),
79 st._tag === "Running" && st.run.id === id ? ({ _tag: "Idle" } as const) : st,
80 ] as const,
81 ).pipe(Effect.flatten)
82
83 const startRun = (work: Effect.Effect<A, E>, done: Deferred.Deferred<A, E | Cancelled>) =>
84 Effect.gen(function* () {
85 const id = next()
86 const fiber = yield* work.pipe(
87 Effect.onExit((exit) => finishRun(id, done, exit)),
88 Effect.forkIn(scope),
89 )
90 return { id, done, fiber } satisfies RunHandle<A, E>
91 })
92
93 const finishShell = (id: number) =>
94 SynchronizedRef.modifyEffect(
95 ref,
96 Effect.fnUntraced(function* (st) {

Callers

nothing calls this directly

Calls 3

idleIfCurrentFunction · 0.85
stopShellFunction · 0.85
interruptMethod · 0.80

Tested by

no test coverage detected