Open History to see the last commit
1import type { TurnItemId } from "@t3tools/contracts";
2import {
3 appendTerminalOutput,
4 EMPTY_TERMINAL_OUTPUT,
5 type TerminalOutputState,
6} from "@t3tools/shared/terminalOutput";
7import * as Context from "effect/Context";
8import * as Effect from "effect/Effect";
9import * as Layer from "effect/Layer";
10
11import * as CommandOutputHub from "../CommandOutputHub.ts";
12import type * as EventSink from "../EventSink.ts";
13import type * as ProjectionStore from "../ProjectionStore.ts";
14
15export interface RecordedCommandOutput {
16 readonly chunks: number;
17 readonly output: TerminalOutputState;
18}
19
20export class CommandOutputRecorder extends Context.Service<
21 CommandOutputRecorder,
22 { readonly snapshot: Effect.Effect<ReadonlyMap<TurnItemId, RecordedCommandOutput>> }
23>()("t3/orchestration-v2/testkit/CommandOutputRecorder") {}
24
25export const layer: Layer.Layer<
26 CommandOutputHub.CommandOutputHub | CommandOutputRecorder,
27 never,
28 EventSink.EventSinkV2 | ProjectionStore.ProjectionStoreV2
29> = Layer.effectContext(
30 Effect.gen(function* () {
31 const hub = yield* CommandOutputHub.make;
32 const recorded = new Map<TurnItemId, RecordedCommandOutput>();
33 return Context.make(
34 CommandOutputHub.CommandOutputHub,
35 CommandOutputHub.CommandOutputHub.of({
36 ...hub,
37 append: Effect.fn("CommandOutputHub.append")(function (input) {
38 return Effect.sync(() => {
39 const previous = recorded.get(input.itemId);
40 recorded.set(input.itemId, {
41 chunks: (previous?.chunks ?? 0) + 1,
42 output: appendTerminalOutput(previous?.output ?? EMPTY_TERMINAL_OUTPUT, input.chunk),
43 });
44 }).pipe(Effect.andThen(hub.append(input)));
45 }),
46 }),
47 ).pipe(
48 Context.add(CommandOutputRecorder, {
49 snapshot: Effect.sync(() => new Map(recorded)),
50 }),
51 );
52 }),
53);