diff --git a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md index 979af51f..1b6c63e5 100644 --- a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md +++ b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md @@ -12,8 +12,8 @@ Verified source roots: - Effect v4 subtree: `/home/elpresidank/YeeBois/projects/beep-effect2/.repos/effect-v4` - Installed Effect beta used by this workspace: `ts/node_modules/effect` -Current signal counts from `ts/packages` after the 2026-06-02 request-response -queue stream slice: +Current signal counts from `ts/packages` after the 2026-06-02 client RPC +acquisition cause tap slice: | Signal | Count | | --- | ---: | @@ -138,6 +138,10 @@ Notes: around the socket program by sandboxing the Effect and handling the resulting `Cause` in the Effect pipeline before the Fastify fire-and-forget `runPromise` boundary. +- The client RPC acquisition cause tap slice removed the Promise `.catch` used + only to update connection state on runtime/client acquisition failure. + `effect-rpc-client.ts` now uses `Effect.tapCause` and `Cause.pretty` before + the public Promise boundary. - `Record` and `throwLibrarianServiceError` are now clean in `ts/packages`. @@ -985,6 +989,27 @@ Notes: - `cd ts && bun run test` - `git diff --check` +### 2026-06-02: Client RPC Acquisition Cause Tap Slice + +- Status: migrated and root-verified. +- Completed: + - `ts/packages/client/src/socket/effect-rpc-client.ts` now observes + runtime/client acquisition failures with `Effect.tapCause` and + `Cause.pretty`. + - Removed the Promise `.catch(...)` that only updated local connection state + after `runtime.runPromise(TrustGraphRpcClientService)`. + - Removed the local `errorMessage` helper and its message-field assertion. + - Public `dispatch`, `dispatchStream`, and `close` Promise facades remain + compatibility boundaries. +- Verification: + - `cd ts && bun run check:tsgo` + - `bun run --cwd ts/packages/client build` + - `bun run --cwd ts/packages/client test` + - `cd ts && bun run check` + - `cd ts && bun run build` + - `cd ts && bun run test` + - `git diff --check` + ## Subagent Findings To Preserve - MCP/workbench: diff --git a/ts/packages/client/src/socket/effect-rpc-client.ts b/ts/packages/client/src/socket/effect-rpc-client.ts index 66b3ab38..b7ec7bd9 100644 --- a/ts/packages/client/src/socket/effect-rpc-client.ts +++ b/ts/packages/client/src/socket/effect-rpc-client.ts @@ -1,4 +1,4 @@ -import { Context, Effect, Layer, ManagedRuntime, Stream } from "effect"; +import { Cause, Context, Effect, Layer, ManagedRuntime, Stream } from "effect"; import type * as RpcGroup from "effect/unstable/rpc/RpcGroup"; import * as RpcClient from "effect/unstable/rpc/RpcClient"; import type { RpcClientError } from "effect/unstable/rpc/RpcClientError"; @@ -128,13 +128,18 @@ export function makeEffectRpcClient( }; const runtime = ManagedRuntime.make(makeClientLayer()); - const clientPromise = runtime.runPromise(TrustGraphRpcClientService); - clientPromise.catch((cause) => { - setState({ - status: "failed", - lastError: errorMessage(cause), - }); - }); + const clientPromise = runtime.runPromise( + TrustGraphRpcClientService.pipe( + Effect.tapCause((cause) => + Effect.sync(() => { + setState({ + status: "failed", + lastError: Cause.pretty(cause), + }); + }) + ), + ), + ); return { subscribe: (listener) => { @@ -200,16 +205,6 @@ export function withDispatchRequestPolicy( return retryTimes > 0 ? timed.pipe(Effect.retry({ times: retryTimes })) : timed; } -function errorMessage(cause: unknown): string { - if (cause instanceof Error) return cause.message; - if (typeof cause === "string") return cause; - if (cause !== null && typeof cause === "object" && "message" in cause) { - const message = (cause as { message?: unknown }).message; - if (typeof message === "string") return message; - } - return String(cause); -} - function normalizeTimeoutMs(timeoutMs: number | undefined): number { if (timeoutMs === undefined || !Number.isFinite(timeoutMs) || timeoutMs <= 0) { return DEFAULT_REQUEST_TIMEOUT_MS;