@ecopages/browser-router 0.2.0-alpha.3 → 0.2.0-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +8 -7
  2. package/README.md +60 -37
  3. package/package.json +4 -2
  4. package/src/client/document-element-sync.d.ts +24 -0
  5. package/src/client/document-element-sync.js +20 -0
  6. package/src/client/eco-router.d.ts +35 -1
  7. package/src/client/eco-router.js +336 -77
  8. package/src/client/services/dom-swapper.d.ts +102 -0
  9. package/src/client/services/dom-swapper.js +316 -39
  10. package/src/client/services/prefetch-manager.d.ts +6 -3
  11. package/src/client/services/prefetch-manager.js +21 -11
  12. package/src/client/services/view-transition-manager.d.ts +7 -1
  13. package/src/client/services/view-transition-manager.js +21 -5
  14. package/src/client/types.d.ts +12 -0
  15. package/src/client/types.js +4 -0
  16. package/src/index.d.ts +2 -1
  17. package/src/index.js +9 -2
  18. package/src/types.d.ts +1 -1
  19. package/src/types.js +2 -1
  20. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Initialization-should-create-router-instance-1.png +0 -0
  21. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Initialization-should-start-and-stop-without-errors-1.png +0 -0
  22. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Lifecycle-Events-should-dispatch-eco-before-swap--eco-after-swap--and-eco-page-load-events-1.png +0 -0
  23. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Lifecycle-Events-should-dispatch-eco-page-load-event-after-animation-frame-1.png +0 -0
  24. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Lifecycle-Events-should-provide-event-details-with-url-and-direction-1.png +0 -0
  25. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Custom-Link-Selector-should-work-with-data-attribute-selector-1.png +0 -0
  26. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Custom-Reload-Attribute-should-intercept-links-with-default-reload-attribute-when-custom-is-set-1.png +0 -0
  27. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Custom-link-selector-should-only-intercept-links-matching-custom-selector-1.png +0 -0
  28. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-External-Links--should-NOT-intercept--should-NOT-intercept-external-links-1.png +0 -0
  29. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Internal-Links-should-intercept-clicks-on-relative-path-links-1.png +0 -0
  30. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Internal-Links-should-intercept-clicks-on-same-origin-absolute-URLs-1.png +0 -0
  31. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Link-Attributes--should-NOT-intercept--should-NOT-intercept-links-with-download-attribute-1.png +0 -0
  32. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Link-Attributes--should-NOT-intercept--should-intercept-links-with-target---self--1.png +0 -0
  33. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-alt-click-1.png +0 -0
  34. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-ctrl-click-1.png +0 -0
  35. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-meta-click--cmd-on-Mac--1.png +0 -0
  36. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-middle-mouse-button-click-1.png +0 -0
  37. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-right-mouse-button-click-1.png +0 -0
  38. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Modifier-keys-should-NOT-intercept-shift-click-1.png +0 -0
  39. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-external-links--different-origin--1.png +0 -0
  40. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-hash-only-links-1.png +0 -0
  41. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-javascript--links-1.png +0 -0
  42. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-custom-reload-attribute-1.png +0 -0
  43. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-data-eco-reload-attribute-1.png +0 -0
  44. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-download-attribute-1.png +0 -0
  45. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-empty-href-1.png +0 -0
  46. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-target---blank--1.png +0 -0
  47. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-with-target---parent--1.png +0 -0
  48. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-NOT-intercept-links-without-href-attribute-1.png +0 -0
  49. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-intercept-internal-links-with-absolute-same-origin-paths-1.png +0 -0
  50. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-intercept-internal-links-with-relative-paths-1.png +0 -0
  51. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-Should-intercept-nested-elements-inside-links-1.png +0 -0
  52. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Link-Interception-should-NOT-intercept-external-links-1.png +0 -0
  53. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Navigation-Abort-should-abort-previous-navigation-when-new-one-starts-1.png +0 -0
  54. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Programmatic-Navigation-should-navigate-and-update-history-with-pushState-1.png +0 -0
  55. package/src/client/__screenshots__/eco-router.test.browser.ts/EcoRouter-Programmatic-Navigation-should-use-replaceState-when-replace-option-is-true-1.png +0 -0
  56. package/src/client/__screenshots__/eco-router.test.ts/EcoRouter-Error-Handling-should-fall-back-to-full-page-navigation-on-fetch-error-1.png +0 -0
  57. package/src/client/__screenshots__/eco-router.test.ts/EcoRouter-Error-Handling-should-log-error-and-attempt-fallback-navigation-on-fetch-error-1.png +0 -0
  58. package/src/client/eco-router.ts +0 -310
  59. package/src/client/services/dom-swapper.ts +0 -325
  60. package/src/client/services/index.ts +0 -9
  61. package/src/client/services/prefetch-manager.ts +0 -457
  62. package/src/client/services/scroll-manager.ts +0 -48
  63. package/src/client/services/view-transition-manager.ts +0 -75
  64. package/src/client/types.ts +0 -109
  65. package/src/client/view-transition-utils.ts +0 -98
  66. package/src/index.ts +0 -19
  67. package/src/types.ts +0 -19
package/CHANGELOG.md CHANGED
@@ -8,19 +8,20 @@ All notable changes to `@ecopages/browser-router` are documented here.
8
8
 
9
9
  ### Features
10
10
 
11
- - **Light-DOM custom element support in `dom-swapper`** `morphdom` morphing process now correctly handles light-DOM custom elements during page transitions (`fce8080c`).
12
- - **Improved `morphHead` script injection** — New scripts from the incoming page's `<head>` are now injected and executed correctly during client-side navigation, even when not marked with `data-eco-rerun` (`08e15e99`).
13
- - **Global injector lifecycle management** — Enhanced global injector with structured lifecycle hooks and tests for hydration script handling (`2ba35aa4`).
11
+ - Added cross-router handoff hooks, configurable `<html>` attribute syncing, and public document sync helpers.
14
12
 
15
13
  ### Bug Fixes
16
14
 
17
- - Published npm package metadata now includes validated declaration exports for generated dist entrypoints.
18
- - Registered a current-page HMR refresh hook that invalidates cached HTML before re-fetching the active route.
15
+ - Fixed navigation races, duplicate script injection, and stale cleanup during repeated page swaps.
16
+ - Fixed mixed-runtime document ownership, script reruns, persisted head scripts, and client-managed `<html>` state during browser-router navigations.
17
+ - Fixed skipped View Transition lifecycle aborts leaking as unhandled browser-router test errors.
18
+ - Fixed body morph swaps retaining stale content when pages contain duplicate `id` attributes by limiting morphdom keying to explicitly persisted nodes.
19
+ - Fixed browser-router stylesheet prefetching to warm future page CSS without injecting unused `preload` hints that trigger browser console warnings.
19
20
 
20
21
  ### Refactoring
21
22
 
22
- - Removed unused `@types/morphdom` dev dependency (`ceb243d0`).
23
+ - Routed handoff and current-page reload behavior through the shared navigation coordinator.
23
24
 
24
25
  ### Documentation
25
26
 
26
- - README updated with new API usage examples.
27
+ - Updated the README examples for the current router API.
package/README.md CHANGED
@@ -1,34 +1,38 @@
1
1
  # @ecopages/browser-router
2
2
 
3
- Client-side navigation and view transitions for Ecopages. Intercepts same-origin link clicks to provide smooth page transitions without full page reloads.
3
+ Client-side navigation and view transitions for Ecopages. It intercepts same-origin link clicks to provide smooth page transitions without full page reloads.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Client-side navigation** - Intercepts `<a>` clicks for fast navigation
8
- - **Efficient DOM diffing** - Uses [morphdom](https://github.com/patrick-steele-idem/morphdom) to update only what changed, preserving scroll positions and internal state
9
- - **State persistence** - Elements with `data-eco-persist` are never recreated, preserving internal state
10
- - **View Transitions** - Optional integration with the View Transition API
11
- - **Lifecycle events** - Hook into navigation with `eco:before-swap`, `eco:after-swap`, `eco:page-load`
7
+ - **Client-side navigation**: Intercepts `<a>` clicks for robust, fast navigation.
8
+ - **Efficient DOM diffing**: Uses [morphdom](https://github.com/patrick-steele-idem/morphdom) to update only what changed, preserving scroll positions and internal state.
9
+ - **State persistence**: Elements with `data-eco-persist` are never recreated, preserving Web Component state, event listeners, and form values.
10
+ - **View Transitions**: Optional integration with the View Transition API.
11
+ - **Lifecycle events**: Hook into navigation with `eco:before-swap`, `eco:after-swap`, `eco:page-load`.
12
12
 
13
13
  ## Compatibility
14
14
 
15
- This package works with MPA-style rendering (KitaJS, Lit, vanilla JS) where the server returns full HTML pages.
15
+ This package is designed for MPA-style rendering where the server returns full HTML pages (e.g., KitaJS, Lit, vanilla JS, or component-level React islands).
16
16
 
17
- **Not compatible with React/Preact** - These frameworks manage their own virtual DOM and component trees. Replacing the DOM breaks hydration, state, and event handlers. For React apps, use a framework-specific routing solution.
17
+ > [!WARNING]
18
+ > **Not compatible with full React applications.**
19
+ > If you are building a React application, use [@ecopages/react-router](../react-router/README.md) instead, as React manages its own virtual DOM and hydration lifecycle.
18
20
 
19
- Component-level islands are a narrower case: small interactive roots emitted by another integration (for example a React island inside an otherwise MPA-style page) can work with `@ecopages/browser-router`, because ownership stays scoped to the island root instead of the full document.
21
+ > [!NOTE]
22
+ > `@ecopages/browser-router` can still participate in mixed sites that contain both React-router pages and non-React pages. In that setup, browser-router remains responsible for DOM-swapping non-React documents, and React-router can hand off already-fetched non-React pages to it through the shared navigation coordinator.
20
23
 
21
24
  ## Installation
22
25
 
23
26
  ```bash
24
- bunx jsr add @ecopages/browser-router
27
+ bun add @ecopages/browser-router
25
28
  ```
26
29
 
27
30
  ## Usage
28
31
 
29
32
  Create and start the router in a **global** client-side script (e.g., `src/layouts/base-layout.script.ts`).
30
33
 
31
- > **Important**: Ensure the router script is injected in a **consistent order** within the `<head>` across all pages. Inconsistent ordering (e.g. script between styles on one page but after on another) causes `morphdom` to reload styles, leading to a "Flash of Unstyled Content" (FOUC).
34
+ > [!IMPORTANT]
35
+ > Ensure the router script is injected in a **consistent order** within the `<head>` across all pages. Inconsistent ordering causes `morphdom` to reload styles, leading to a "Flash of Unstyled Content" (FOUC).
32
36
 
33
37
  ```ts
34
38
  import { createRouter } from '@ecopages/browser-router/client';
@@ -45,54 +49,71 @@ import { createRouter } from '@ecopages/browser-router/client';
45
49
  const router = createRouter({
46
50
  viewTransitions: true,
47
51
  scrollBehavior: 'auto',
52
+ documentElementAttributesToSync: ['lang', 'dir', 'data-theme'],
48
53
  });
49
54
  ```
50
55
 
56
+ By default, browser-router only syncs root `<html>` metadata it owns. Client-managed attributes and classes such as theme state are preserved unless you explicitly include them in `documentElementAttributesToSync`.
57
+
58
+ For advanced cases, browser-router also exports low-level document sync tooling without changing the router instance API:
59
+
60
+ ```ts
61
+ import {
62
+ createRouter,
63
+ defaultDocumentElementAttributesToSync,
64
+ syncDocumentElementAttributes,
65
+ } from '@ecopages/browser-router';
66
+
67
+ const router = createRouter();
68
+
69
+ document.addEventListener('eco:before-swap', (event) => {
70
+ syncDocumentElementAttributes(document, event.detail.newDocument, [
71
+ ...defaultDocumentElementAttributesToSync,
72
+ 'data-theme',
73
+ ]);
74
+ });
75
+ ```
76
+
77
+ Loading the router script is the opt-in point for browser-router-managed navigation on that page shell. Pages without the router script continue to use normal document navigation.
78
+
51
79
  ## Configuration
52
80
 
53
- | Option | Type | Default | Description |
54
- | :----------------- | :-----------------------------: | :------------------: | :--------------------------------------------- |
55
- | `linkSelector` | `string` | `'a[href]'` | Selector for links to intercept |
56
- | `persistAttribute` | `string` | `'data-eco-persist'` | Attribute to mark elements for DOM persistence |
57
- | `reloadAttribute` | `string` | `'data-eco-reload'` | Attribute to force full page reload |
58
- | `updateHistory` | `boolean` | `true` | Whether to update browser history |
59
- | `scrollBehavior` | `'top' \| 'preserve' \| 'auto'` | `'top'` | Scroll behavior after navigation |
60
- | `viewTransitions` | `boolean` | `false` | Use View Transition API for animations |
61
- | `smoothScroll` | `boolean` | `false` | Use smooth scrolling during navigation |
81
+ | Option | Type | Default | Description |
82
+ | :-------------------------------- | :------------------------------ | :------------------------------------------- | :------------------------------------------------------------------------------------------ |
83
+ | `linkSelector` | `string` | `'a[href]'` | Selector for links to intercept |
84
+ | `documentElementAttributesToSync` | `string[]` | `['lang', 'dir', 'data-eco-document-owner']` | `<html>` attributes to sync from the incoming document; other root attributes are preserved |
85
+ | `persistAttribute` | `string` | `'data-eco-persist'` | Attribute to mark elements for DOM persistence |
86
+ | `reloadAttribute` | `string` | `'data-eco-reload'` | Attribute to force full page reload |
87
+ | `updateHistory` | `boolean` | `true` | Whether to update browser history |
88
+ | `scrollBehavior` | `'top' \| 'preserve' \| 'auto'` | `'top'` | Scroll behavior after navigation |
89
+ | `viewTransitions` | `boolean` | `false` | Use View Transition API for animations |
90
+ | `smoothScroll` | `boolean` | `false` | Use smooth scrolling during navigation |
62
91
 
63
92
  ## Persistence
64
93
 
65
- Mark elements to preserve across navigations. These elements are never recreated during navigation, morphdom skips them entirely, preserving their internal state (event listeners, web component state, form values, etc.):
94
+ Mark elements to preserve across navigations. These elements are never recreated during navigation; morphdom skips them entirely.
66
95
 
67
96
  ```html
68
- <!-- This counter keeps its state across all navigations -->
97
+ <!-- This counter keeps its internal state across all navigations -->
69
98
  <radiant-counter data-eco-persist="counter"></radiant-counter>
70
99
  ```
71
100
 
72
101
  ## Script Re-execution
73
102
 
74
- To force a script to re-execute on every navigation (e.g. analytics, hydration), add `data-eco-rerun` and `data-eco-script-id`:
103
+ To force a script to re-execute on every navigation (e.g., analytics), add `data-eco-rerun`:
75
104
 
76
105
  ```html
77
- <script data-eco-rerun="true" data-eco-script-id="analytics">
78
- // This runs on every navigation
106
+ <script data-eco-rerun="true">
79
107
  trackPageview();
80
108
  </script>
81
109
  ```
82
110
 
83
- ### React islands with `@ecopages/browser-router`
84
-
85
- When `@ecopages/browser-router` is used in an MPA-style app that also renders component-level React islands:
86
-
87
- - island hydration scripts may need to run again after `eco:after-swap`
88
- - hydration bootstraps should carry stable `data-eco-script-id` metadata
89
- - `data-eco-rerun` allows those bootstraps to be re-executed safely during head reconciliation
90
-
91
- This note is specific to DOM-swapping navigation with `@ecopages/browser-router`. It does **not** apply to full React applications using [@ecopages/react-router](../react-router/README.md), where page routing and hydration are handled by the React router runtime itself.
111
+ > [!NOTE]
112
+ > `data-eco-script-id` is optional. Use it when you want an explicit stable identity for a rerun script. Otherwise the router falls back to matching by original `src` and inline content.
92
113
 
93
114
  ## Force Full Reload
94
115
 
95
- Use `data-eco-reload` to force a full page reload:
116
+ Use `data-eco-reload` on an anchor tag to bypass the router and force a full page reload:
96
117
 
97
118
  ```html
98
119
  <a href="/logout" data-eco-reload>Logout</a>
@@ -100,12 +121,12 @@ Use `data-eco-reload` to force a full page reload:
100
121
 
101
122
  ## Events
102
123
 
103
- Listen to navigation lifecycle events:
124
+ Listen to navigation lifecycle events on the `document`:
104
125
 
105
126
  ```ts
106
127
  document.addEventListener('eco:before-swap', (e) => {
107
128
  console.log('Navigating to:', e.detail.url);
108
- // Call e.detail.reload() to abort and do full reload
129
+ // Call e.detail.reload() to abort client-side navigation and do a full reload
109
130
  });
110
131
 
111
132
  document.addEventListener('eco:after-swap', (e) => {
@@ -119,6 +140,8 @@ document.addEventListener('eco:page-load', (e) => {
119
140
 
120
141
  ## Programmatic Navigation
121
142
 
143
+ Use the router instance to navigate programmatically:
144
+
122
145
  ```ts
123
146
  import { createRouter } from '@ecopages/browser-router/client';
124
147
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/browser-router",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.0-alpha.31",
4
4
  "description": "Client-side router for Ecopages with view transitions support",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -32,8 +32,10 @@
32
32
  "directory": "packages/browser-router"
33
33
  },
34
34
  "dependencies": {
35
- "@ecopages/core": "0.2.0-alpha.3",
36
35
  "morphdom": "^2.7.8"
37
36
  },
37
+ "peerDependencies": {
38
+ "@ecopages/core": "0.2.0-alpha.31"
39
+ },
38
40
  "types": "./src/index.d.ts"
39
41
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Helpers for synchronizing selected root `<html>` attributes during client-side navigation.
3
+ * @module
4
+ */
5
+ /**
6
+ * Default root `<html>` attributes that browser-router treats as document-owned.
7
+ *
8
+ * These attributes are synchronized from the incoming document during navigation.
9
+ * Other root attributes are preserved unless explicitly included.
10
+ */
11
+ export declare const defaultDocumentElementAttributesToSync: string[];
12
+ /**
13
+ * Synchronizes a selected set of root `<html>` attributes from an incoming document
14
+ * onto the current live document.
15
+ *
16
+ * Attributes listed here are treated as document-owned metadata. Attributes not
17
+ * listed remain untouched on the live document so client-managed state can survive
18
+ * across navigation swaps.
19
+ *
20
+ * @param currentDocument - The live document being updated
21
+ * @param newDocument - The parsed incoming document for the next page
22
+ * @param attributes - Root `<html>` attributes to synchronize
23
+ */
24
+ export declare function syncDocumentElementAttributes(currentDocument: Document, newDocument: Document, attributes: readonly string[]): void;
@@ -0,0 +1,20 @@
1
+ import { DEFAULT_DOCUMENT_ELEMENT_ATTRIBUTES_TO_SYNC } from "./types.js";
2
+ const defaultDocumentElementAttributesToSync = DEFAULT_DOCUMENT_ELEMENT_ATTRIBUTES_TO_SYNC;
3
+ function syncDocumentElementAttributes(currentDocument, newDocument, attributes) {
4
+ const currentHtml = currentDocument.documentElement;
5
+ const nextHtml = newDocument.documentElement;
6
+ for (const attributeName of attributes) {
7
+ const nextValue = nextHtml.getAttribute(attributeName);
8
+ if (nextValue === null) {
9
+ currentHtml.removeAttribute(attributeName);
10
+ continue;
11
+ }
12
+ if (currentHtml.getAttribute(attributeName) !== nextValue) {
13
+ currentHtml.setAttribute(attributeName, nextValue);
14
+ }
15
+ }
16
+ }
17
+ export {
18
+ defaultDocumentElementAttributesToSync,
19
+ syncDocumentElementAttributes
20
+ };
@@ -9,12 +9,36 @@ import type { EcoRouterOptions } from './types.js';
9
9
  */
10
10
  export declare class EcoRouter {
11
11
  private options;
12
- private abortController;
12
+ private unregisterNavigationRuntime;
13
+ private started;
14
+ private pendingNavigations;
15
+ private pendingPointerNavigation;
16
+ private pendingHoverNavigation;
17
+ private queuedNavigationHref;
13
18
  private domSwapper;
14
19
  private scrollManager;
15
20
  private viewTransitionManager;
16
21
  private prefetchManager;
17
22
  constructor(options?: EcoRouterOptions);
23
+ private getLinkFromEvent;
24
+ private canInterceptLink;
25
+ private getRecoveredPointerHref;
26
+ private getRecoveredHoverHref;
27
+ private isAnotherNavigationRuntimeActive;
28
+ private getDocumentOwner;
29
+ private adoptDocumentOwner;
30
+ private syncDocumentElementAttributes;
31
+ private reloadDocument;
32
+ /**
33
+ * Commits a fully fetched document into the live page.
34
+ *
35
+ * When browser-router accepts a handoff from another runtime, it delays source
36
+ * runtime cleanup until the incoming document has been prepared and is ready to
37
+ * commit. That ordering avoids the blank-page window we previously hit when a
38
+ * delegated navigation went stale after the source runtime had already torn
39
+ * itself down.
40
+ */
41
+ private commitDocumentNavigation;
18
42
  /**
19
43
  * Starts the router and begins intercepting navigation.
20
44
  *
@@ -51,6 +75,8 @@ export declare class EcoRouter {
51
75
  * Uses `event.composedPath()` to correctly detect clicks on anchors inside
52
76
  * Shadow DOM boundaries (Web Components).
53
77
  */
78
+ private handlePointerDown;
79
+ private handleHoverIntent;
54
80
  private handleClick;
55
81
  /**
56
82
  * Handles browser back/forward navigation.
@@ -62,6 +88,8 @@ export declare class EcoRouter {
62
88
  * Cross-origin navigation always falls back to full page reload.
63
89
  */
64
90
  private isSameOrigin;
91
+ private cancelNavigationTransaction;
92
+ private beginNavigationTransaction;
65
93
  /**
66
94
  * Executes the core navigation flow.
67
95
  *
@@ -91,6 +119,12 @@ export declare class EcoRouter {
91
119
  }
92
120
  /**
93
121
  * Creates and starts a router instance.
122
+ *
123
+ * Stops the previously active router (if any) before creating a new one so
124
+ * click listeners and coordinator registrations from earlier instances are
125
+ * cleaned up on re-execution (e.g. when the layout script is re-run via
126
+ * `data-eco-rerun` after a browser-router page commit).
127
+ *
94
128
  * @param options - Configuration options for the router
95
129
  * @returns A started EcoRouter instance
96
130
  */