97 lines · 2.7 KB · TypeScript
RawDownload
import { it } from "@effect/vitest";import { describe, expect } from "vitest";import { Effect, Ref } from "effect";import { WS_CHANNELS } from "@t3tools/contracts"; import { makeServerPushBus, type ServerPushClient } from "./pushBus"; class MockPushClient implements ServerPushClient {  readonly sent: string[] = [];  private readonly waiters = new Set<() => void>();   readonly send: ServerPushClient["send"] = (message: string) =>    Effect.sync(() => {      this.sent.push(message);      for (const waiter of this.waiters) {        waiter();      }      return true;    });   waitForSentCount(count: number): Promise<void> {    if (this.sent.length >= count) {      return Promise.resolve();    }     return new Promise((resolve) => {      const check = () => {        if (this.sent.length < count) {          return;        }        this.waiters.delete(check);        resolve();      };       this.waiters.add(check);    });  }} describe("makeServerPushBus", () => {  it.live("waits for the welcome push before a new client joins broadcast delivery", () =>    Effect.scoped(      Effect.gen(function* () {        const client = new MockPushClient();        const clients = yield* Ref.make(new Set<ServerPushClient>());        const pushBus = yield* makeServerPushBus({          clients,          logOutgoingPush: () => {},        });         yield* pushBus.publishAll(WS_CHANNELS.serverConfigUpdated, {          issues: [{ kind: "keybindings.malformed-config", message: "queued-before-connect" }],          providers: [],        });         const delivered = yield* pushBus.publishClient(client, WS_CHANNELS.serverWelcome, {          cwd: "/tmp/project",          projectName: "project",        });        expect(delivered).toBe(true);         yield* Ref.update(clients, (current) => current.add(client));         yield* pushBus.publishAll(WS_CHANNELS.serverConfigUpdated, {          issues: [],          providers: [],        });         yield* Effect.promise(() => client.waitForSentCount(2));         const messages = client.sent.map(          (message) => JSON.parse(message) as { channel: string; data: unknown },        );         expect(messages).toHaveLength(2);        expect(messages[0]).toEqual({          type: "push",          sequence: 2,          channel: WS_CHANNELS.serverWelcome,          data: {            cwd: "/tmp/project",            projectName: "project",          },        });        expect(messages[1]).toEqual({          type: "push",          sequence: 3,          channel: WS_CHANNELS.serverConfigUpdated,          data: {            issues: [],            providers: [],          },        });      }),    ),  );});