import { EnvironmentId, ProjectId, WS_METHODS } from "@t3tools/contracts";import { expect, it } from "@effect/vitest";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Stream from "effect/Stream";import * as SubscriptionRef from "effect/SubscriptionRef";import { AsyncResult, Atom, AtomRegistry } from "effect/unstable/reactivity"; import { AVAILABLE_CONNECTION_STATE, PrimaryConnectionTarget, type PreparedConnection, type SupervisorConnectionState,} from "../connection/model.ts";import * as EnvironmentRegistry from "../connection/registry.ts";import * as EnvironmentSupervisor from "../connection/supervisor.ts";import type { WsRpcProtocolClient } from "../rpc/protocol.ts";import type { RpcSession } from "../rpc/session.ts";import { createPullRequestEnvironmentAtoms } from "./pullRequests.ts";import { PullRequestDiffLoader } from "./pullRequestDiffHttp.ts";import { executeAtomQuery } from "./runtime.ts"; const TARGET = new PrimaryConnectionTarget({ environmentId: EnvironmentId.make("environment-1"), label: "Test environment", httpBaseUrl: "https://environment.example.test", wsBaseUrl: "wss://environment.example.test",}); function session(client: WsRpcProtocolClient): RpcSession { return { client, initialConfig: Effect.never, ready: Effect.void, probe: Effect.void, closed: Effect.never, };} it.effect("refreshes pull request activity after a comment is updated", () => Effect.scoped( Effect.gen(function* () { let commentBody = "old comment"; const client = { [WS_METHODS.pullRequestsActivity]: () => Effect.succeed({ author: null, reviewers: [], comments: [ { id: "comment-1", kind: "issue-comment", author: null, body: commentBody, createdAt: "2026-08-24T00:00:00Z", url: null, path: null, reviewState: null, reactions: [], }, ], commentCount: 1, commentsTruncated: false, reviewThreads: [], commits: [], reactions: [], }), [WS_METHODS.pullRequestsUpdateComment]: (input: { readonly body: string }) => Effect.sync(() => { commentBody = input.body; }), } as unknown as WsRpcProtocolClient; const connectionState: SupervisorConnectionState = { ...AVAILABLE_CONNECTION_STATE, desired: true, network: "online", phase: "connected", attempt: 1, generation: 1, }; const supervisor = EnvironmentSupervisor.EnvironmentSupervisor.of({ target: TARGET, state: yield* SubscriptionRef.make(connectionState), session: yield* SubscriptionRef.make(Option.some(session(client))), prepared: yield* SubscriptionRef.make(Option.none<PreparedConnection>()), connect: Effect.void, disconnect: Effect.void, retryNow: Effect.void, } satisfies EnvironmentSupervisor.EnvironmentSupervisor["Service"]); const environmentRegistry = EnvironmentRegistry.EnvironmentRegistry.of({ run: (_environmentId, effect) => Effect.provideService(effect, EnvironmentSupervisor.EnvironmentSupervisor, supervisor), runStream: (_environmentId, stream) => Stream.provideService(stream, EnvironmentSupervisor.EnvironmentSupervisor, supervisor), followStream: (_environmentId, stream) => Stream.provideService(stream, EnvironmentSupervisor.EnvironmentSupervisor, supervisor), } as EnvironmentRegistry.EnvironmentRegistry["Service"]); const runtime = Atom.runtime( Layer.merge( Layer.succeed(EnvironmentRegistry.EnvironmentRegistry, environmentRegistry), Layer.succeed( PullRequestDiffLoader, PullRequestDiffLoader.of({ load: () => Effect.die("unused") }), ), ), ); const atoms = createPullRequestEnvironmentAtoms(runtime); const registry = yield* Effect.acquireRelease(Effect.sync(AtomRegistry.make), (registry) => Effect.sync(() => registry.dispose()), ); const reference = { projectId: ProjectId.make("project-1"), repository: "acme/web", number: 1, } as const; const activity = atoms.activity({ environmentId: TARGET.environmentId, input: reference }); const unmount = registry.mount(activity); yield* Effect.addFinalizer(() => Effect.sync(unmount)); const initial = yield* Effect.promise(() => executeAtomQuery(registry, activity)); expect(AsyncResult.isSuccess(initial)).toBe(true); if (!AsyncResult.isSuccess(initial)) { return yield* Effect.die("activity did not load"); } expect(initial.value.comments[0]?.body).toBe("old comment"); const update = yield* Effect.promise(() => atoms.updateComment.run(registry, { environmentId: TARGET.environmentId, input: { ...reference, commentId: "comment-1", kind: "issue-comment", body: "updated" }, }), ); expect(AsyncResult.isSuccess(update)).toBe(true); expect( (yield* AtomRegistry.getResult(registry, activity, { suspendOnWaiting: true })).comments[0] ?.body, ).toBe("updated"); }), ),);
import { EnvironmentId, ProjectId, WS_METHODS } from "@t3tools/contracts";
import { expect, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Stream from "effect/Stream";
import * as SubscriptionRef from "effect/SubscriptionRef";
import { AsyncResult, Atom, AtomRegistry } from "effect/unstable/reactivity";
import {
AVAILABLE_CONNECTION_STATE,
PrimaryConnectionTarget,
type PreparedConnection,
type SupervisorConnectionState,
} from "../connection/model.ts";
import * as EnvironmentRegistry from "../connection/registry.ts";
import * as EnvironmentSupervisor from "../connection/supervisor.ts";
import type { WsRpcProtocolClient } from "../rpc/protocol.ts";
import type { RpcSession } from "../rpc/session.ts";
import { createPullRequestEnvironmentAtoms } from "./pullRequests.ts";
import { PullRequestDiffLoader } from "./pullRequestDiffHttp.ts";
import { executeAtomQuery } from "./runtime.ts";
const TARGET = new PrimaryConnectionTarget({
environmentId: EnvironmentId.make("environment-1"),
label: "Test environment",
httpBaseUrl: "https://environment.example.test",
wsBaseUrl: "wss://environment.example.test",
});
function session(client: WsRpcProtocolClient): RpcSession {
return {
client,
initialConfig: Effect.never,
ready: Effect.void,
probe: Effect.void,
closed: Effect.never,
};
}
it.effect("refreshes pull request activity after a comment is updated", () =>
Effect.scoped(
Effect.gen(function* () {
let commentBody = "old comment";
const client = {
[WS_METHODS.pullRequestsActivity]: () =>
Effect.succeed({
author: null,
reviewers: [],
comments: [
{
id: "comment-1",
kind: "issue-comment",
author: null,
body: commentBody,
createdAt: "2026-08-24T00:00:00Z",
url: null,
path: null,
reviewState: null,
reactions: [],
},
],
commentCount: 1,
commentsTruncated: false,
reviewThreads: [],
commits: [],
reactions: [],
}),
[WS_METHODS.pullRequestsUpdateComment]: (input: { readonly body: string }) =>
Effect.sync(() => {
commentBody = input.body;
}),
} as unknown as WsRpcProtocolClient;
const connectionState: SupervisorConnectionState = {
...AVAILABLE_CONNECTION_STATE,
desired: true,
network: "online",
phase: "connected",
attempt: 1,
generation: 1,
};
const supervisor = EnvironmentSupervisor.EnvironmentSupervisor.of({
target: TARGET,
state: yield* SubscriptionRef.make(connectionState),
session: yield* SubscriptionRef.make(Option.some(session(client))),
prepared: yield* SubscriptionRef.make(Option.none<PreparedConnection>()),
connect: Effect.void,
disconnect: Effect.void,
retryNow: Effect.void,
} satisfies EnvironmentSupervisor.EnvironmentSupervisor["Service"]);
const environmentRegistry = EnvironmentRegistry.EnvironmentRegistry.of({
run: (_environmentId, effect) =>
Effect.provideService(effect, EnvironmentSupervisor.EnvironmentSupervisor, supervisor),
runStream: (_environmentId, stream) =>
Stream.provideService(stream, EnvironmentSupervisor.EnvironmentSupervisor, supervisor),
followStream: (_environmentId, stream) =>
Stream.provideService(stream, EnvironmentSupervisor.EnvironmentSupervisor, supervisor),
} as EnvironmentRegistry.EnvironmentRegistry["Service"]);
const runtime = Atom.runtime(
Layer.merge(
Layer.succeed(EnvironmentRegistry.EnvironmentRegistry, environmentRegistry),
Layer.succeed(
PullRequestDiffLoader,
PullRequestDiffLoader.of({ load: () => Effect.die("unused") }),
),
),
);
const atoms = createPullRequestEnvironmentAtoms(runtime);
const registry = yield* Effect.acquireRelease(Effect.sync(AtomRegistry.make), (registry) =>
Effect.sync(() => registry.dispose()),
);
const reference = {
projectId: ProjectId.make("project-1"),
repository: "acme/web",
number: 1,
} as const;
const activity = atoms.activity({ environmentId: TARGET.environmentId, input: reference });
const unmount = registry.mount(activity);
yield* Effect.addFinalizer(() => Effect.sync(unmount));
const initial = yield* Effect.promise(() => executeAtomQuery(registry, activity));
expect(AsyncResult.isSuccess(initial)).toBe(true);
if (!AsyncResult.isSuccess(initial)) {
return yield* Effect.die("activity did not load");
}
expect(initial.value.comments[0]?.body).toBe("old comment");
const update = yield* Effect.promise(() =>
atoms.updateComment.run(registry, {
environmentId: TARGET.environmentId,
input: { ...reference, commentId: "comment-1", kind: "issue-comment", body: "updated" },
}),
);
expect(AsyncResult.isSuccess(update)).toBe(true);
expect(
(yield* AtomRegistry.getResult(registry, activity, { suspendOnWaiting: true })).comments[0]
?.body,
).toBe("updated");
}),
),
);