import * as Refreshable from "effect-fc-next/Refreshable" import { describe, expect, it, vi } from "vitest" import { accept, register } from "../src/runtime.js" describe("refresh runtime", () => { it("retains a cell and notifies subscribers for compatible updates", async () => { const hot = { data: {}, accept: vi.fn(), invalidate: vi.fn(), } const first = register({ body: "first" }, hot, "module:View", "hooks") const cell = (first as Record)[Refreshable.RefreshableTypeId] as Refreshable.Cell const listener = vi.fn() cell.subscribe(listener) const second = register({ body: "second" }, hot, "module:View", "hooks") const secondCell = (second as Record)[Refreshable.RefreshableTypeId] expect(secondCell).toBe(cell) expect(cell.current).toBe(second) expect(cell.snapshot).toEqual({ revision: 1, resetRevision: 0, }) await Promise.resolve() expect(listener).toHaveBeenCalledTimes(1) }) it("increments resetRevision for incompatible and forced updates", () => { const hot = { data: {}, accept: vi.fn(), invalidate: vi.fn(), } const first = register({}, hot, "module:View", "one") const cell = (first as Record)[Refreshable.RefreshableTypeId] as Refreshable.Cell register({}, hot, "module:View", "two") expect(cell.snapshot.resetRevision).toBe(1) register({}, hot, "module:View", "two", true) expect(cell.snapshot.resetRevision).toBe(2) }) it("is inert outside a Vite hot context", () => { const component = {} expect(register(component, undefined, "module:View", "hooks")).toBe(component) expect((component as Record)[Refreshable.RefreshableTypeId]).toBeUndefined() }) it("invalidates when the module's View IDs change", () => { const hot = { data: {}, accept: vi.fn(), invalidate: vi.fn(), } accept(hot, ["module:First"]) expect(hot.accept).toHaveBeenCalledTimes(1) expect(hot.invalidate).not.toHaveBeenCalled() accept(hot, ["module:Second"]) expect(hot.invalidate).toHaveBeenCalledWith("[effect-view] Effect View exports changed") }) })