import assert from "node:assert/strict"; import test from "node:test"; import { createPageLifecycleDispatcher } from "../src/sdk/lifecycle.ts"; test("maps page visibility transitions to show, hide and unload events", () => { const dispatcher = createPageLifecycleDispatcher(); const events = []; dispatcher.lifecycle.onShow((event) => events.push(event)); dispatcher.lifecycle.onHide((event) => events.push(event)); dispatcher.lifecycle.onUnload((event) => events.push(event)); assert.equal(dispatcher.lifecycle.state(), "initializing"); dispatcher.dispatch("show", "host"); dispatcher.dispatch("hide", "host"); dispatcher.dispatch("show", "host"); dispatcher.dispatch("unload", "host"); assert.equal(dispatcher.lifecycle.state(), "unloaded"); assert.deepEqual( events.map(({ type, previous, current, source }) => ({ type, previous, current, source, })), [ { type: "show", previous: "initializing", current: "visible", source: "host" }, { type: "hide", previous: "visible", current: "hidden", source: "host" }, { type: "show", previous: "hidden", current: "visible", source: "host" }, { type: "unload", previous: "visible", current: "unloaded", source: "host" }, ], ); }); test("deduplicates lifecycle events and ignores transitions after unload", () => { const dispatcher = createPageLifecycleDispatcher(); const events = []; dispatcher.lifecycle.on("show", (event) => events.push(event.type)); dispatcher.lifecycle.on("unload", (event) => events.push(event.type)); assert.equal(dispatcher.dispatch("show", "host")?.type, "show"); assert.equal(dispatcher.dispatch("show", "host"), null); assert.equal(dispatcher.dispatch("unload", "host")?.type, "unload"); assert.equal(dispatcher.dispatch("unload", "document"), null); assert.equal(dispatcher.dispatch("show", "host"), null); assert.deepEqual(events, ["show", "unload"]); }); test("unsubscribe removes a page lifecycle listener", () => { const dispatcher = createPageLifecycleDispatcher(); let calls = 0; const unsubscribe = dispatcher.lifecycle.onHide(() => { calls += 1; }); unsubscribe(); unsubscribe(); dispatcher.dispatch("hide", "host"); assert.equal(calls, 0); }); test("show and hide helpers replay current state for lazy pages", () => { const dispatcher = createPageLifecycleDispatcher(); dispatcher.dispatch("show", "host"); const replayed = []; dispatcher.lifecycle.onShow((event) => replayed.push(event.type)); dispatcher.lifecycle.onHide((event) => replayed.push(event.type)); dispatcher.lifecycle.on("show", (event) => replayed.push(`future:${event.type}`)); assert.deepEqual(replayed, ["show"]); dispatcher.dispatch("hide", "host"); dispatcher.lifecycle.onHide((event) => replayed.push(`late:${event.type}`)); assert.deepEqual(replayed, ["show", "hide", "late:hide"]); });