76 lines
2.8 KiB
JavaScript
76 lines
2.8 KiB
JavaScript
|
|
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"]);
|
||
|
|
});
|