import { describe, expect, it, vi } from "vitest"; import { createOptionalRuntimeHost } from "../../src/bootstrap/optional-runtime-host.ts"; import type { ResolvedRuntimeCapabilities } from "../../src/contracts/runtime-capabilities.ts"; import type { ServiceWorkerRuntimeHost, ServiceWorkerStartOutcome, } from "../../src/contracts/service-worker.ts"; const capabilities: ResolvedRuntimeCapabilities = Object.freeze({ realtime: Object.freeze([]), webWorkers: Object.freeze([]), serviceWorker: null, serviceWorkerDisabledCleanup: false, offlineCommands: null, }); function deferred() { let resolve!: (value: Value) => void; const promise = new Promise((settle) => { resolve = settle; }); return { promise, resolve } as const; } describe("optional runtime host", () => { it("keeps stop-before-start terminal without acquiring browser resources", async () => { const serviceWorker: ServiceWorkerRuntimeHost = { start: vi.fn( async (): Promise => ({ kind: "ACTIVE", buildId: "build-1", }), ), requestActivation: vi.fn(), resetOwnedCaches: vi.fn(), stop: vi.fn(async () => {}), }; const addEventListener = vi.fn(); const runtime = createOptionalRuntimeHost({ capabilities, routerBasePath: "/", buildId: "build-1", serviceWorkerHost: serviceWorker, browserLifecycleHost: { addEventListener, removeEventListener: vi.fn(), }, }); await runtime.stop(); await runtime.startAfterMount(); expect(runtime.browserLifecycle()).toBeNull(); expect(runtime.health().serviceWorker).toBe("DISABLED"); expect(addEventListener).not.toHaveBeenCalled(); expect(serviceWorker.start).not.toHaveBeenCalled(); expect(serviceWorker.stop).not.toHaveBeenCalled(); }); it("serializes stop behind an in-flight start and suppresses late health", async () => { const start = deferred(); const serviceWorker: ServiceWorkerRuntimeHost = { start: vi.fn(() => start.promise), requestActivation: vi.fn(), resetOwnedCaches: vi.fn(), stop: vi.fn(async () => {}), }; const runtime = createOptionalRuntimeHost({ capabilities, routerBasePath: "/", buildId: "build-1", serviceWorkerHost: serviceWorker, browserLifecycleHost: { addEventListener: vi.fn(), removeEventListener: vi.fn(), }, }); const starting = runtime.startAfterMount(); const stopping = runtime.stop(); start.resolve({ kind: "ACTIVE", buildId: "build-1" }); await Promise.all([starting, stopping]); expect(serviceWorker.stop).toHaveBeenCalledTimes(1); expect(runtime.health().serviceWorker).toBe("DISABLED"); expect(runtime.browserLifecycle()).toBeNull(); }); });