feat: expose stable journey intent signals
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
canonicalSectionIdFromHash,
|
||||
createNavigationController,
|
||||
validateSectionAnchor,
|
||||
type NavigationState,
|
||||
type NavigationRuntime,
|
||||
} from "@/journey/navigation-controller";
|
||||
import type { SectionId } from "@/content/types";
|
||||
@@ -205,6 +206,7 @@ describe("navigation epochs and effects", () => {
|
||||
expect(controller.state()).toEqual({
|
||||
epoch: 2,
|
||||
source: "passive-scroll",
|
||||
phase: "idle",
|
||||
destinationId: null,
|
||||
signDestinationId: null,
|
||||
});
|
||||
@@ -221,6 +223,30 @@ describe("navigation epochs and effects", () => {
|
||||
expect(harness.focused).toEqual(["experience"]);
|
||||
});
|
||||
|
||||
it("publishes travelling and settled only for the latest explicit epoch", () => {
|
||||
const harness = createRuntime(true);
|
||||
const controller = createNavigationController(sectionIds, harness.runtime);
|
||||
const states: NavigationState[] = [];
|
||||
controller.subscribe((state) => states.push(state));
|
||||
|
||||
controller.navigate("contact", target("contact"));
|
||||
controller.navigate("toolkit", target("toolkit"));
|
||||
expect(controller.state()).toMatchObject({
|
||||
epoch: 2,
|
||||
source: "explicit-navigation",
|
||||
phase: "travelling",
|
||||
destinationId: "toolkit",
|
||||
});
|
||||
|
||||
harness.emitScrollEnd();
|
||||
expect(controller.state()).toMatchObject({
|
||||
epoch: 2,
|
||||
phase: "settled",
|
||||
destinationId: "toolkit",
|
||||
});
|
||||
expect(states.filter((state) => state.phase === "settled")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("falls back to three consecutive sub-pixel-stable animation frames", () => {
|
||||
const harness = createRuntime(false);
|
||||
const controller = createNavigationController(sectionIds, harness.runtime);
|
||||
@@ -271,7 +297,9 @@ describe("navigation epochs and effects", () => {
|
||||
const controller = createNavigationController(sectionIds, harness.runtime);
|
||||
|
||||
expect(controller.initialize("toolkit", target("toolkit"))).toBe(1);
|
||||
expect(controller.state()).toMatchObject({ phase: "settled" });
|
||||
expect(controller.restore("profile", target("profile"))).toBe(2);
|
||||
expect(controller.state()).toMatchObject({ phase: "travelling" });
|
||||
harness.runFrame();
|
||||
expect(harness.pushes).toEqual([]);
|
||||
expect(harness.replacements).toEqual([]);
|
||||
@@ -283,6 +311,7 @@ describe("navigation epochs and effects", () => {
|
||||
expect(controller.state()).toEqual({
|
||||
epoch: 2,
|
||||
source: "history-restoration",
|
||||
phase: "settled",
|
||||
destinationId: "profile",
|
||||
signDestinationId: null,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user