@real-router/angular 0.11.2 → 0.11.3

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.
@@ -11,8 +11,8 @@ class ClientOnly {
11
11
  this.mounted.set(true);
12
12
  });
13
13
  }
14
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ClientOnly, deps: [], target: i0.ɵɵFactoryTarget.Component });
15
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ClientOnly, isStandalone: true, selector: "client-only", inputs: { fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
14
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ClientOnly, deps: [], target: i0.ɵɵFactoryTarget.Component });
15
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ClientOnly, isStandalone: true, selector: "client-only", inputs: { fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
16
16
  @if (mounted()) {
17
17
  <ng-content />
18
18
  } @else if (fallback()) {
@@ -20,7 +20,7 @@ class ClientOnly {
20
20
  }
21
21
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
22
22
  }
23
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ClientOnly, decorators: [{
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ClientOnly, decorators: [{
24
24
  type: Component,
25
25
  args: [{
26
26
  selector: "client-only",
@@ -43,8 +43,8 @@ class ServerOnly {
43
43
  this.mounted.set(true);
44
44
  });
45
45
  }
46
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ServerOnly, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ServerOnly, isStandalone: true, selector: "server-only", inputs: { fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ServerOnly, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ServerOnly, isStandalone: true, selector: "server-only", inputs: { fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
48
48
  @if (!mounted()) {
49
49
  <ng-content />
50
50
  } @else if (fallback()) {
@@ -52,7 +52,7 @@ class ServerOnly {
52
52
  }
53
53
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
54
54
  }
55
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ServerOnly, decorators: [{
55
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ServerOnly, decorators: [{
56
56
  type: Component,
57
57
  args: [{
58
58
  selector: "server-only",
@@ -182,10 +182,10 @@ class HttpStatusCode {
182
182
  this.sink.code = value;
183
183
  }
184
184
  }
185
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: HttpStatusCode, deps: [], target: i0.ɵɵFactoryTarget.Component });
186
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: HttpStatusCode, isStandalone: true, selector: "http-status-code", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "", isInline: true });
185
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HttpStatusCode, deps: [], target: i0.ɵɵFactoryTarget.Component });
186
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: HttpStatusCode, isStandalone: true, selector: "http-status-code", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "", isInline: true });
187
187
  }
188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: HttpStatusCode, decorators: [{
188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HttpStatusCode, decorators: [{
189
189
  type: Component,
190
190
  args: [{
191
191
  selector: "http-status-code",
@@ -695,6 +695,7 @@ const createUrlPluginDetector = (router, onMissing) => {
695
695
  // boolean, a hypothetical multi-fire would double-warn.
696
696
  let detectionConsumed = false;
697
697
  detectionUnsub = router.subscribe(({ route }) => {
698
+ /* v8 ignore next 3 -- @preserve: the multi-fire is hypothetical (see above) — the real router never invokes a subscriber synchronously twice before unsub; defensive guard, not testable without a contract-violating fake */
698
699
  if (detectionConsumed) {
699
700
  return;
700
701
  }
@@ -1279,10 +1280,10 @@ function navigateWithHash(router, routeName, routeParams, hash, extraOptions) {
1279
1280
  // for the slow-path branch.
1280
1281
  const WHITESPACE_PROBE = /\s/;
1281
1282
  const WHITESPACE_SPLIT = /\S+/g;
1283
+ // `value` is always a truthy class string: both call sites narrow it first
1284
+ // (`if (isActive && activeClassName)` / `if (!baseClassName) return …`), so the
1285
+ // former `if (!value) return []` guard was unreachable dead code (#809).
1282
1286
  function parseTokens(value) {
1283
- if (!value) {
1284
- return [];
1285
- }
1286
1287
  // Hot-path fast-path (audit-2026-05-17 §8b #1): >99% of active-class
1287
1288
  // inputs at `<Link>` emit are single-token strings like `"active"` or
1288
1289
  // `"is-current"` — no whitespace, no leading/trailing pad. Skip the
@@ -1933,30 +1934,30 @@ function injectRouteEnter(handler, options) {
1933
1934
  class RouteMatch {
1934
1935
  routeMatch = input.required(...(ngDevMode ? [{ debugName: "routeMatch" }] : /* istanbul ignore next */ []));
1935
1936
  templateRef = inject(TemplateRef);
1936
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteMatch, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1937
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: RouteMatch, isStandalone: true, selector: "ng-template[routeMatch]", inputs: { routeMatch: { classPropertyName: "routeMatch", publicName: "routeMatch", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1937
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteMatch, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1938
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: RouteMatch, isStandalone: true, selector: "ng-template[routeMatch]", inputs: { routeMatch: { classPropertyName: "routeMatch", publicName: "routeMatch", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1938
1939
  }
1939
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteMatch, decorators: [{
1940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteMatch, decorators: [{
1940
1941
  type: Directive,
1941
1942
  args: [{ selector: "ng-template[routeMatch]" }]
1942
1943
  }], propDecorators: { routeMatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeMatch", required: true }] }] } });
1943
1944
 
1944
1945
  class RouteNotFound {
1945
1946
  templateRef = inject(TemplateRef);
1946
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteNotFound, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1947
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.13", type: RouteNotFound, isStandalone: true, selector: "ng-template[routeNotFound]", ngImport: i0 });
1947
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteNotFound, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1948
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: RouteNotFound, isStandalone: true, selector: "ng-template[routeNotFound]", ngImport: i0 });
1948
1949
  }
1949
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteNotFound, decorators: [{
1950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteNotFound, decorators: [{
1950
1951
  type: Directive,
1951
1952
  args: [{ selector: "ng-template[routeNotFound]" }]
1952
1953
  }] });
1953
1954
 
1954
1955
  class RouteSelf {
1955
1956
  templateRef = inject(TemplateRef);
1956
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteSelf, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1957
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.13", type: RouteSelf, isStandalone: true, selector: "ng-template[routeSelf]", ngImport: i0 });
1957
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteSelf, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1958
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: RouteSelf, isStandalone: true, selector: "ng-template[routeSelf]", ngImport: i0 });
1958
1959
  }
1959
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteSelf, decorators: [{
1960
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteSelf, decorators: [{
1960
1961
  type: Directive,
1961
1962
  args: [{ selector: "ng-template[routeSelf]" }]
1962
1963
  }] });
@@ -2082,14 +2083,14 @@ class RouteView {
2082
2083
  }));
2083
2084
  });
2084
2085
  }
2085
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteView, deps: [], target: i0.ɵɵFactoryTarget.Component });
2086
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: RouteView, isStandalone: true, selector: "route-view", inputs: { nodeName: { classPropertyName: "nodeName", publicName: "routeNode", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "matches", predicate: RouteMatch, descendants: true, isSignal: true }, { propertyName: "selfs", predicate: RouteSelf, descendants: true, isSignal: true }, { propertyName: "notFounds", predicate: RouteNotFound, descendants: true, isSignal: true }], ngImport: i0, template: `
2086
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteView, deps: [], target: i0.ɵɵFactoryTarget.Component });
2087
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: RouteView, isStandalone: true, selector: "route-view", inputs: { nodeName: { classPropertyName: "nodeName", publicName: "routeNode", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "matches", predicate: RouteMatch, descendants: true, isSignal: true }, { propertyName: "selfs", predicate: RouteSelf, descendants: true, isSignal: true }, { propertyName: "notFounds", predicate: RouteNotFound, descendants: true, isSignal: true }], ngImport: i0, template: `
2087
2088
  @if (activeTemplate()) {
2088
2089
  <ng-container [ngTemplateOutlet]="activeTemplate()!" />
2089
2090
  }
2090
2091
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2091
2092
  }
2092
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouteView, decorators: [{
2093
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouteView, decorators: [{
2093
2094
  type: Component,
2094
2095
  args: [{
2095
2096
  selector: "route-view",
@@ -2135,8 +2136,8 @@ class RouterErrorBoundary {
2135
2136
  }
2136
2137
  });
2137
2138
  }
2138
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouterErrorBoundary, deps: [], target: i0.ɵɵFactoryTarget.Component });
2139
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: RouterErrorBoundary, isStandalone: true, selector: "router-error-boundary", inputs: { errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onError: "onError" }, ngImport: i0, template: `
2139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouterErrorBoundary, deps: [], target: i0.ɵɵFactoryTarget.Component });
2140
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: RouterErrorBoundary, isStandalone: true, selector: "router-error-boundary", inputs: { errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onError: "onError" }, ngImport: i0, template: `
2140
2141
  <ng-content />
2141
2142
  @if (errorContext() && errorTemplate()) {
2142
2143
  <ng-container
@@ -2146,7 +2147,7 @@ class RouterErrorBoundary {
2146
2147
  }
2147
2148
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2148
2149
  }
2149
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RouterErrorBoundary, decorators: [{
2150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RouterErrorBoundary, decorators: [{
2150
2151
  type: Component,
2151
2152
  args: [{
2152
2153
  selector: "router-error-boundary",
@@ -2170,10 +2171,10 @@ class NavigationAnnouncer {
2170
2171
  this.announcer.destroy();
2171
2172
  });
2172
2173
  }
2173
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: NavigationAnnouncer, deps: [], target: i0.ɵɵFactoryTarget.Component });
2174
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: NavigationAnnouncer, isStandalone: true, selector: "navigation-announcer", ngImport: i0, template: "", isInline: true });
2174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NavigationAnnouncer, deps: [], target: i0.ɵɵFactoryTarget.Component });
2175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.17", type: NavigationAnnouncer, isStandalone: true, selector: "navigation-announcer", ngImport: i0, template: "", isInline: true });
2175
2176
  }
2176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: NavigationAnnouncer, decorators: [{
2177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NavigationAnnouncer, decorators: [{
2177
2178
  type: Component,
2178
2179
  args: [{
2179
2180
  selector: "navigation-announcer",
@@ -2262,10 +2263,10 @@ class RealLink {
2262
2263
  }
2263
2264
  this.prevActiveClass = activeClass;
2264
2265
  }
2265
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RealLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2266
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: RealLink, isStandalone: true, selector: "a[realLink]", inputs: { routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, routeOptions: { classPropertyName: "routeOptions", publicName: "routeOptions", isSignal: true, isRequired: false, transformFunction: null }, activeClassName: { classPropertyName: "activeClassName", publicName: "activeClassName", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null }, hash: { classPropertyName: "hash", publicName: "hash", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
2266
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RealLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2267
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: RealLink, isStandalone: true, selector: "a[realLink]", inputs: { routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, routeOptions: { classPropertyName: "routeOptions", publicName: "routeOptions", isSignal: true, isRequired: false, transformFunction: null }, activeClassName: { classPropertyName: "activeClassName", publicName: "activeClassName", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null }, hash: { classPropertyName: "hash", publicName: "hash", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
2267
2268
  }
2268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RealLink, decorators: [{
2269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RealLink, decorators: [{
2269
2270
  type: Directive,
2270
2271
  args: [{
2271
2272
  selector: "a[realLink]",
@@ -2314,10 +2315,10 @@ class RealLinkActive {
2314
2315
  }
2315
2316
  this.element.classList.toggle(className, this.isActive());
2316
2317
  }
2317
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RealLinkActive, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2318
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: RealLinkActive, isStandalone: true, selector: "[realLinkActive]", inputs: { realLinkActive: { classPropertyName: "realLinkActive", publicName: "realLinkActive", isSignal: true, isRequired: false, transformFunction: null }, routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
2318
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RealLinkActive, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2319
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: RealLinkActive, isStandalone: true, selector: "[realLinkActive]", inputs: { realLinkActive: { classPropertyName: "realLinkActive", publicName: "realLinkActive", isSignal: true, isRequired: false, transformFunction: null }, routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
2319
2320
  }
2320
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RealLinkActive, decorators: [{
2321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: RealLinkActive, decorators: [{
2321
2322
  type: Directive,
2322
2323
  args: [{ selector: "[realLinkActive]" }]
2323
2324
  }], ctorParameters: () => [], propDecorators: { realLinkActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "realLinkActive", required: false }] }], routeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeName", required: false }] }], routeParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeParams", required: false }] }], activeStrict: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStrict", required: false }] }], ignoreQueryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryParams", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"real-router-angular.mjs","sources":["../../src/dom-utils/direction-tracker.ts","../../src/dom-utils/route-announcer.ts","../../src/dom-utils/scroll-restore.ts","../../src/dom-utils/scroll-spy.ts","../../src/dom-utils/view-transitions.ts","../../src/dom-utils/link-utils.ts","../../src/internal/install.ts","../../src/sourceToSignal.ts","../../src/providers.ts","../../src/providersFactory.ts","../../src/functions/injectOrThrow.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/internal/buildActiveRouteOptions.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/internal/subscribeSourceToSignal.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts","../../src/real-router-angular.ts"],"sourcesContent":["import type { Router } from \"@real-router/core\";\n\nexport interface DirectionTracker {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: DirectionTracker = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n/**\n * Track navigation direction (forward / back) and write it to\n * `<html data-nav-direction>` on every leave. CSS / JS readers consume\n * the attribute via `html[data-nav-direction=\"back\"]` selectors or\n * `document.documentElement.dataset.navDirection`.\n *\n * Mechanism-agnostic — works identically whether downstream UI uses CSS\n * `@keyframes`, View Transitions pseudo-elements, or library state\n * (motion's `motion.div initial={{ x: ... }}`).\n *\n * Implementation:\n * - On install, set `data-nav-direction=\"forward\"` baseline.\n * - Attach a `popstate` listener that flips an internal flag to\n * `true`. Browser back/forward navigation triggers popstate; user\n * clicks on `<Link>` / programmatic `router.navigate(...)` do not.\n * - On every `subscribeLeave`, write\n * `popstateFlag ? \"back\" : \"forward\"` and reset the flag.\n *\n * Returns `{ destroy }` to clean up the listener and clear the dataset\n * attribute.\n */\nexport function createDirectionTracker(router: Router): DirectionTracker {\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n let popstateFlag = false;\n\n document.documentElement.dataset.navDirection = \"forward\";\n\n const onPopstate = (): void => {\n popstateFlag = true;\n };\n\n // IMPORTANT — listener-ordering: `popstate` fires on `window`, which\n // has no DOM descendants, so capture phase is moot. Listeners are\n // dispatched in registration order. To beat the browser-plugin's own\n // popstate handler, this tracker must be installed **before**\n // `router.usePlugin(browserPluginFactory())` in user code. Otherwise\n // the plugin's handler runs first and synchronously fires\n // `subscribeLeave` while `popstateFlag` is still `false`.\n globalThis.addEventListener(\"popstate\", onPopstate);\n\n const offLeave = router.subscribeLeave(() => {\n document.documentElement.dataset.navDirection = popstateFlag\n ? \"back\"\n : \"forward\";\n popstateFlag = false;\n });\n\n return {\n destroy: () => {\n offLeave();\n globalThis.removeEventListener(\"popstate\", onPopstate);\n delete document.documentElement.dataset.navDirection;\n },\n };\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n // Defensive SSR / non-browser guard: in SSR (Node.js) or non-DOM\n // environments, `document` is undefined and the announcer cannot\n // attach its aria-live region. Return a frozen NOOP_INSTANCE — same\n // pattern as `createDirectionTracker`, `createScrollRestoration`, and\n // `createViewTransitions`. Without this guard, `NavigationAnnouncer`\n // component construction would throw `ReferenceError: document is not\n // defined` under `@angular/ssr` rendering, tearing down the whole SSR\n // bootstrap. Closes review-2026-05-10 §5.10 ⛔ \"NavigationAnnouncer\n // SSR mode\" MED.\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n // Defensive SSR / pre-`<body>` guard: in some environments (early\n // injection, deferred-body documents, certain SSR rehydration paths)\n // `document.body` can be null when the announcer is constructed.\n // `document.body.prepend(...)` would throw `TypeError: Cannot read\n // properties of null`, tearing down the consumer's RouterProvider /\n // NavigationAnnouncer mount. Fallback to `documentElement` keeps the\n // announcer working for SR users; visual-hidden styling means there is\n // no visible artifact regardless of mount point.\n //\n // TS dom lib types `document.body` as `HTMLElement` (non-null), but\n // runtime can return null per spec. The `as` cast narrows the type to\n // include null so the `??` short-circuit is type-safe.\n ((document.body as HTMLElement | null) ?? document.documentElement).prepend(\n element,\n );\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n try {\n const customText = getCustomText(route);\n\n // Mini-sprint E.4 (audit-5 §4.2 #4) — empty-string fallback.\n // A consumer pattern like\n // getAnnouncementText: (route) => myMap[route.name] ?? \"\"\n // returns `\"\"` for routes outside the map. The subscribe loop\n // then sees an empty text and silently no-announces — screen\n // readers stay quiet without any signal to the developer. Treat\n // a falsy custom result (`\"\"` / `null` / `undefined`) as\n // \"consumer doesn't have a name for this route\" and fall through\n // to the default resolution chain (h1 → title → route name).\n if (customText) {\n return customText;\n }\n } catch (error) {\n // A throwing consumer callback inside the router's subscribe loop\n // would tear down sibling listeners — log and fall through to the\n // built-in resolution chain so the announcer keeps working.\n console.error(\n \"[real-router] getAnnouncementText threw; falling back to default resolution.\",\n error,\n );\n }\n }\n\n const h1Text = (h1?.textContent ?? \"\").trim();\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst DEFAULT_STORAGE_KEY = \"real-router:scroll\";\n\n// Bounded retry budget for resolving a late-mounting scroll container on the\n// restore path. A per-route container (e.g. an `overflow:auto` div rendered\n// only on one route) can be committed to the DOM a few frames after the\n// navigation settles — heavier routes paint later than the subscribe's rAF.\n// ~10 frames (≈160ms at 60fps) comfortably covers a React commit of a large\n// route without being perceptible. See the doc-block on `restorePos`.\nconst RESTORE_RETRY_FRAMES = 10;\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"native\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n /**\n * Scroll behavior passed to `scrollTo({ behavior })` and\n * `scrollIntoView({ behavior })`.\n *\n * - `\"auto\"` (default) — browser-defined, usually instant.\n * - `\"instant\"` — explicit instant jump (no animation).\n * - `\"smooth\"` — animated transition. Note: smooth restore on back/traverse\n * can feel disorienting if the user expects to land at the saved position\n * immediately. Recommended for `mode: \"top\"` or anchor scroll only.\n *\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).\n */\n behavior?: ScrollBehavior | undefined;\n /**\n * sessionStorage key used to persist saved scroll positions. Default:\n * `\"real-router:scroll\"`. Override only when multiple independent\n * `RouterProvider` instances share the same document and you need to\n * isolate their scroll stores (e.g. micro-frontends, embedded widgets,\n * or testing). For a single app with one provider the default is fine.\n */\n storageKey?: string | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"native\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — `history.scrollRestoration`\n // stays at the browser default (\"auto\") so the browser handles scroll\n // restore natively. (Note: this is the OPPOSITE of `history.scrollRestoration\n // === \"manual\"` — utility's \"native\" leaves the DOM property at \"auto\" so\n // the browser is in charge.)\n if (mode === \"native\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n const behavior: ScrollBehavior = options?.behavior ?? \"auto\";\n const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;\n\n // Write-through in-memory cache: parse sessionStorage once per provider\n // mount, then mutate in-memory. Avoids a JSON.parse + JSON.stringify pair\n // on every subscribeLeave / pagehide event.\n let store: Record<string, number> | undefined;\n\n const loadStore = (): Record<string, number> => {\n if (store !== undefined) {\n return store;\n }\n\n try {\n const raw = sessionStorage.getItem(storageKey);\n\n store = raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n store = {};\n }\n\n return store;\n };\n\n const putPos = (key: string, pos: number): void => {\n try {\n const cached = loadStore();\n\n // Skip-same-value: when a route is left at the same scroll position it\n // already holds in the cache (e.g. tab-switching without scrolling),\n // both the in-memory write and the JSON.stringify + setItem pair are\n // no-ops. Eliminates redundant serialization on the navigation hot\n // path for the common \"click tabs without scrolling\" case.\n if (cached[key] === pos) {\n return;\n }\n\n cached[key] = pos;\n sessionStorage.setItem(storageKey, JSON.stringify(cached));\n } catch {\n // Ignore quota / security errors.\n }\n };\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTo({ top, left: 0, behavior });\n } else {\n globalThis.scrollTo({ top, left: 0, behavior });\n }\n };\n\n // Restore path (back / traverse / reload). Unlike `writePos`, this tolerates a\n // scroll container that both MOUNTS and LAYS OUT a few frames AFTER the\n // navigation settles.\n //\n // The capture-side `readPos` always runs against an already-mounted DOM (the\n // route being left). On restore the target route — and its container — is\n // still being committed by the view layer. The subscribe callback schedules a\n // single rAF; for a heavy route (e.g. a long virtual list) the framework's\n // commit can land AFTER that frame. Two distinct failures follow, each losing\n // the saved position (Scenario 6 e2e, reproduced under CI's slower runner):\n //\n // 1. Container not mounted yet → `getContainer()` is `null`, the scroll\n // silently falls back to `window`, which on a container-only route has\n // nothing to scroll.\n // 2. Container mounted but its content not laid out yet → `scrollHeight`\n // is still small, so a single `scrollTo({ top })` clamps short of the\n // saved position and never re-applies once layout grows.\n //\n // With no `scrollContainer` getter the target is always `window`, present\n // from the first frame — restore in a single shot (unchanged behaviour). When\n // a getter is configured we cannot tell \"this route legitimately uses window\"\n // from \"the container is still mounting\", so re-apply the scroll on every\n // frame for a bounded budget: window as a fallback while the container is\n // absent (harmless clamp on container routes), the container itself once it\n // appears. For instant restores we stop early the moment the position sticks;\n // smooth restores animate asynchronously, so they run the full budget. The\n // frame budget is the hard backstop against an unreachable target (saved\n // position taller than the restored content).\n const restorePos = (top: number): void => {\n if (!getContainer) {\n globalThis.scrollTo({ top, left: 0, behavior });\n\n return;\n }\n\n let frames = 0;\n\n const attempt = (): void => {\n if (destroyed) {\n return;\n }\n\n const element = getContainer();\n\n if (element) {\n element.scrollTo({ top, left: 0, behavior });\n\n // Instant restore landed within rounding tolerance → done; no point\n // re-applying. Smooth restore never matches synchronously, so let it\n // ride the budget.\n if (behavior !== \"smooth\" && Math.abs(element.scrollTop - top) <= 1) {\n return;\n }\n } else {\n globalThis.scrollTo({ top, left: 0, behavior });\n }\n\n if (frames >= RESTORE_RETRY_FRAMES) {\n return;\n }\n\n frames += 1;\n requestAnimationFrame(attempt);\n };\n\n attempt();\n };\n\n const scrollToHashOrTop = (route: State): void => {\n // URL plugin path (#532): `state.context.url.hash` is the source of truth\n // when one of the URL plugins (browser-plugin / navigation-plugin) is\n // installed. The value is already DECODED — feeding it through\n // `decodeURIComponent` again would throw on a bare `%`.\n const ctxHash = (route.context as { url?: { hash?: string } } | undefined)\n ?.url?.hash;\n\n if (ctxHash !== undefined) {\n if (anchorEnabled && ctxHash.length > 0) {\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(ctxHash);\n\n if (element) {\n element.scrollIntoView({ behavior });\n\n return;\n }\n }\n\n writePos(0);\n\n return;\n }\n\n // Fallback path: no URL plugin, read the DOM. `location.hash` is\n // percent-encoded; ids in the DOM are the raw string, so decode for the\n // match. Fall back to the raw slice if the hash contains a malformed\n // escape sequence (decodeURIComponent throws on those).\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView({ behavior });\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n let unserializableWarned = false;\n\n // `keyOf` defers to `canonicalJson` which calls `JSON.stringify`. Two\n // realistic inputs blow up the serializer and would otherwise crash the\n // subscribe callback (taking scroll-restore offline for the whole session):\n // - `BigInt` params → `TypeError: Do not know how to serialize a BigInt`\n // - cyclic params (reactive proxies, DOM-ref back-pointers) → stack\n // overflow.\n // The defensive wrapper drops capture/restore for that specific navigation\n // and warns once per provider — the rest of the cache stays usable.\n const safeKeyOf = (state: State): string | null => {\n try {\n return keyOf(state);\n } catch {\n if (!unserializableWarned) {\n unserializableWarned = true;\n console.error(\n `[real-router] scroll-restore: route \"${state.name}\" has params that cannot be canonicalized (e.g. BigInt or cyclic structure). Scroll position will not be captured or restored for this route.`,\n );\n }\n\n return null;\n }\n };\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n const prevKey = safeKeyOf(previousRoute);\n\n if (prevKey !== null) {\n putPos(prevKey, readPos());\n }\n }\n\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\") {\n scrollToHashOrTop(route);\n\n return;\n }\n\n // Restore branches (reload, back/traverse) MUST be evaluated before the\n // replace-skip below. Since #657 lifted `replace` into TransitionMeta, a\n // history TRAVERSAL (back/forward) under navigation-plugin carries\n // `transition.replace === true` — a traversal reuses an existing history\n // entry, which is replace-shaped at the history level. If the replace-skip\n // ran first it would swallow every back/forward navigation and restore\n // would never fire (the Scenario 6 e2e regression). Genuine in-place\n // replaces (`router.navigate({ replace: true })`, navigateToNotFound) are\n // not traversals and fall through to the skip below.\n //\n // Both arms of each check are required: `transition.reload` only fires for\n // programmatic `router.navigate({reload:true})`. F5 under navigation-plugin\n // primes `nav.navigationType === \"reload\"` via #531 getActivationType but\n // leaves opts.reload undefined, so dropping the plugin arm would regress F5\n // scroll-restore. Browser-plugin's F5 is not covered (no priming, out of\n // scope).\n if (route.transition.reload || nav?.navigationType === \"reload\") {\n const key = safeKeyOf(route);\n\n restorePos(key === null ? 0 : (loadStore()[key] ?? 0));\n\n return;\n }\n\n if (nav?.direction === \"back\" || nav?.navigationType === \"traverse\") {\n const key = safeKeyOf(route);\n\n restorePos(key === null ? 0 : (loadStore()[key] ?? 0));\n\n return;\n }\n\n // Genuine in-place replace (not a traversal) — leave scroll untouched.\n if (route.transition.replace || nav?.navigationType === \"replace\") {\n return;\n }\n\n scrollToHashOrTop(route);\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n const key = safeKeyOf(current);\n\n if (key !== null) {\n putPos(key, readPos());\n }\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\n/**\n * Internal cache-key builder for scroll-position storage.\n *\n * **Exported for testing only — not part of the public API** (intentionally\n * excluded from `index.ts` barrel). Adapter property tests import it via\n * the direct path to lock the `(name, canonicalJson(params))` key shape\n * as a regression guard (§8b H20 / audit-2026-05-16 #S3). A change to\n * key format would silently lose scroll positions across an upgrade —\n * the test set is the contract.\n *\n * ## Identity-based memoization (audit-2026-05-17 §8b #2)\n *\n * `State` objects emitted by core are frozen per-navigation: their\n * `name` / `params` are immutable for the lifetime of the snapshot, and\n * any change produces a new `State` reference. A `WeakMap<State, string>`\n * therefore safely caches the canonicalised key by identity — repeat\n * `keyOf(state)` calls on the same snapshot (typical on\n * back/forward/traverse where the same prior `State` is re-emitted)\n * skip the recursive `canonicalJson` pass entirely.\n *\n * The cache key is the `State` reference, so entries auto-release when\n * the snapshot is GC'd — no eviction needed.\n */\nconst KEY_CACHE = new WeakMap<State, string>();\n\nexport function keyOf(state: State): string {\n const cached = KEY_CACHE.get(state);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const key = `${state.name}:${canonicalJson(state.params)}`;\n\n KEY_CACHE.set(state, key);\n\n return key;\n}\n\n/**\n * Stable JSON serializer with sorted object keys.\n *\n * **Exported for testing only — not part of the public API** (intentionally\n * excluded from `index.ts` barrel). Adapter property tests import it via\n * the direct path to lock the key-order-insensitive property\n * (`canonicalJson({a:1,b:2}) === canonicalJson({b:2,a:1})`).\n *\n * ## Divergence from `@real-router/sources/canonicalJson` — by design\n *\n * Two independent implementations live in the monorepo:\n *\n * - **`shared/dom-utils/scroll-restore.canonicalJson`** (this file) — scroll\n * cache key builder. Uses `localeCompare` and a plain-object accumulator;\n * tolerates `__proto__`-keyed inputs only insofar as `JSON.stringify`'s\n * replacer happens to sort them; relies on `JSON.stringify`'s native cycle\n * detector. Designed to be cheap on the navigation hot path. The\n * surrounding [[safeKeyOf]] wrapper catches the two crash inputs (`BigInt`,\n * cyclic) and skips the offending capture/restore.\n *\n * - **`@real-router/sources/canonicalJson`** — sources cache key builder.\n * Uses byte-order compare (`< / >`) for locale-independence, a\n * `Object.create(null)` accumulator to prevent prototype pollution, and a\n * bespoke path-based cycle detector (the native one cannot see the cloned\n * graph). Throws eagerly on `Map`/`Set`/`RegExp`/cycles — the caller falls\n * back to a non-cached source.\n *\n * **They are intentionally NOT interchangeable.** Aligning them would either\n * regress scroll-restore performance (byte-order + recursive clone is heavier\n * per call) or weaken the sources cache (locale dependence breaks\n * deterministic cache keys across machines). No cross-package equivalence\n * test exists or should be added; the relationship is \"different invariants,\n * different costs, different consumers.\" Audit-2 / audit-2026-05-17 §2\n * documents the choice.\n */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n // audit-2026-05-17 §5 MEDIUM (Sprint A.3) — function/Symbol marker.\n // `JSON.stringify` silently drops function and symbol values from\n // object output. Two routes that differ ONLY in a function/Symbol\n // value would canonicalize to the same string → silent scroll-cache\n // key collision (positions clobber each other). Replacing the value\n // with a sentinel string breaks the collision while keeping the\n // canonical form deterministic. The sentinels are intentionally\n // ASCII-only and lexically distinct from valid JSON-stringified\n // values; consumers will see `\"<fn>\"` / `\"<sym>\"` if they ever\n // round-trip the cache key, signalling the substitution clearly.\n if (typeof val === \"function\") {\n return \"<fn>\";\n }\n if (typeof val === \"symbol\") {\n return \"<sym>\";\n }\n\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n // Null-prototype accumulator: a plain `{}` would interpret\n // `sorted[\"__proto__\"] = x` as a prototype assignment (silently dropped\n // from JSON.stringify output AND a prototype-pollution vector). Mirrors\n // the same guard in `@real-router/sources/canonicalJson`. The two\n // implementations are still intentionally divergent (see the doc-block\n // on [[canonicalJson]] above), but prototype-safety is non-negotiable\n // on both. Lock-test: scrollRestoreKey.properties.ts Invariant 11.\n const sorted = Object.create(null) as Record<string, unknown>;\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val).sort((left: string, right: string) =>\n left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import { getTransitionSource } from \"@real-router/sources\";\n\nimport type { NavigationOptions, Router } from \"@real-router/core\";\n\n/**\n * Router-coordinated scroll spy (#575).\n *\n * On `IntersectionObserver` notifications the utility picks the topmost\n * visible anchor inside the configured scroll container and emits a forced\n * same-route transition with `{ hash, replace: true, force: true, hashChange:\n * true }` through `router.navigate(...)`. The URL plugin\n * (`@real-router/browser-plugin` or `@real-router/navigation-plugin`) updates\n * `state.context.url.hash` so sibling hash-aware `<Link hash>` re-highlights\n * via the standard `createActiveRouteSource` pipeline.\n *\n * **Anti-flicker gates** (RFC §5.2):\n * 1. `getTransitionSource(router).getSnapshot().isTransitioning` — skip emits\n * while a transition is in-flight (re-entrant lock).\n * 2. `coolingDown` — set on a user-driven hash transition (e.g. `<Link hash>`\n * click + smooth `scrollIntoView`). Cleared on `scrollend` or after a\n * 500ms safety timeout. Spy's own emits are excluded via the synchronous\n * `selfEmitting` flag — required so the spy doesn't rate-limit itself.\n *\n * **Self-healing** (RFC §7.3): if the initial URL contains a hash without a\n * matching `id` (e.g. `/page#nonexistent`), the first IO event emitted right\n * after observe()-ing picks the topmost real anchor and corrects the URL.\n *\n * **Hash-only transition pipeline cost** (RFC §5.3): for same-route same-\n * params hash-only navigations, `getTransitionPath` returns empty\n * `toDeactivate` / `toActivate` arrays, so `runGuards` is a no-op. The only\n * work is the URL plugin's `onTransitionSuccess` write and the\n * `getTransitionSource` flip — cheap.\n *\n * **Architecture**: decomposed into 4 private subsystem closure factories\n * (`createUrlPluginDetector`, `createCooldown`, `createDebouncer`,\n * `createObserverPair`). The main `createScrollSpy` wires them together\n * around the shared `silenced` / `destroyed` / `selfEmitting` flags and the\n * `flush()` emit logic. Each subsystem owns its state + cleanup; `destroy()`\n * delegates to each. See section banners below.\n *\n * @returns A `ScrollSpy` handle whose `destroy()` is idempotent.\n */\nexport interface ScrollSpyOptions {\n /**\n * CSS selector for anchor candidates. Empty string `\"\"` or `undefined`\n * disables the spy (returns a NOOP handle). Common values:\n * `\"[id]\"`, `\"[id]:is(h1,h2,h3)\"`, `\"section[id]\"`.\n */\n selector: string;\n\n /**\n * `IntersectionObserver` `rootMargin`. Default\n * `\"-20% 0px -60% 0px\"` — an anchor is considered \"active\" once it crosses\n * into the top 20 % of the viewport (or scroll container).\n */\n rootMargin?: string | undefined;\n\n /**\n * Lazy getter for the scrollable container. Resolved on every event.\n * `null` (or missing getter) falls back to the window viewport\n * (`root: null` on the `IntersectionObserver`).\n */\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\nexport interface ScrollSpy {\n /** Tear down observer + listeners. Idempotent. */\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ScrollSpy = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n// Hardcoded internals (RFC §5.1 — promote only with evidence).\nconst RAF_DEBOUNCE_MS = 150;\nconst MUTATION_DEBOUNCE_MS = 250;\nconst COOLDOWN_TIMEOUT_MS = 500;\nconst DEFAULT_ROOT_MARGIN = \"-20% 0px -60% 0px\";\n\n// Local extension type — browser-plugin / navigation-plugin augment\n// `NavigationOptions` with `hash` and `hashChange`, but `shared/dom-utils`\n// is plugin-agnostic and cannot rely on the augmentation. Mirrors the\n// `HashAwareNavigationOptions` pattern in `link-utils.ts`.\ntype HashAwareNavigationOptions = NavigationOptions & {\n hash?: string;\n hashChange?: boolean;\n};\n\ninterface UrlContextSlice {\n hash?: string;\n hashChanged?: boolean;\n}\n\nconst getUrlContext = (state: {\n context?: unknown;\n}): UrlContextSlice | undefined =>\n (state.context as { url?: UrlContextSlice } | undefined)?.url;\n\n// =============================================================================\n// Picker — pure, no state. RFC §5.2 selection rule.\n// =============================================================================\n\n// Pick the anchor closest to the active zone top in viewport coordinates.\n// `entry.rootBounds.top` already reflects `rootMargin` (per W3C IO spec\n// §3.3) — for `rootMargin: \"-20% 0px -60% 0px\"` it returns 20% of root\n// height, for `\"-50% 0px -50% 0px\"` it returns the center, etc. Distance\n// = boundingClientRect.top − zoneTop in viewport pixels: positive = anchor\n// below zone top (just entered), negative = anchor above zone top (body\n// crossing zone from above). We prefer smallest non-negative; fall back to\n// least-negative when no entry has crossed yet.\n// Falls back to zoneTop = 0 when rootBounds is null (cross-origin roots,\n// unit tests). Single pass — handles `Iterable` so flushes can pass\n// `Map.values()` directly without realising the array.\nconst pickTopmost = (\n entries: Iterable<IntersectionObserverEntry>,\n): IntersectionObserverEntry | null => {\n let bestPositive: IntersectionObserverEntry | null = null;\n let bestPositiveDist = Number.POSITIVE_INFINITY;\n let bestNegative: IntersectionObserverEntry | null = null;\n let bestNegativeDist = Number.NEGATIVE_INFINITY;\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n continue;\n }\n\n const zoneTop = entry.rootBounds?.top ?? 0;\n const distance = entry.boundingClientRect.top - zoneTop;\n\n if (distance >= 0) {\n if (distance < bestPositiveDist) {\n bestPositive = entry;\n bestPositiveDist = distance;\n }\n } else if (distance > bestNegativeDist) {\n bestNegative = entry;\n bestNegativeDist = distance;\n }\n }\n\n return bestPositive ?? bestNegative;\n};\n\n// =============================================================================\n// Subsystem: URL plugin detector (RFC §5.5)\n// Calls `onMissing` if `state.context` is published but `url` key is missing\n// (i.e. no URL plugin installed). Either synchronous on start, or deferred\n// via a one-shot `router.subscribe` if the router has not started yet.\n// `silenced` flag itself lives in main scope — detector signals via callback\n// (per Oracle Q1 — `silenced` has multiple unrelated triggers; main scope\n// owns the kill switch).\n// =============================================================================\n\ninterface UrlPluginDetector {\n destroy: () => void;\n}\n\nconst createUrlPluginDetector = (\n router: Router,\n onMissing: () => void,\n): UrlPluginDetector => {\n let detectionUnsub: (() => void) | null = null;\n\n const verify = (state: { context?: unknown }): void => {\n const context = state.context as\n | (Record<string, unknown> & { url?: unknown })\n | undefined;\n\n if (context && context.url === undefined) {\n console.warn(\n \"[real-router] scroll-spy: state.context.url is not claimed. \" +\n \"Spy requires browser-plugin or navigation-plugin. Disabling.\",\n );\n onMissing();\n }\n };\n\n const peekState = router.getState();\n\n if (peekState) {\n verify(peekState);\n } else {\n // Re-entry guard: `router.subscribe` MAY invoke the callback synchronously\n // from inside `.subscribe(...)` before the function returns. In that case\n // `detectionUnsub` is still `null` when the callback fires. Without this\n // boolean, a hypothetical multi-fire would double-warn.\n let detectionConsumed = false;\n\n detectionUnsub = router.subscribe(({ route }) => {\n if (detectionConsumed) {\n return;\n }\n\n detectionConsumed = true;\n verify(route);\n\n detectionUnsub?.();\n detectionUnsub = null;\n });\n }\n\n return {\n destroy(): void {\n detectionUnsub?.();\n detectionUnsub = null;\n },\n };\n};\n\n// =============================================================================\n// Subsystem: Cooldown gate (RFC §5.2 — anti-flicker for smooth scrollIntoView)\n// Set on user-driven `<Link hash>` click → smooth scroll. Cleared on\n// `scrollend` (Baseline 2026) or 500ms safety timeout (older Safari).\n// =============================================================================\n\ninterface Cooldown {\n readonly active: boolean;\n start: () => void;\n destroy: () => void;\n}\n\nconst createCooldown = (getContainer: () => HTMLElement | null): Cooldown => {\n let active = false;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let listenerContainer: HTMLElement | null = null;\n let listener: (() => void) | null = null;\n\n const clear = (): void => {\n if (timeout !== null) {\n clearTimeout(timeout);\n timeout = null;\n }\n\n if (listener) {\n const target: EventTarget = listenerContainer ?? globalThis;\n\n target.removeEventListener(\"scrollend\", listener);\n }\n\n listener = null;\n listenerContainer = null;\n active = false;\n };\n\n return {\n get active(): boolean {\n return active;\n },\n start(): void {\n // Reset rather than stack timers if cooldown is already active.\n clear();\n\n active = true;\n\n const lift = (): void => {\n clear();\n };\n\n listener = lift;\n listenerContainer = getContainer();\n\n const target: EventTarget = listenerContainer ?? globalThis;\n\n target.addEventListener(\"scrollend\", lift, { once: true });\n\n timeout = setTimeout(lift, COOLDOWN_TIMEOUT_MS);\n },\n destroy(): void {\n clear();\n },\n };\n};\n\n// =============================================================================\n// Subsystem: rAF + trailing debounce (RFC §5.1)\n// Coalesces a burst of IO events into ≤ 1 callback per debounce window.\n// rAF reduces N setTimeout creations to 1 per animation frame; the trailing\n// 150ms setTimeout waits for the IO stream to quiesce.\n// =============================================================================\n\ninterface Debouncer {\n schedule: () => void;\n destroy: () => void;\n}\n\nconst createDebouncer = (\n callback: () => void,\n trailingMs: number,\n): Debouncer => {\n let raf: number | null = null;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return {\n schedule(): void {\n if (raf !== null) {\n return;\n }\n\n raf = requestAnimationFrame(() => {\n raf = null;\n\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => {\n timeout = null;\n callback();\n }, trailingMs);\n });\n },\n destroy(): void {\n if (raf !== null) {\n cancelAnimationFrame(raf);\n raf = null;\n }\n\n if (timeout !== null) {\n clearTimeout(timeout);\n timeout = null;\n }\n },\n };\n};\n\n// =============================================================================\n// Subsystem: Observer pair (IntersectionObserver + MutationObserver)\n// IO + MO genuinely form one subsystem — both write/read `observed` set and\n// `pending` map, and reconcile flow couples them. Per Oracle Q10, splitting\n// would force cross-subsystem references that re-introduce the wiring\n// problem we're trying to solve.\n//\n// Exposes `pending` directly (per Oracle Q4: hiding behind `consume()` adds\n// boilerplate without isolating the shared mutable state — observers write\n// from IO callbacks while main scope reads in `flush()`).\n// =============================================================================\n\ninterface ObserverPair {\n readonly pending: Map<Element, IntersectionObserverEntry>;\n destroy: () => void;\n}\n\nconst createObserverPair = (\n selector: string,\n rootMargin: string,\n getContainer: () => HTMLElement | null,\n onIntersection: () => void,\n onInvalidSelector: () => void,\n isStopped: () => boolean,\n): ObserverPair => {\n const observed = new Set<Element>();\n // Latest IO entry per target — accumulated across batches. IO delivers\n // entries only for targets whose intersection state CHANGED (W3C IO\n // §3.2.1), so a fast scroll that lands two callbacks inside the same\n // debounce window must merge by target, not overwrite. Entries are\n // dropped from the map when their target leaves the DOM (see `reconcile`)\n // and on `destroy()`.\n const pending = new Map<Element, IntersectionObserverEntry>();\n\n let duplicateIdWarned = false;\n let mutationTimer: ReturnType<typeof setTimeout> | null = null;\n\n const handleIntersection: IntersectionObserverCallback = (entries) => {\n // Defensive: IO callback may fire AFTER `destroy()` if a queued event\n // was already scheduled by the browser before `disconnect()`. Cheap\n // belt-and-suspenders.\n if (isStopped()) {\n return;\n }\n\n for (const entry of entries) {\n pending.set(entry.target, entry);\n }\n\n onIntersection();\n };\n\n const io = new IntersectionObserver(handleIntersection, {\n root: getContainer(),\n rootMargin,\n threshold: 0,\n });\n\n const observeMatches = (): void => {\n const scope = getContainer() ?? document;\n let candidates: NodeListOf<Element>;\n\n try {\n candidates = scope.querySelectorAll(selector);\n } catch {\n onInvalidSelector();\n\n return;\n }\n\n const seenIds = new Set<string>();\n\n for (const element of candidates) {\n // Detect duplicate ids once (RFC §7.7). The DOM permits duplicate ids\n // even though it is a markup bug; the spy keeps working but picks the\n // first one deterministically via the topmost-visible rule.\n const id = (element as HTMLElement).id;\n\n if (id && !duplicateIdWarned) {\n if (seenIds.has(id)) {\n duplicateIdWarned = true;\n\n console.warn(\n `[real-router] scroll-spy: duplicate id \"${id}\" observed. ` +\n \"Selection picks the topmost visible match deterministically.\",\n );\n }\n\n seenIds.add(id);\n }\n\n if (observed.has(element)) {\n continue;\n }\n\n io.observe(element);\n observed.add(element);\n }\n };\n\n const reconcile = (): void => {\n // Drop observed elements that left the DOM. Avoids observer holding\n // strong refs to detached nodes. Also drop their accumulated entry so\n // stale \"was intersecting\" state for a removed node cannot be picked\n // by `pickTopmost` after the node is gone.\n for (const element of observed) {\n if (!element.isConnected) {\n io.unobserve(element);\n observed.delete(element);\n pending.delete(element);\n }\n }\n\n observeMatches();\n };\n\n observeMatches();\n\n // MutationObserver targets the scroll container (or document.body for\n // window viewport). `childList: true, subtree: true` catches structural\n // changes; `attributes: true, attributeFilter: [\"id\"]` catches anchor\n // id renames (typical for client-rendered docs).\n const mutationTarget = getContainer() ?? document.body;\n\n const mo = new MutationObserver(() => {\n if (mutationTimer !== null) {\n clearTimeout(mutationTimer);\n }\n\n mutationTimer = setTimeout(() => {\n mutationTimer = null;\n reconcile();\n }, MUTATION_DEBOUNCE_MS);\n });\n\n mo.observe(mutationTarget, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"id\"],\n });\n\n return {\n pending,\n destroy(): void {\n io.disconnect();\n mo.disconnect();\n\n if (mutationTimer !== null) {\n clearTimeout(mutationTimer);\n mutationTimer = null;\n }\n\n observed.clear();\n pending.clear();\n },\n };\n};\n\n// =============================================================================\n// Main: compositional wiring\n// =============================================================================\n\nexport function createScrollSpy(\n router: Router,\n options: ScrollSpyOptions,\n): ScrollSpy {\n // SSR guard (RFC §7.5) — return early without warnings.\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n // Feature-detect IntersectionObserver — no polyfill ships (RFC §4).\n if (typeof IntersectionObserver === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const { selector } = options;\n\n // Empty selector → disabled. Documented opt-out for conditional enabling\n // (RFC §5.4 `scrollSpy={{ selector: enable ? \"[id]\" : \"\" }}`).\n if (!selector) {\n return NOOP_INSTANCE;\n }\n\n const rootMargin = options.rootMargin ?? DEFAULT_ROOT_MARGIN;\n const getContainer = options.scrollContainer;\n const resolveContainer = (): HTMLElement | null => getContainer?.() ?? null;\n\n // Shared lifecycle flags (Oracle Q1 — `silenced` has multiple unrelated\n // triggers; Oracle Q3 — `selfEmitting` synchronously bracketed around\n // `router.navigate()` cannot cleanly extract). Kept in main scope.\n let destroyed = false;\n let silenced = false;\n let selfEmitting = false;\n\n const isStopped = (): boolean => silenced || destroyed;\n\n // Symmetric late-binding (Oracle Q2): declare `flush` as nullable, wire\n // debouncer + observers, then assign the real implementation. Reads as\n // intentional wiring rather than accidental closure capture ordering.\n // The `flush?.()` call below safely no-ops if a callback somehow fires\n // before assignment (impossible in practice — IO/debounce are async).\n let flush: (() => void) | null = null;\n\n const transitionSource = getTransitionSource(router);\n\n const detector = createUrlPluginDetector(router, () => {\n silenced = true;\n });\n\n const cooldown = createCooldown(resolveContainer);\n\n const debouncer = createDebouncer(() => {\n flush?.();\n }, RAF_DEBOUNCE_MS);\n\n const observers = createObserverPair(\n selector,\n rootMargin,\n resolveContainer,\n () => {\n debouncer.schedule();\n },\n () => {\n if (silenced) {\n return;\n }\n\n silenced = true;\n\n console.warn(\n `[real-router] scroll-spy: invalid selector \"${selector}\". Disabling.`,\n );\n },\n isStopped,\n );\n\n flush = (): void => {\n if (destroyed || silenced) {\n observers.pending.clear();\n\n return;\n }\n\n // Gate-skipped flushes keep `pendingEntries` populated — the merged\n // state is still the best-known snapshot, and the next non-gated flush\n // consumes it. Clearing under a gate would re-introduce the overwrite\n // bug for any anchor whose intersection state did not change during\n // the gate window.\n if (transitionSource.getSnapshot().isTransitioning) {\n return;\n }\n\n if (cooldown.active) {\n return;\n }\n\n if (observers.pending.size === 0) {\n return;\n }\n\n // Successful flush consumes the merged snapshot. We clear so that the\n // next debounce window starts fresh; an anchor that is still\n // intersecting will only stay observable if IO emits another event for\n // it (which it does whenever the anchor's intersection state actually\n // changes). Skipping the clear here would leak state from one user-\n // perceived \"scroll stop\" into the next.\n const picked = pickTopmost(observers.pending.values());\n\n observers.pending.clear();\n\n if (!picked) {\n // No anchor visible / above zone — preserve last hash (RFC §10 #5).\n return;\n }\n\n const newHash = (picked.target as HTMLElement).id;\n\n if (!newHash) {\n return;\n }\n\n const state = router.getState();\n\n if (!state) {\n return;\n }\n\n const currentHash = getUrlContext(state)?.hash ?? \"\";\n\n if (newHash === currentHash) {\n return;\n }\n\n // Emit the same-route same-params hash-only transition. URL plugin\n // writes `state.context.url.hash = newHash` + `hashChanged = true` in\n // its `onTransitionSuccess` claim.\n const opts: HashAwareNavigationOptions = {\n hash: newHash,\n replace: true,\n force: true,\n hashChange: true,\n };\n\n // Self-emit guard (RFC §5.2): set synchronously around our own\n // `router.navigate()` so the `router.subscribe` callback skips the\n // cooldown setup for spy-emitted transitions — otherwise spy would\n // rate-limit itself to ≤ 2 emits/s, contradicting the ≤ 10/s benchmark\n // target. Test coupling (Q8): preserve exact `.catch(noop).finally(reset)`\n // chain — migrating to `try/finally` over `await router.navigate(...)`\n // changes microtask schedule and breaks \"spy continues after rejection\".\n selfEmitting = true;\n router\n .navigate(state.name, state.params, opts)\n .catch(() => {\n // Fire-and-forget — suppress expected rejections (concurrent\n // navigate, router stopped, etc.) consistent with `<Link>` adapter\n // patterns.\n })\n .finally(() => {\n selfEmitting = false;\n });\n };\n\n // Cooldown setup on user-driven hash transitions. Spy's own emits are\n // distinguished via the synchronous `selfEmitting` flag (see `flush`).\n const unsubscribeRouter = router.subscribe(({ route }) => {\n if (selfEmitting) {\n return;\n }\n\n if (getUrlContext(route)?.hashChanged) {\n cooldown.start();\n }\n });\n\n return {\n destroy(): void {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n\n // Unsubscribe FIRST to prevent late-arriving router transition\n // callback from calling `cooldown.start()` on a half-destroyed\n // instance. Without this ordering, a transition with `hashChanged:\n // true` firing between subsystem teardown and `unsubscribeRouter()`\n // would re-install a 500ms timer that survives `destroy()`. Verified\n // via Oracle review (Q5/Q7).\n unsubscribeRouter();\n\n observers.destroy();\n debouncer.destroy();\n cooldown.destroy();\n detector.destroy();\n },\n };\n}\n","import type { Router } from \"@real-router/core\";\n\nexport interface ViewTransitions {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ViewTransitions = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createViewTransitions(router: Router): ViewTransitions {\n if (\n typeof document === \"undefined\" ||\n typeof document.startViewTransition !== \"function\"\n ) {\n return NOOP_INSTANCE;\n }\n\n let closeVT: (() => void) | null = null;\n let currentVT: { skipTransition?: () => void } | null = null;\n // Tracks whether TRANSITION_SUCCESS fired for the current leave. Used to\n // distinguish \"benign cleanup abort\" (router's async path aborts its own\n // controller in a finally block after successful navigation) from \"real\n // cancellation\" (concurrent navigate, guard rejection, dispose).\n let successFired = false;\n\n const resolveAndClear = (): void => {\n closeVT?.();\n closeVT = null;\n };\n\n const offLeave = router.subscribeLeave(({ signal }) => {\n // Reentrant abort: signal already aborted when we're called. Open no VT\n // — router will fall through to TRANSITION_CANCELLED via isCurrentNav()\n // after leave resolves. addEventListener(\"abort\", ...) does not re-fire\n // for past events, so skipping startViewTransition is the safe path.\n if (signal.aborted) {\n return;\n }\n\n successFired = false;\n resolveAndClear();\n\n // Return a Promise so the router awaits until the browser invokes\n // updateCallback. This ensures old DOM snapshot is captured BEFORE the\n // router commits the new state — giving correct exit→state→entry\n // ordering (vs fire-and-forget, where URL changes before VT captures).\n return new Promise<void>((resolveLeave) => {\n // Capture the resolver synchronously BEFORE startViewTransition() is\n // called. The browser invokes updateCallback in a later task, but\n // router.subscribe (TRANSITION_SUCCESS) can fire before that. If we\n // captured `resolve` inside the callback, subscribe would see closeVT\n // still null and skip resolving — the deferred would hang for 4s\n // until the VT API aborts with TimeoutError.\n const deferred = new Promise<void>((resolve) => {\n closeVT = resolve;\n });\n\n signal.addEventListener(\n \"abort\",\n () => {\n if (successFired) {\n // Router's async path (#finishAsyncNavigation) aborts its own\n // controller in a finally block AFTER completeTransition (and\n // thus AFTER subscribe fired). This is cleanup, not\n // cancellation — VT is progressing normally, do nothing.\n return;\n }\n\n // Real cancellation (concurrent navigate, dispose). Resolve the\n // deferred so updateCallback can complete, skip the VT so no\n // stale animation leaks, and unblock the router if the abort\n // fires before updateCallback was invoked.\n resolveAndClear();\n currentVT?.skipTransition?.();\n resolveLeave();\n },\n { once: true },\n );\n\n try {\n currentVT = document.startViewTransition(() => {\n // Resolving here unblocks the router at the moment the browser\n // enters updateCallback — by spec, old DOM snapshot is captured\n // before this callback runs. Router now proceeds through\n // activation guards and setState; the VT animation waits on\n // `deferred`, which is resolved from router.subscribe after a\n // task-queue tick (see NOTE on setTimeout below).\n resolveLeave();\n\n return deferred;\n });\n } catch {\n // Defensive: spec says startViewTransition doesn't throw under\n // normal conditions, but Chromium has had edge cases (detached\n // document, extension interference). Clean up and unblock router.\n resolveAndClear();\n resolveLeave();\n }\n });\n });\n\n const offSuccess = router.subscribe(() => {\n const resolver = closeVT;\n\n successFired = true;\n closeVT = null;\n\n if (resolver === null) {\n currentVT = null;\n } else {\n // CRITICAL: CANNOT use requestAnimationFrame here. When the router\n // takes the async path (leave returned a Promise), subscribe fires\n // AFTER the browser has already transitioned VT into the\n // \"update-callback-called\" phase. In that phase Chromium sets\n // rendering suppression to true, which ALSO blocks rAF callbacks.\n // rAF would never fire → deferred never resolves → browser aborts\n // vt.ready with TimeoutError after 4s (observed in Chromium).\n //\n // setTimeout runs on the task queue independent of the rendering\n // pipeline, so it fires regardless of suppression. React's scheduler\n // uses MessageChannel tasks, which are queued before our setTimeout,\n // so the new DOM is committed by the time our callback runs.\n setTimeout(() => {\n resolver();\n currentVT = null;\n }, 0);\n }\n });\n\n return {\n destroy: () => {\n offLeave();\n offSuccess();\n currentVT?.skipTransition?.();\n currentVT = null;\n resolveAndClear();\n },\n };\n}\n","import type {\n NavigationOptions,\n Params,\n Router,\n State,\n} from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\n// Matches a single percent-escape triple (`%` + two hex digits). Used as\n// the \"already-encoded\" probe in `encodeFragmentInline` below — see the\n// idempotency rationale there.\nconst PERCENT_ESCAPE_PROBE = /%[\\dA-Fa-f]{2}/;\n\n/**\n * RFC 3986 fragment encoding: preserve sub-delims (`&`, `=`, `?`, `:`),\n * encode space, `%`, control chars, non-ASCII via encodeURI; defensively\n * escape `#` (encodeURI does not). Mirrors `encodeHashFragment` in\n * `shared/browser-env/url-context.ts` — duplicated here because the\n * shared/dom-utils symlink graph does not reach shared/browser-env.\n *\n * **Idempotency for pre-encoded input (audit-2026-05-17 §5 MEDIUM E.1).**\n * The doc-comment on `<Link hash>` says the value is a \"decoded fragment\n * without leading #\". But realistic consumers copy hashes out of\n * `location.hash` (which is percent-encoded) and pass them back, so the\n * naive `encodeURI(\"%20\")` would double-encode into `\"%2520\"` and break\n * anchor lookup. We detect a percent-escape triple in the input and, if\n * present, decode + re-encode for idempotency. Malformed `%XX` (e.g.\n * `\"%2\"` or `\"%ZZ\"`) makes `decodeURIComponent` throw — in that case we\n * fall through to plain `encodeURI`, which never throws.\n */\nfunction encodeFragmentInline(decoded: string): string {\n if (PERCENT_ESCAPE_PROBE.test(decoded)) {\n try {\n const roundtrip = decodeURIComponent(decoded);\n\n return encodeURI(roundtrip).replaceAll(\"#\", \"%23\");\n } catch {\n // Malformed `%XX` — fall through to the plain encoding path.\n // encodeURI does not throw on malformed escapes; it treats the\n // `%` as a literal and percent-encodes it (`%2` → `%252`).\n }\n }\n\n return encodeURI(decoded).replaceAll(\"#\", \"%23\");\n}\n\ntype BuildUrlFn = (\n name: string,\n params: Params,\n options?: { hash?: string },\n) => string | undefined;\n\n/**\n * Builds an href for a `<Link>` element.\n *\n * - Prefers the URL plugin's `buildUrl` (browser-plugin, navigation-plugin,\n * hash-plugin) when present.\n * - Falls back to `router.buildPath` for runtimes without a URL plugin\n * (memory-plugin, console UIs, NativeScript). In that fallback the hash\n * is appended manually so the rendered href is still correct.\n * - The optional 4th argument is an options object so the contract stays\n * extensible. The `hash` option is a decoded fragment without leading \"#\";\n * `<Link hash=\"#section\">` is accepted defensively (leading \"#\" stripped).\n * Frozen API: previous 3-arg call sites continue to work unchanged.\n */\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n options?: { hash?: string },\n): string | undefined {\n try {\n const rawHash = options?.hash;\n let normHash: string | undefined;\n\n if (rawHash !== undefined) {\n normHash = rawHash.startsWith(\"#\") ? rawHash.slice(1) : rawHash;\n }\n\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(\n routeName,\n routeParams,\n normHash === undefined ? undefined : { hash: normHash },\n );\n\n // Accept only non-empty strings. The BuildUrlFn type contract is\n // `string | undefined`, but defensive against:\n // - `\"\"` (empty string) → would render `<a href=\"\">`, which resolves\n // to the current page URL → silent self-navigation on click.\n // - `null` (type-contract violation) → would render `<a href={null}>`,\n // stringified to `\"null\"` in some renderers.\n // Either case falls through to the `router.buildPath` fallback below.\n if (typeof url === \"string\" && url.length > 0) {\n return url;\n }\n }\n\n const path = router.buildPath(routeName, routeParams);\n\n // Symmetric to the buildUrl guard above (#S1 audit, Invariant 12).\n // `router.buildPath` is typed `string`, but defends against:\n // - `\"\"` (empty string) — would render `<a href=\"\">`, which resolves\n // to the current page URL → silent self-navigation on click.\n // - non-string type-contract violations from custom path-matchers.\n // Both yield `undefined` (renderer drops the attribute) with a warning.\n if (typeof path !== \"string\" || path.length === 0) {\n console.error(\n `[real-router] Route \"${routeName}\" yielded an empty path. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n\n return normHash ? `${path}#${encodeFragmentInline(normHash)}` : path;\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\n/**\n * `<Link>` click-handler navigation helper (#532).\n *\n * Wraps `router.navigate(name, params, opts)` with same-route different-hash\n * detection: when the consumer clicks a hash-bearing Link that targets the\n * current route with the same params but a different fragment, core's\n * SAME_STATES check would otherwise reject the navigation. The helper adds\n * `force: true` and `hashChange: true` automatically — subscribers can then\n * disambiguate via `state.context.url.hashChanged`.\n *\n * For pure programmatic same-route hash-only navigation, callers are\n * documented to pass `{ force: true }` themselves; the auto-bypass here is\n * a UX convenience for `<Link hash>` that all 6 framework adapters share.\n */\n/**\n * Local extended-options type. Adapters that depend only on `@real-router/core`\n * (without a URL plugin) do not see the `NavigationOptions` augmentation that\n * declares `hash` / `hashChange`. Casting to this widened type inside the\n * helper keeps shared/dom-utils self-contained — adapters do not need to\n * augment NavigationOptions themselves to consume `<Link hash>`.\n */\ntype HashAwareNavigationOptions = NavigationOptions & {\n hash?: string;\n hashChange?: boolean;\n};\n\nexport function navigateWithHash(\n router: Router,\n routeName: string,\n routeParams: Params,\n hash: string | undefined,\n extraOptions?: NavigationOptions,\n): Promise<State> {\n const opts: HashAwareNavigationOptions = { ...extraOptions };\n\n if (hash !== undefined) {\n opts.hash = hash;\n }\n\n const current = router.getState();\n\n if (\n current?.name === routeName &&\n shallowEqual(current.params, routeParams)\n ) {\n const currentHash =\n (current.context as { url?: { hash?: string } } | undefined)?.url?.hash ??\n \"\";\n const newHash = hash ?? currentHash;\n\n if (currentHash !== newHash) {\n opts.force = true;\n opts.hashChange = true;\n }\n }\n\n return router.navigate(routeName, routeParams, opts);\n}\n\n// Match-any-whitespace regex shared across calls. RegExp literals at\n// call-site recompile in some engines; lifting it avoids that microcost\n// for the slow-path branch.\nconst WHITESPACE_PROBE = /\\s/;\nconst WHITESPACE_SPLIT = /\\S+/g;\n\nfunction parseTokens(value: string | undefined): string[] {\n if (!value) {\n return [];\n }\n\n // Hot-path fast-path (audit-2026-05-17 §8b #1): >99% of active-class\n // inputs at `<Link>` emit are single-token strings like `\"active\"` or\n // `\"is-current\"` — no whitespace, no leading/trailing pad. Skip the\n // regex match and Array result allocation: a literal `[value]` works\n // because the slow-path `match(/\\S+/g)` would return exactly `[value]`\n // for the same input. PBT lock: linkUtils.properties.ts Invariant 13.\n if (!WHITESPACE_PROBE.test(value)) {\n return [value];\n }\n\n return value.match(WHITESPACE_SPLIT) ?? [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\n/**\n * One-level structural equality using `Object.is` per key.\n *\n * **String-keyed properties only (Mini-sprint E.3 — audit-5 §4.2 #3).**\n * Implementation walks `Object.keys()` which by spec returns only\n * enumerable own STRING keys. Symbol-keyed properties — created via\n * `obj[Symbol(\"brand\")] = value` or `{ [Symbol(...)]: value }` — are\n * NOT compared. Two records that differ only in a Symbol-keyed value\n * will compare as equal.\n *\n * This is intentional: route params and Link options are documented as\n * string-keyed primitives (string | number | boolean) — Symbol-keyed\n * metadata (e.g. brand markers, private state) doesn't belong in a\n * cache-key comparison. Switching to `Reflect.ownKeys()` would extend\n * the contract to symbols at the cost of one extra allocation per call\n * (Reflect.ownKeys composes string-keys + symbol-keys arrays). If a\n * consumer relies on symbol-keyed metadata for navigation\n * disambiguation, they should encode it into a string key instead.\n *\n * Mirrors React's `shallowEqual` (packages/shared/shallowEqual.js) in\n * both the string-keys-only semantics and the `hasOwnProperty` guard\n * below.\n */\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n // hasOwnProperty guard: without it, a key missing in `next` reads as\n // `undefined` and falsely matches `prev[key] === undefined`. Same shape\n // as React's shallowEqual (packages/shared/shallowEqual.js).\n if (\n !Object.prototype.hasOwnProperty.call(next, key) ||\n !Object.is(prevRecord[key], nextRecord[key])\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n\n // Cross-realm safety (audit-2026-05-17 §5 HIGH #4):\n // `instanceof HTMLAnchorElement` compares against the constructor from\n // the CURRENT realm. An element created in a different window (iframe\n // contentDocument, micro-frontend, embedded widget) fails the check\n // even when it IS a real anchor — the helper would then inject\n // role=\"link\" + tabindex=\"0\" on top of native anchor semantics,\n // breaking screen reader output (\"link link\") and focus order.\n //\n // tagName is realm-agnostic and is uppercase for HTML-namespaced\n // elements in any document. SVG `<a>` has lowercase tagName plus a\n // different prototype (SVGAElement) — skipping it here is wrong by\n // accident: SVG anchors don't have keyboard activation semantics the\n // helper would add. But they also don't reach this helper in\n // practice (router Link components emit HTML anchors). Lock the\n // uppercase compare to keep the contract narrow.\n const tag = element.tagName;\n\n if (tag === \"A\" || tag === \"BUTTON\") {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { ApplicationRef, DestroyRef, inject } from \"@angular/core\";\n\nimport {\n createScrollRestoration,\n createScrollSpy,\n createViewTransitions,\n} from \"../dom-utils\";\nimport { ROUTER } from \"../providers\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"../dom-utils\";\n\n/**\n * Shared installation helpers for `provideRealRouter` and\n * `provideRealRouterFactory`. Must be called inside the body of a\n * `provideEnvironmentInitializer(() => { ... })` callback so the active\n * injection context resolves `ROUTER`, `ApplicationRef`, and `DestroyRef`.\n *\n * Closes review-2026-05-10 §8.1 MED — eliminates duplicate wiring between\n * `providers.ts` and `providersFactory.ts` (high drift risk noted in the\n * audit: the comment blocks were identical down to the punctuation).\n */\n\nexport function installScrollRestoration(\n options: ScrollRestorationOptions,\n): void {\n const router = inject(ROUTER);\n const sr = createScrollRestoration(router, options);\n\n inject(DestroyRef).onDestroy(() => {\n sr.destroy();\n });\n}\n\nexport function installScrollSpy(options: ScrollSpyOptions): void {\n const router = inject(ROUTER);\n const spy = createScrollSpy(router, options);\n\n inject(DestroyRef).onDestroy(() => {\n spy.destroy();\n });\n}\n\nexport function installViewTransitions(): void {\n const router = inject(ROUTER);\n\n // Feature-detect `document.startViewTransition` once at install time. The\n // `appRef.tick()` listener exists ONLY to feed Angular's zoneless CD into\n // the VT utility's `setTimeout(0)`-driven snapshot capture (see comment\n // below). When `startViewTransition` is unavailable (Firefox as of 2026-04,\n // SSR, older browsers), `createViewTransitions` short-circuits to its\n // frozen NOOP_INSTANCE — no leave subscriber registered, no\n // `setTimeout(0)` invariant to satisfy. Installing the per-navigation\n // tick listener anyway would force a synchronous CD pass on every\n // navigation with zero benefit, doubling CD work in zoneless apps.\n // Closes review-2026-05-10 §8.2 MED (view-transitions hot path).\n const vtAvailable =\n typeof document !== \"undefined\" &&\n typeof document.startViewTransition === \"function\";\n\n let offTick: (() => void) | undefined;\n\n if (vtAvailable) {\n // Force synchronous change detection on every transition success BEFORE\n // the VT utility resolves its deferred. The utility uses `setTimeout(0)`\n // to release the new-snapshot capture, which is load-bearing because\n // Chromium blocks rAF callbacks while VT sits in the\n // `update-callback-called` phase. Angular's zoneless CD is rAF-driven by\n // default — without this synchronous tick the new DOM is not committed\n // when the browser captures the new snapshot, so old and new snapshots\n // end up identical and animations finish in ~0 ms with no visible work\n // (the inner-route `products.list ↔ products.detail` morph in the\n // example app was the canary).\n //\n // Subscribers fire in registration order; this one runs BEFORE\n // `createViewTransitions` registers its own subscriber, guaranteeing CD\n // completes first.\n const appRef = inject(ApplicationRef);\n\n offTick = router.subscribe(() => {\n appRef.tick();\n });\n }\n\n const vt = createViewTransitions(router);\n\n inject(DestroyRef).onDestroy(() => {\n offTick?.();\n vt.destroy();\n });\n}\n","import { signal, type Signal, inject, DestroyRef } from \"@angular/core\";\n\nimport type { RouterSource } from \"@real-router/sources\";\n\n/** Must be called within an injection context (constructor, field initializer, runInInjectionContext). */\nexport function sourceToSignal<T>(source: RouterSource<T>): Signal<T> {\n const sig = signal<T>(source.getSnapshot());\n const destroyRef = inject(DestroyRef);\n\n const unsubscribe = source.subscribe(() => {\n sig.set(source.getSnapshot());\n });\n\n destroyRef.onDestroy(() => {\n // `try/finally` guarantees `source.destroy()` runs even if `unsubscribe`\n // throws. Cached sources from `@real-router/sources` keep `destroy()` as\n // a no-op (so they survive multi-consumer teardown), but non-cached\n // sources rely on this call to release their router subscription —\n // skipping it on an unsubscribe throw would leak the listener.\n try {\n unsubscribe();\n } finally {\n source.destroy();\n }\n });\n\n return sig.asReadonly();\n}\n","import {\n InjectionToken,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport { getNavigator, type Router, type Navigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport {\n installScrollRestoration,\n installScrollSpy,\n installViewTransitions,\n} from \"./internal/install\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\nexport const ROUTER = new InjectionToken<Router>(\"ROUTER\");\n\nexport const NAVIGATOR = new InjectionToken<Navigator>(\"NAVIGATOR\");\n\nexport const ROUTE = new InjectionToken<RouteSignals>(\"ROUTE\");\n\nexport interface RealRouterOptions {\n scrollRestoration?: ScrollRestorationOptions;\n scrollSpy?: ScrollSpyOptions;\n viewTransitions?: boolean;\n}\n\nexport function provideRealRouter(\n router: Router,\n options?: RealRouterOptions,\n): EnvironmentProviders {\n const navigator = getNavigator(router);\n\n // `Parameters<typeof makeEnvironmentProviders>[0]` is the actual union\n // `(Provider | EnvironmentProviders | EnvironmentProviders[])[]` —\n // `provideEnvironmentInitializer()` returns `EnvironmentProviders`, so the\n // narrower `Provider[]` would force a cast at every push (review §8a — the\n // proposed Provider[] swap was retracted after discovering this).\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: ROUTER, useValue: router },\n { provide: NAVIGATOR, useValue: navigator },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => ({\n routeState: sourceToSignal(createRouteSource(router)),\n navigator,\n }),\n },\n ];\n\n if (options?.scrollRestoration) {\n const scrollOpts = options.scrollRestoration;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollRestoration(scrollOpts);\n }),\n );\n }\n\n if (options?.scrollSpy && options.scrollSpy.selector !== \"\") {\n const spyOpts = options.scrollSpy;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollSpy(spyOpts);\n }),\n );\n }\n\n if (options?.viewTransitions === true) {\n providers.push(provideEnvironmentInitializer(installViewTransitions));\n }\n\n return makeEnvironmentProviders(providers);\n}\n","import {\n DestroyRef,\n REQUEST,\n TransferState,\n inject,\n makeEnvironmentProviders,\n makeStateKey,\n provideAppInitializer,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport {\n getNavigator,\n type DefaultDependencies,\n type PluginFactory,\n type Router,\n} from \"@real-router/core\";\nimport { cloneRouter } from \"@real-router/core/api\";\nimport { hydrateRouter, serializeRouterState } from \"@real-router/core/utils\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport {\n installScrollRestoration,\n installScrollSpy,\n installViewTransitions,\n} from \"./internal/install\";\nimport { NAVIGATOR, ROUTE, ROUTER } from \"./providers\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\n/**\n * `TransferState` key carrying the SSR-resolved router state from server to\n * client as an XSS-safe JSON string (produced by `serializeRouterState`).\n * Populated server-side by the `provideAppInitializer` callback after\n * `router.start()` resolves; consumed client-side after hydration. Mirrors the\n * `<script>window.__SSR_STATE__ = …</script>` pattern used by every other\n * adapter — Angular's idiomatic transport is `TransferState` (#599).\n *\n * Stored as `string`: `serializeRouterState(state)` already produces JSON;\n * `hydrateRouter(router, json)` accepts a JSON string and parses it once\n * internally. Storing the parsed object would force a double round-trip\n * (TransferState wraps every value in JSON for transport).\n *\n * Internal implementation detail. Not re-exported.\n */\nconst ROUTER_STATE_KEY = makeStateKey<string>(\"@real-router/angular:ssrState\");\n\n/**\n * Factory function for deriving per-request dependencies from an SSR `Request`.\n *\n * - **Server:** receives the real `Request` exposed via Angular's `REQUEST` token.\n * - **SSG:** receives a mocked `Request` injected via `platformProviders`.\n * - **Client:** receives `null` — derive deps from `document.cookie` etc.\n *\n * The returned object becomes the second argument to\n * `cloneRouter(baseRouter, deps)`. Returning `undefined` clones the router with\n * no extra deps (cloneRouter accepts the optional 2nd argument).\n */\nexport type RequestDepsFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> = (request: Request | null) => TDeps | undefined;\n\n/**\n * Function form for conditional plugins (different sets server vs client).\n *\n * Use this when the plugin set must differ — typically because some plugins\n * (e.g. `browser-plugin`, `navigation-plugin`, `hash-plugin`) touch\n * `window.history` / `window.location` and cannot run on the server.\n */\nexport type RequestPluginsFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> = (request: Request | null) => readonly PluginFactory<TDeps>[];\n\nexport interface RealRouterFactoryOptions<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> {\n /**\n * Base router instance — created once at app bootstrap (typically inside\n * `app.config.ts` module scope). Each request clones this router via\n * `cloneRouter(baseRouter, deps?.(request))`, producing an isolated\n * router with its own state, plugins, and subscriptions.\n *\n * **Important:** the `baseRouter` MUST NOT be started ahead of time —\n * `provideAppInitializer` is responsible for calling `router.start(url)`\n * inside the per-request DI scope.\n */\n baseRouter: Router<TDeps>;\n\n /**\n * Plugins applied to every per-request router clone.\n *\n * **Static form** — same plugins on both sides:\n * ```ts\n * plugins: [ssrDataPluginFactory(loaders)]\n * ```\n *\n * **Function form** — conditional client vs server (recommended when any\n * browser-only plugin is involved):\n * ```ts\n * plugins: (request) => request\n * ? [ssrDataPluginFactory(loaders)]\n * : [browserPluginFactory(), ssrDataPluginFactory(loaders)],\n * ```\n *\n * Function form is required if the plugin list contains\n * `browser-plugin`, `navigation-plugin`, or `hash-plugin` — those plugins\n * read `window.history` / `window.location` and crash on the server.\n */\n plugins?: readonly PluginFactory<TDeps>[] | RequestPluginsFactory<TDeps>;\n\n /**\n * Derive request-scoped deps (e.g. `currentUser` from cookies). The result\n * is passed to `cloneRouter(baseRouter, deps)` and merged with any deps\n * already registered on the base router.\n *\n * Receives `request: Request | null`:\n * - non-null on server (real `Request` from `@angular/ssr` runtime)\n * - non-null on SSG (mocked `Request` via `platformProviders`)\n * - null on client (derive deps externally — e.g. parse `document.cookie`)\n */\n deps?: RequestDepsFactory<TDeps>;\n\n /** Optional scroll restoration — same semantics as `provideRealRouter`. */\n scrollRestoration?: ScrollRestorationOptions;\n\n /** Optional scroll spy — same semantics as `provideRealRouter`. */\n scrollSpy?: ScrollSpyOptions;\n\n /** Optional view transitions — same semantics as `provideRealRouter`. */\n viewTransitions?: boolean;\n}\n\n/**\n * `provideRealRouterFactory` — environment providers for SSR / SSG scenarios.\n *\n * Unlike `provideRealRouter(router)` (single instance via `useValue`), this\n * factory uses `useFactory` to produce a per-request router clone:\n *\n * 1. Reads Angular's `REQUEST` token (`{ optional: true }`).\n * 2. Calls `cloneRouter(baseRouter, deps?.(request))` to create a request-scoped clone.\n * 3. Applies plugins (`plugins` array or `plugins(request)` factory).\n * 4. Registers `provideAppInitializer` that calls `await router.start(url)`.\n * 5. Schedules `router.dispose()` via `DestroyRef.onDestroy` — the request\n * Injector is destroyed after the response is sent, releasing all\n * subscriptions and plugins.\n *\n * Use cases:\n * - Angular SSR with `@angular/ssr` (`outputMode: \"server\"`).\n * - SSG build-time render via `renderApplication` + `platformProviders` `REQUEST` mock.\n * - Multi-tenant request-scoped routing.\n *\n * Existing single-instance scenarios (SPA, SSG client after hydration) continue\n * to use `provideRealRouter(router)` — both APIs ship in parallel.\n *\n * @param options - Factory configuration — see `RealRouterFactoryOptions`.\n * @returns `EnvironmentProviders` to spread into `ApplicationConfig.providers`.\n */\nexport function provideRealRouterFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n>(options: RealRouterFactoryOptions<TDeps>): EnvironmentProviders {\n const {\n baseRouter,\n plugins,\n deps,\n scrollRestoration,\n scrollSpy,\n viewTransitions,\n } = options;\n\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n {\n provide: ROUTER,\n useFactory: (): Router => {\n const request = inject(REQUEST, { optional: true });\n const requestDeps = deps?.(request);\n const router = cloneRouter(baseRouter, requestDeps);\n\n const pluginList =\n typeof plugins === \"function\" ? plugins(request) : plugins;\n\n if (pluginList && pluginList.length > 0) {\n // Variadic — `usePlugin` accepts `(PluginFactory<D> | false | null | undefined)[]`.\n router.usePlugin(...pluginList);\n }\n\n // Per-request cleanup. The application Injector is destroyed:\n // - On server: after `writeResponseToNodeResponse` finishes the response\n // (request scope ends).\n // - On client: at `ApplicationRef.destroy` (rare in SPA, common in TestBed).\n // - In SSG build: after each `renderApplication` resolves.\n inject(DestroyRef).onDestroy(() => {\n router.dispose();\n });\n\n return router as unknown as Router;\n },\n },\n {\n provide: NAVIGATOR,\n useFactory: () => getNavigator(inject(ROUTER)),\n },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => {\n const router = inject(ROUTER);\n\n return {\n routeState: sourceToSignal(createRouteSource(router)),\n navigator: inject(NAVIGATOR),\n };\n },\n },\n // Async bootstrap — runs before the first component renders. Three\n // branches based on TransferState population:\n //\n // 1. **Client after hydration** — server populated TransferState with\n // the SSR-resolved router state. Consume it via `hydrateRouter`,\n // which deposits the parsed state into the one-shot\n // `RouterInternals.hydrationState` scratchpad before invoking\n // `router.start(state.path)`. SSR loader plugins\n // (`@real-router/ssr-data-plugin`, `@real-router/rsc-server-plugin`)\n // read the scratchpad and skip the loader on first paint — parity\n // with the other 5 adapters that consume `<script>__SSR_STATE__</script>` (#596, #599).\n //\n // 2. **Server / SSG** — TransferState empty; run the regular\n // `router.start(path)`. After it resolves, write the serialized\n // state back into TransferState so the matching client run lands\n // in branch 1. Angular's `TransferState` infrastructure\n // (provided by `provideClientHydration()`) carries this blob to\n // the client as a `<script id=\"ng-state\">` payload.\n //\n // 3. **Pure CSR** — TransferState empty (never populated by a server\n // pass), and `inject(REQUEST, { optional: true })` returns null.\n // Falls into the same `router.start(path)` branch as server-side\n // but skips the TransferState write (no client to hand off to).\n //\n // Errors propagate (Option A from RFC §10): the bootstrap fails and the\n // server returns 500. Custom error pages should be wired via\n // `RouterErrorBoundary` on subsequent renders.\n provideAppInitializer(async () => {\n const router = inject(ROUTER);\n const request = inject(REQUEST, { optional: true });\n const transferState = inject(TransferState);\n\n const ssrJson = transferState.get(ROUTER_STATE_KEY, null);\n\n if (ssrJson !== null) {\n // Branch 1: client after hydration — reuse server-resolved state.\n await hydrateRouter(router, ssrJson);\n // One-shot semantic, parity with `delete window.__SSR_STATE__`.\n transferState.remove(ROUTER_STATE_KEY);\n\n return;\n }\n\n // Branches 2 & 3: regular start.\n // Browser-plugin's `start` interceptor (when registered) wraps this call\n // with location-derived path. We always pass an explicit string — the\n // interceptor uses the explicit value because `next(path ?? location)`\n // short-circuits when `path` is non-nullish.\n const path = deriveStartPath(request);\n const state = await router.start(path);\n\n if (request !== null) {\n // Branch 2: running inside `@angular/ssr`'s request handler — write\n // serialized state to TransferState so the matching client run can\n // skip the loader on first paint.\n transferState.set(ROUTER_STATE_KEY, serializeRouterState(state));\n }\n }),\n ];\n\n if (scrollRestoration) {\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollRestoration(scrollRestoration);\n }),\n );\n }\n\n if (scrollSpy && scrollSpy.selector !== \"\") {\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollSpy(scrollSpy);\n }),\n );\n }\n\n if (viewTransitions === true) {\n providers.push(provideEnvironmentInitializer(installViewTransitions));\n }\n\n return makeEnvironmentProviders(providers);\n}\n\n/**\n * Derive the path passed to `router.start(path)`:\n * - Server / SSG: `request.url` → pathname + search.\n * - Client: `window.location` if available.\n * - Fallback: `\"/\"` (only reachable in synthetic non-browser non-SSR setups).\n */\nfunction deriveStartPath(request: Request | null): string {\n if (request) {\n const url = new URL(request.url);\n\n return url.pathname + url.search;\n }\n\n if (typeof globalThis.window !== \"undefined\") {\n return globalThis.location.pathname + globalThis.location.search;\n }\n\n return \"/\";\n}\n","import { inject } from \"@angular/core\";\n\nimport type { InjectionToken } from \"@angular/core\";\n\nexport function injectOrThrow<T>(token: InjectionToken<T>, fnName: string): T {\n const value = inject(token, { optional: true });\n\n // Explicit null / undefined check — falsy guard would misfire on\n // legitimately falsy values (`0`, `\"\"`, `false`) if the token were ever\n // typed for primitives. Today all our tokens hold object instances, but\n // pinning the check keeps the function safe for future typing changes.\n if (value === null || value === undefined) {\n throw new Error(\n `${fnName} must be used within a provideRealRouter context`,\n );\n }\n\n return value;\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTER } from \"../providers\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport function injectRouter(): Router {\n assertInInjectionContext(injectRouter);\n\n return injectOrThrow(ROUTER, \"injectRouter\");\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { NAVIGATOR } from \"../providers\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport function injectNavigator(): Navigator {\n assertInInjectionContext(injectNavigator);\n\n return injectOrThrow(NAVIGATOR, \"injectNavigator\");\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTE } from \"../providers\";\n\nimport type { RouteSignals } from \"../types\";\nimport type { Signal } from \"@angular/core\";\nimport type { Params, State } from \"@real-router/core\";\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\ntype NonNullRouteSignals<P extends Params> = Omit<\n RouteSignals<P>,\n \"routeState\"\n> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n};\n\nexport function injectRoute<\n P extends Params = Params,\n>(): NonNullRouteSignals<P> {\n assertInInjectionContext(injectRoute);\n\n const signals = injectOrThrow(ROUTE, \"injectRoute\") as RouteSignals<P>;\n\n // Read the snapshot once: the signal is reactive, but the throw-guard\n // and any future use of the snapshot within this call should observe the\n // SAME value to avoid races.\n const snapshot = signals.routeState();\n\n if (!snapshot.route) {\n throw new Error(\n \"injectRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?\",\n );\n }\n\n return signals as NonNullRouteSignals<P>;\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteSignals } from \"../types\";\n\nexport function injectRouteNode(nodeName: string): RouteSignals {\n assertInInjectionContext(injectRouteNode);\n\n const router = injectRouter();\n const navigator = getNavigator(router);\n const source = createRouteNodeSource(router, nodeName);\n const routeState = sourceToSignal(source);\n\n return { routeState, navigator };\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\nexport function injectRouteUtils(): RouteUtils {\n assertInInjectionContext(injectRouteUtils);\n\n const router = injectRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getTransitionSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function injectRouterTransition(): Signal<RouterTransitionSnapshot> {\n assertInInjectionContext(injectRouterTransition);\n\n const router = injectRouter();\n const source = getTransitionSource(router);\n\n return sourceToSignal(source);\n}\n","import type { ActiveRouteSourceOptions } from \"@real-router/sources\";\n\n/**\n * Build the `options` literal for `createActiveRouteSource` while honoring\n * `exactOptionalPropertyTypes` — the type forbids passing `{ hash: undefined }`\n * literally (#532), so callers must conditionally include the `hash` key only\n * when a value was provided.\n *\n * Used by `RealLink`, `RealLinkActive`, and `injectIsActiveRoute` — extracted\n * from three identical ternaries (review-2026-05-16 §8a LOW).\n */\nexport function buildActiveRouteOptions(\n strict: boolean,\n ignoreQueryParams: boolean,\n hash: string | undefined,\n): ActiveRouteSourceOptions {\n return hash === undefined\n ? { strict, ignoreQueryParams }\n : { strict, ignoreQueryParams, hash };\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { Params } from \"@real-router/core\";\n\nexport function injectIsActiveRoute(\n routeName: string,\n params?: Params,\n options?: { strict?: boolean; ignoreQueryParams?: boolean; hash?: string },\n): Signal<boolean> {\n assertInInjectionContext(injectIsActiveRoute);\n\n const router = injectRouter();\n const source = createActiveRouteSource(\n router,\n routeName,\n params,\n buildActiveRouteOptions(\n options?.strict ?? false,\n options?.ignoreQueryParams ?? true,\n options?.hash,\n ),\n );\n\n return sourceToSignal(source);\n}\n","import { DestroyRef, assertInInjectionContext, inject } from \"@angular/core\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteExitContext {\n /** The route being left. */\n route: State;\n /** The route being navigated to. */\n nextRoute: State;\n /**\n * AbortSignal that fires when this navigation is superseded by a later\n * one (rapid clicks). Already filtered: when the handler runs,\n * `signal.aborted` is guaranteed to be `false`. Use\n * `signal.addEventListener(\"abort\", cleanup, { once: true })` for\n * cleanup that must run on cancellation.\n */\n signal: AbortSignal;\n}\n\nexport interface UseRouteExitOptions {\n /**\n * Skip the handler when `route.name === nextRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`.\n */\n skipSameRoute?: boolean;\n}\n\nexport type RouteExitHandler = (\n context: RouteExitContext,\n) => void | Promise<void>;\n\n/**\n * Subscribe to the router's leave-window with the universal guards baked\n * in. Wraps `router.subscribeLeave` so consumers don't repeat the same\n * boilerplate every time:\n *\n * - **Reentrant abort pre-check**: if `signal.aborted` is already `true`\n * when the handler would run (rapid navigation superseded a slower\n * one), the handler is skipped entirely.\n * - **Same-route skip**: by default, `route.name === nextRoute.name`\n * short-circuits the handler — query-only navigations skip the work.\n * Opt out with `skipSameRoute: false`.\n *\n * Cleanup is bound to the injection context's `DestroyRef`. Must be\n * called within an injection context (constructor, field initializer,\n * or `runInInjectionContext`).\n *\n * If the handler returns a Promise, the router blocks on it. If the\n * Promise resolves, navigation proceeds. If it rejects, the router emits\n * `TRANSITION_CANCELLED`.\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method\n * (`this.onExit.bind(this)` or an arrow-property) — its identity is\n * stable across change detection. To vary behavior over time, read\n * signals **inside** the handler body — do not rely on swapping the\n * handler reference.\n *\n * @example Animation\n * ```ts\n * \\@Component({ ... })\n * class FadeOutComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteExit(async ({ signal }) => {\n * const el = this.el.nativeElement;\n * el.classList.add(\"fade-out\");\n * const cleanup = () => el.classList.remove(\"fade-out\");\n * signal.addEventListener(\"abort\", cleanup, { once: true });\n * try {\n * el.getBoundingClientRect();\n * await Promise.allSettled(el.getAnimations().map((a) => a.finished));\n * } finally {\n * cleanup();\n * }\n * });\n * }\n * }\n * ```\n *\n * @example Auto-save form draft\n * ```ts\n * injectRouteExit(async ({ signal }) => {\n * if (this.formState.dirty) {\n * await this.api.saveDraft(this.formState, { signal });\n * }\n * });\n * ```\n */\nexport function injectRouteExit(\n handler: RouteExitHandler,\n options?: UseRouteExitOptions,\n): void {\n assertInInjectionContext(injectRouteExit);\n\n const router = injectRouter();\n const destroyRef = inject(DestroyRef);\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n const off = router.subscribeLeave(({ route, nextRoute, signal }) => {\n if (skipSameRoute && route.name === nextRoute.name) {\n return;\n }\n\n if (signal.aborted) {\n return;\n }\n\n return handler({ route, nextRoute, signal });\n });\n\n destroyRef.onDestroy(off);\n}\n","import { assertInInjectionContext, effect } from \"@angular/core\";\n\nimport { injectRoute } from \"./injectRoute\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteEnterContext {\n /** The route that was just activated. */\n route: State;\n /** The route that was active immediately before this navigation. */\n previousRoute: State;\n}\n\nexport type RouteEnterHandler = (context: RouteEnterContext) => void;\n\nexport interface UseRouteEnterOptions {\n /**\n * Skip the handler when `route.name === previousRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`. Symmetric with `injectRouteExit`'s same-name option.\n */\n skipSameRoute?: boolean;\n}\n\n/**\n * Fire `handler` once when the component is created as a result of a\n * navigation. Mirror of `injectRouteExit` for the entry side.\n *\n * What this function covers that an ad-hoc `effect()` + `injectRoute()`\n * doesn't:\n *\n * - **Skip-initial**: handler is skipped when there is no\n * `route.transition.from` (i.e. first-load mount). Most consumers\n * want to fire side effects only on real navigations, not on\n * hydration.\n * - **Same-route skip** (default): handler is skipped when\n * `route.transition.from === route.name`. Sort/filter/query-only\n * navigations re-run the effect (because the `route` reference\n * changes), but they are not \"entries\" in the animation / analytics\n * sense. Opt out with `skipSameRoute: false`.\n * - **Mount-time `route` / `previousRoute` snapshot**: handler receives\n * the values that were live at the moment of effect activation.\n *\n * Effect cleanup is wired through the injection context's `DestroyRef`\n * (Angular's `effect()` ties into the active context automatically).\n * Must be called within an injection context (constructor, field\n * initializer, or `runInInjectionContext`).\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method —\n * its identity is stable across change detection. To vary behavior\n * over time, read signals **inside** the handler body.\n *\n * @example Direction-aware entry animation\n * ```ts\n * \\@Component({ ... })\n * class PageComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteEnter(({ route }) => {\n * const direction = route.context.browser?.direction;\n * this.el.nativeElement.classList.add(\n * direction === \"back\" ? \"slide-from-left\" : \"slide-from-right\",\n * );\n * });\n * }\n * }\n * ```\n *\n * @example Analytics page-enter event (skip-initial built-in)\n * ```ts\n * injectRouteEnter(({ route, previousRoute }) => {\n * analytics.track(\"page_enter\", {\n * route: route.name,\n * from: previousRoute.name,\n * });\n * });\n * ```\n */\nexport function injectRouteEnter(\n handler: RouteEnterHandler,\n options?: UseRouteEnterOptions,\n): void {\n assertInInjectionContext(injectRouteEnter);\n\n const { routeState } = injectRoute();\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n effect(() => {\n const { route, previousRoute } = routeState();\n\n // Early-exit guards, top-down:\n //\n // - **Skip-initial**: `state.transition.from` is undefined only\n // for the very first state committed by `router.start()`.\n // - **Skip-same-route**: query-only navigations have\n // `transition.from === route.name`. Opt-out via\n // `skipSameRoute: false`.\n if (!route.transition.from) {\n return;\n }\n if (skipSameRoute && route.transition.from === route.name) {\n return;\n }\n // `previousRoute` is guaranteed populated whenever `route.transition.from`\n // is set — core writes them together. The dead-code throw-guard that used\n // to live here (review §8a LOW) is removed; the narrowing below is the\n // type-safe equivalent and avoids the no-non-null-assertion lint.\n if (!previousRoute) {\n return;\n }\n\n handler({ route, previousRoute });\n });\n}\n","import { Directive, TemplateRef, inject, input } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeMatch]\" })\nexport class RouteMatch {\n readonly routeMatch = input.required<string>();\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeNotFound]\" })\nexport class RouteNotFound {\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeSelf]\" })\nexport class RouteSelf {\n readonly templateRef = inject(TemplateRef);\n}\n","import type { RouterSource } from \"@real-router/sources\";\n\n/**\n * Subscribe a `RouterSource<T>` to a write-callback and return a cleanup\n * function. The shape is the per-effect-run pattern that `RealLink`,\n * `RealLinkActive`, and `RouteView` all share inside their constructor\n * `effect(...)` (review-2026-05-16 §8a MEDIUM — identical 8-line block\n * repeated in 3 directives):\n *\n * 1. Read initial snapshot and apply it via `onSnapshot(snap)`.\n * 2. Subscribe — every subsequent emission calls `onSnapshot(snap)` again.\n * 3. Return a cleanup that unsubscribes and destroys the source. For\n * cached factories from `@real-router/sources` (`createActiveRouteSource`,\n * `createRouteNodeSource`, `getTransitionSource`, `getErrorSource`,\n * `createDismissableError`) `destroy()` is a no-op on the shared\n * wrapper, so this helper is safe to invoke from rapid effect re-runs\n * under signal-input changes.\n *\n * Callers pass the result to `onCleanup(...)` from Angular's `effect()`.\n *\n * @example\n * ```ts\n * effect((onCleanup) => {\n * const source = createActiveRouteSource(router, routeName(), params());\n * onCleanup(\n * subscribeSourceToSignal(source, (snap) => {\n * this.isActive.set(snap);\n * this.updateDom();\n * }),\n * );\n * });\n * ```\n */\nexport function subscribeSourceToSignal<T>(\n source: RouterSource<T>,\n onSnapshot: (snapshot: T) => void,\n): () => void {\n onSnapshot(source.getSnapshot());\n\n const unsub = source.subscribe(() => {\n onSnapshot(source.getSnapshot());\n });\n\n return () => {\n unsub();\n source.destroy();\n };\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n Component,\n computed,\n contentChildren,\n effect,\n input,\n signal,\n type TemplateRef,\n} from \"@angular/core\";\nimport { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { RouteMatch } from \"../directives/RouteMatch\";\nimport { RouteNotFound } from \"../directives/RouteNotFound\";\nimport { RouteSelf } from \"../directives/RouteSelf\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nconst EMPTY_SNAPSHOT: RouteSnapshot = {\n route: undefined,\n previousRoute: undefined,\n};\n\n@Component({\n selector: \"route-view\",\n template: `\n @if (activeTemplate()) {\n <ng-container [ngTemplateOutlet]=\"activeTemplate()!\" />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouteView {\n readonly nodeName = input<string>(\"\", { alias: \"routeNode\" });\n\n readonly matches = contentChildren(RouteMatch, { descendants: true });\n readonly selfs = contentChildren(RouteSelf, { descendants: true });\n readonly notFounds = contentChildren(RouteNotFound, { descendants: true });\n\n readonly activeTemplate = computed<TemplateRef<unknown> | null>(\n () => this.matchedTemplate() ?? this.fallbackTemplate(),\n );\n\n private readonly router = injectRouter();\n private readonly routeState = signal<RouteSnapshot>(EMPTY_SNAPSHOT);\n\n private readonly matchEntries = computed(() => {\n const nodeName = this.nodeName();\n\n return this.matches().map((match) => {\n const segment = match.routeMatch();\n\n return {\n match,\n fullSegmentName: nodeName ? `${nodeName}.${segment}` : segment,\n };\n });\n });\n\n // The matched template (Match priority) is independent of the Self /\n // NotFound fallback chain. Splitting the two paths into separate computeds\n // localises re-runs: a change to `selfs()` / `notFounds()` no longer\n // re-evaluates the Match loop (review §8a LOW — RouteView activeTemplate\n // split).\n private readonly matchedTemplate = computed<TemplateRef<unknown> | null>(\n () => {\n const route = this.routeState().route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n\n for (const { match, fullSegmentName } of this.matchEntries()) {\n if (startsWithSegment(routeName, fullSegmentName)) {\n return match.templateRef;\n }\n }\n\n return null;\n },\n );\n\n // Fallback chain — only consulted when `matchedTemplate()` returned `null`.\n // Template priority: Self → NotFound. Selection rules differ on purpose:\n // - **Self uses first-wins** (`.at(0)`) for parity with React / Preact /\n // Solid / Vue, where the first matching `<Self>` token in declaration\n // order wins.\n // - **NotFound uses last-wins** (`.at(-1)`) intentionally — the fallback\n // should be the most-recently-declared template so that consumers can\n // override an inherited `<ng-template routeNotFound>` simply by\n // re-declaring it lower in the projected content.\n private readonly fallbackTemplate = computed<TemplateRef<unknown> | null>(\n () => {\n const route = this.routeState().route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n\n if (routeName === this.nodeName()) {\n const first = this.selfs().at(0);\n\n if (first) {\n return first.templateRef;\n }\n }\n\n if (routeName === UNKNOWN_ROUTE) {\n const last = this.notFounds().at(-1);\n\n if (last) {\n return last.templateRef;\n }\n }\n\n return null;\n },\n );\n\n constructor() {\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n effect((onCleanup) => {\n const source = createRouteNodeSource(this.router, this.nodeName());\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n this.routeState.set(snap);\n }),\n );\n });\n }\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport { Component, computed, effect, input, output } from \"@angular/core\";\nimport { createDismissableError } from \"@real-router/sources\";\n\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { sourceToSignal } from \"../sourceToSignal\";\n\nimport type { ErrorContext } from \"../types\";\nimport type { TemplateRef } from \"@angular/core\";\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { DismissableErrorSnapshot } from \"@real-router/sources\";\n\n@Component({\n selector: \"router-error-boundary\",\n template: `\n <ng-content />\n @if (errorContext() && errorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"errorTemplate()!\"\n [ngTemplateOutletContext]=\"errorContext()!\"\n />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouterErrorBoundary {\n readonly errorTemplate = input<TemplateRef<ErrorContext>>();\n\n readonly onError = output<{\n error: RouterError;\n toRoute: State | null;\n fromRoute: State | null;\n }>();\n\n readonly errorContext = computed<ErrorContext | null>(() => {\n const snap = this.snapshot();\n\n if (!snap.error) {\n return null;\n }\n\n return {\n $implicit: snap.error,\n resetError: snap.resetError,\n };\n });\n\n private readonly router = injectRouter();\n private readonly snapshot = sourceToSignal<DismissableErrorSnapshot>(\n createDismissableError(this.router),\n );\n\n constructor() {\n // `effect()` registers itself with the current injection context's\n // `DestroyRef` and tears down automatically when the component is\n // destroyed. The earlier manual `effectRef.destroy()` wired through\n // `inject(DestroyRef).onDestroy(...)` duplicated that built-in cleanup\n // (audit §8.1 LOW — confirmed: no behavior change without the manual\n // path).\n effect(() => {\n const snap = this.snapshot();\n\n if (snap.error) {\n this.onError.emit({\n error: snap.error,\n toRoute: snap.toRoute,\n fromRoute: snap.fromRoute,\n });\n }\n });\n }\n}\n","import { Component, inject, DestroyRef } from \"@angular/core\";\n\nimport { createRouteAnnouncer } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\n@Component({\n selector: \"navigation-announcer\",\n template: \"\",\n})\nexport class NavigationAnnouncer {\n private readonly announcer = createRouteAnnouncer(injectRouter());\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.announcer.destroy();\n });\n }\n}\n","import {\n Directive,\n ElementRef,\n computed,\n effect,\n inject,\n input,\n signal,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildHref, navigateWithHash, shouldNavigate } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { Params, NavigationOptions } from \"@real-router/core\";\n\nconst NOOP_CATCH = (): void => {};\n\n@Directive({\n selector: \"a[realLink]\",\n host: {\n \"(click)\": \"onClick($event)\",\n },\n})\nexport class RealLink {\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly routeOptions = input<NavigationOptions>({});\n readonly activeClassName = input<string>(\"active\");\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n /**\n * URL fragment (decoded form, no leading \"#\") (#532).\n * - omitted/`undefined` → preserve current fragment on same-route navigation\n * - `\"\"` → clear fragment\n * - non-empty → set fragment\n */\n readonly hash = input<string | undefined>(undefined);\n\n private readonly router = injectRouter();\n private readonly anchor = inject(ElementRef)\n .nativeElement as HTMLAnchorElement;\n private readonly isActive = signal(false);\n // `href` is computed from signal inputs only — Angular's default Object.is\n // equality already collapses repeated `string` results, so no custom\n // comparator is required (review §8b note 3 — applies after verifying that\n // `buildHref` returns a primitive).\n private readonly href = computed(() => {\n const hashValue = this.hash();\n\n return buildHref(\n this.router,\n this.routeName(),\n this.routeParams(),\n hashValue === undefined ? undefined : { hash: hashValue },\n );\n });\n private prevActiveClass = \"\";\n private prevHref: string | undefined = undefined;\n // Skip-same-value: only re-touch the DOM `class` list when the active state\n // actually flipped. Without this, every navigation that re-fires the active\n // source still issues a `classList.toggle` no-op (review §8b MEDIUM).\n private prevActive: boolean | undefined = undefined;\n\n constructor() {\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n // Reading signal inputs inside `effect()` re-creates the active-route\n // source whenever any input changes; `onCleanup` tears the previous\n // subscription down.\n effect((onCleanup) => {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n buildActiveRouteOptions(\n this.activeStrict(),\n this.ignoreQueryParams(),\n this.hash(),\n ),\n );\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n // Pure-href refresh: when the active flag did not change, only the\n // href may have moved (e.g. param-only update on a parent route).\n // Skip the classList work in that branch (review §8b MEDIUM).\n if (snap === this.prevActive) {\n this.isActive.set(snap);\n this.updateHref();\n\n return;\n }\n\n this.prevActive = snap;\n this.isActive.set(snap);\n this.updateHref();\n this.updateActiveClass();\n }),\n );\n });\n }\n\n onClick(event: MouseEvent): void {\n if (!shouldNavigate(event) || this.anchor.target === \"_blank\") {\n return;\n }\n\n event.preventDefault();\n navigateWithHash(\n this.router,\n this.routeName(),\n this.routeParams(),\n this.hash(),\n this.routeOptions(),\n ).catch(NOOP_CATCH);\n }\n\n private updateHref(): void {\n const href = this.href();\n\n if (href !== undefined && href !== this.prevHref) {\n this.anchor.setAttribute(\"href\", href);\n }\n\n this.prevHref = href;\n }\n\n private updateActiveClass(): void {\n const activeClass = this.activeClassName();\n\n if (this.prevActiveClass && this.prevActiveClass !== activeClass) {\n this.anchor.classList.remove(this.prevActiveClass);\n }\n\n if (activeClass) {\n this.anchor.classList.toggle(activeClass, this.isActive());\n }\n\n this.prevActiveClass = activeClass;\n }\n}\n","import {\n Directive,\n ElementRef,\n effect,\n inject,\n input,\n signal,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { applyLinkA11y } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { Params } from \"@real-router/core\";\n\n@Directive({ selector: \"[realLinkActive]\" })\nexport class RealLinkActive {\n readonly realLinkActive = input<string>(\"\");\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n\n private readonly router = injectRouter();\n private readonly element = inject(ElementRef).nativeElement as HTMLElement;\n private readonly isActive = signal(false);\n // Skip-same-value: only touch `classList.toggle` when the active flag\n // actually flipped. Saves one DOM write per RealLinkActive per unrelated\n // navigation (review §8b MEDIUM).\n private prevActive: boolean | undefined = undefined;\n\n constructor() {\n // One-time a11y setup — doesn't depend on signal inputs, stays in\n // constructor body. `applyLinkA11y` is idempotent so re-running would\n // be safe, but we only need it once per element.\n applyLinkA11y(this.element);\n\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n effect((onCleanup) => {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n buildActiveRouteOptions(\n this.activeStrict(),\n this.ignoreQueryParams(),\n undefined,\n ),\n );\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n if (snap === this.prevActive) {\n return;\n }\n\n this.prevActive = snap;\n this.isActive.set(snap);\n this.updateClass();\n }),\n );\n });\n }\n\n private updateClass(): void {\n const className = this.realLinkActive();\n\n if (!className) {\n return;\n }\n\n this.element.classList.toggle(className, this.isActive());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NOOP_INSTANCE"],"mappings":"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"}
1
+ {"version":3,"file":"real-router-angular.mjs","sources":["../../src/dom-utils/direction-tracker.ts","../../src/dom-utils/route-announcer.ts","../../src/dom-utils/scroll-restore.ts","../../src/dom-utils/scroll-spy.ts","../../src/dom-utils/view-transitions.ts","../../src/dom-utils/link-utils.ts","../../src/internal/install.ts","../../src/sourceToSignal.ts","../../src/providers.ts","../../src/providersFactory.ts","../../src/functions/injectOrThrow.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/internal/buildActiveRouteOptions.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/internal/subscribeSourceToSignal.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts","../../src/real-router-angular.ts"],"sourcesContent":["import type { Router } from \"@real-router/core\";\n\nexport interface DirectionTracker {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: DirectionTracker = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n/**\n * Track navigation direction (forward / back) and write it to\n * `<html data-nav-direction>` on every leave. CSS / JS readers consume\n * the attribute via `html[data-nav-direction=\"back\"]` selectors or\n * `document.documentElement.dataset.navDirection`.\n *\n * Mechanism-agnostic — works identically whether downstream UI uses CSS\n * `@keyframes`, View Transitions pseudo-elements, or library state\n * (motion's `motion.div initial={{ x: ... }}`).\n *\n * Implementation:\n * - On install, set `data-nav-direction=\"forward\"` baseline.\n * - Attach a `popstate` listener that flips an internal flag to\n * `true`. Browser back/forward navigation triggers popstate; user\n * clicks on `<Link>` / programmatic `router.navigate(...)` do not.\n * - On every `subscribeLeave`, write\n * `popstateFlag ? \"back\" : \"forward\"` and reset the flag.\n *\n * Returns `{ destroy }` to clean up the listener and clear the dataset\n * attribute.\n */\nexport function createDirectionTracker(router: Router): DirectionTracker {\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n let popstateFlag = false;\n\n document.documentElement.dataset.navDirection = \"forward\";\n\n const onPopstate = (): void => {\n popstateFlag = true;\n };\n\n // IMPORTANT — listener-ordering: `popstate` fires on `window`, which\n // has no DOM descendants, so capture phase is moot. Listeners are\n // dispatched in registration order. To beat the browser-plugin's own\n // popstate handler, this tracker must be installed **before**\n // `router.usePlugin(browserPluginFactory())` in user code. Otherwise\n // the plugin's handler runs first and synchronously fires\n // `subscribeLeave` while `popstateFlag` is still `false`.\n globalThis.addEventListener(\"popstate\", onPopstate);\n\n const offLeave = router.subscribeLeave(() => {\n document.documentElement.dataset.navDirection = popstateFlag\n ? \"back\"\n : \"forward\";\n popstateFlag = false;\n });\n\n return {\n destroy: () => {\n offLeave();\n globalThis.removeEventListener(\"popstate\", onPopstate);\n delete document.documentElement.dataset.navDirection;\n },\n };\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n // Defensive SSR / non-browser guard: in SSR (Node.js) or non-DOM\n // environments, `document` is undefined and the announcer cannot\n // attach its aria-live region. Return a frozen NOOP_INSTANCE — same\n // pattern as `createDirectionTracker`, `createScrollRestoration`, and\n // `createViewTransitions`. Without this guard, `NavigationAnnouncer`\n // component construction would throw `ReferenceError: document is not\n // defined` under `@angular/ssr` rendering, tearing down the whole SSR\n // bootstrap. Closes review-2026-05-10 §5.10 ⛔ \"NavigationAnnouncer\n // SSR mode\" MED.\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n // Defensive SSR / pre-`<body>` guard: in some environments (early\n // injection, deferred-body documents, certain SSR rehydration paths)\n // `document.body` can be null when the announcer is constructed.\n // `document.body.prepend(...)` would throw `TypeError: Cannot read\n // properties of null`, tearing down the consumer's RouterProvider /\n // NavigationAnnouncer mount. Fallback to `documentElement` keeps the\n // announcer working for SR users; visual-hidden styling means there is\n // no visible artifact regardless of mount point.\n //\n // TS dom lib types `document.body` as `HTMLElement` (non-null), but\n // runtime can return null per spec. The `as` cast narrows the type to\n // include null so the `??` short-circuit is type-safe.\n ((document.body as HTMLElement | null) ?? document.documentElement).prepend(\n element,\n );\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n try {\n const customText = getCustomText(route);\n\n // Mini-sprint E.4 (audit-5 §4.2 #4) — empty-string fallback.\n // A consumer pattern like\n // getAnnouncementText: (route) => myMap[route.name] ?? \"\"\n // returns `\"\"` for routes outside the map. The subscribe loop\n // then sees an empty text and silently no-announces — screen\n // readers stay quiet without any signal to the developer. Treat\n // a falsy custom result (`\"\"` / `null` / `undefined`) as\n // \"consumer doesn't have a name for this route\" and fall through\n // to the default resolution chain (h1 → title → route name).\n if (customText) {\n return customText;\n }\n } catch (error) {\n // A throwing consumer callback inside the router's subscribe loop\n // would tear down sibling listeners — log and fall through to the\n // built-in resolution chain so the announcer keeps working.\n console.error(\n \"[real-router] getAnnouncementText threw; falling back to default resolution.\",\n error,\n );\n }\n }\n\n const h1Text = (h1?.textContent ?? \"\").trim();\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst DEFAULT_STORAGE_KEY = \"real-router:scroll\";\n\n// Bounded retry budget for resolving a late-mounting scroll container on the\n// restore path. A per-route container (e.g. an `overflow:auto` div rendered\n// only on one route) can be committed to the DOM a few frames after the\n// navigation settles — heavier routes paint later than the subscribe's rAF.\n// ~10 frames (≈160ms at 60fps) comfortably covers a React commit of a large\n// route without being perceptible. See the doc-block on `restorePos`.\nconst RESTORE_RETRY_FRAMES = 10;\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"native\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n /**\n * Scroll behavior passed to `scrollTo({ behavior })` and\n * `scrollIntoView({ behavior })`.\n *\n * - `\"auto\"` (default) — browser-defined, usually instant.\n * - `\"instant\"` — explicit instant jump (no animation).\n * - `\"smooth\"` — animated transition. Note: smooth restore on back/traverse\n * can feel disorienting if the user expects to land at the saved position\n * immediately. Recommended for `mode: \"top\"` or anchor scroll only.\n *\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).\n */\n behavior?: ScrollBehavior | undefined;\n /**\n * sessionStorage key used to persist saved scroll positions. Default:\n * `\"real-router:scroll\"`. Override only when multiple independent\n * `RouterProvider` instances share the same document and you need to\n * isolate their scroll stores (e.g. micro-frontends, embedded widgets,\n * or testing). For a single app with one provider the default is fine.\n */\n storageKey?: string | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"native\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — `history.scrollRestoration`\n // stays at the browser default (\"auto\") so the browser handles scroll\n // restore natively. (Note: this is the OPPOSITE of `history.scrollRestoration\n // === \"manual\"` — utility's \"native\" leaves the DOM property at \"auto\" so\n // the browser is in charge.)\n if (mode === \"native\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n const behavior: ScrollBehavior = options?.behavior ?? \"auto\";\n const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;\n\n // Write-through in-memory cache: parse sessionStorage once per provider\n // mount, then mutate in-memory. Avoids a JSON.parse + JSON.stringify pair\n // on every subscribeLeave / pagehide event.\n let store: Record<string, number> | undefined;\n\n const loadStore = (): Record<string, number> => {\n if (store !== undefined) {\n return store;\n }\n\n try {\n const raw = sessionStorage.getItem(storageKey);\n\n store = raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n store = {};\n }\n\n return store;\n };\n\n const putPos = (key: string, pos: number): void => {\n try {\n const cached = loadStore();\n\n // Skip-same-value: when a route is left at the same scroll position it\n // already holds in the cache (e.g. tab-switching without scrolling),\n // both the in-memory write and the JSON.stringify + setItem pair are\n // no-ops. Eliminates redundant serialization on the navigation hot\n // path for the common \"click tabs without scrolling\" case.\n if (cached[key] === pos) {\n return;\n }\n\n cached[key] = pos;\n sessionStorage.setItem(storageKey, JSON.stringify(cached));\n } catch {\n // Ignore quota / security errors.\n }\n };\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTo({ top, left: 0, behavior });\n } else {\n globalThis.scrollTo({ top, left: 0, behavior });\n }\n };\n\n // Restore path (back / traverse / reload). Unlike `writePos`, this tolerates a\n // scroll container that both MOUNTS and LAYS OUT a few frames AFTER the\n // navigation settles.\n //\n // The capture-side `readPos` always runs against an already-mounted DOM (the\n // route being left). On restore the target route — and its container — is\n // still being committed by the view layer. The subscribe callback schedules a\n // single rAF; for a heavy route (e.g. a long virtual list) the framework's\n // commit can land AFTER that frame. Two distinct failures follow, each losing\n // the saved position (Scenario 6 e2e, reproduced under CI's slower runner):\n //\n // 1. Container not mounted yet → `getContainer()` is `null`, the scroll\n // silently falls back to `window`, which on a container-only route has\n // nothing to scroll.\n // 2. Container mounted but its content not laid out yet → `scrollHeight`\n // is still small, so a single `scrollTo({ top })` clamps short of the\n // saved position and never re-applies once layout grows.\n //\n // With no `scrollContainer` getter the target is always `window`, present\n // from the first frame — restore in a single shot (unchanged behaviour). When\n // a getter is configured we cannot tell \"this route legitimately uses window\"\n // from \"the container is still mounting\", so re-apply the scroll on every\n // frame for a bounded budget: window as a fallback while the container is\n // absent (harmless clamp on container routes), the container itself once it\n // appears. For instant restores we stop early the moment the position sticks;\n // smooth restores animate asynchronously, so they run the full budget. The\n // frame budget is the hard backstop against an unreachable target (saved\n // position taller than the restored content).\n const restorePos = (top: number): void => {\n if (!getContainer) {\n globalThis.scrollTo({ top, left: 0, behavior });\n\n return;\n }\n\n let frames = 0;\n\n const attempt = (): void => {\n if (destroyed) {\n return;\n }\n\n const element = getContainer();\n\n if (element) {\n element.scrollTo({ top, left: 0, behavior });\n\n // Instant restore landed within rounding tolerance → done; no point\n // re-applying. Smooth restore never matches synchronously, so let it\n // ride the budget.\n if (behavior !== \"smooth\" && Math.abs(element.scrollTop - top) <= 1) {\n return;\n }\n } else {\n globalThis.scrollTo({ top, left: 0, behavior });\n }\n\n if (frames >= RESTORE_RETRY_FRAMES) {\n return;\n }\n\n frames += 1;\n requestAnimationFrame(attempt);\n };\n\n attempt();\n };\n\n const scrollToHashOrTop = (route: State): void => {\n // URL plugin path (#532): `state.context.url.hash` is the source of truth\n // when one of the URL plugins (browser-plugin / navigation-plugin) is\n // installed. The value is already DECODED — feeding it through\n // `decodeURIComponent` again would throw on a bare `%`.\n const ctxHash = (route.context as { url?: { hash?: string } } | undefined)\n ?.url?.hash;\n\n if (ctxHash !== undefined) {\n if (anchorEnabled && ctxHash.length > 0) {\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(ctxHash);\n\n if (element) {\n element.scrollIntoView({ behavior });\n\n return;\n }\n }\n\n writePos(0);\n\n return;\n }\n\n // Fallback path: no URL plugin, read the DOM. `location.hash` is\n // percent-encoded; ids in the DOM are the raw string, so decode for the\n // match. Fall back to the raw slice if the hash contains a malformed\n // escape sequence (decodeURIComponent throws on those).\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView({ behavior });\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n let unserializableWarned = false;\n\n // `keyOf` defers to `canonicalJson` which calls `JSON.stringify`. Two\n // realistic inputs blow up the serializer and would otherwise crash the\n // subscribe callback (taking scroll-restore offline for the whole session):\n // - `BigInt` params → `TypeError: Do not know how to serialize a BigInt`\n // - cyclic params (reactive proxies, DOM-ref back-pointers) → stack\n // overflow.\n // The defensive wrapper drops capture/restore for that specific navigation\n // and warns once per provider — the rest of the cache stays usable.\n const safeKeyOf = (state: State): string | null => {\n try {\n return keyOf(state);\n } catch {\n if (!unserializableWarned) {\n unserializableWarned = true;\n console.error(\n `[real-router] scroll-restore: route \"${state.name}\" has params that cannot be canonicalized (e.g. BigInt or cyclic structure). Scroll position will not be captured or restored for this route.`,\n );\n }\n\n return null;\n }\n };\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n const prevKey = safeKeyOf(previousRoute);\n\n if (prevKey !== null) {\n putPos(prevKey, readPos());\n }\n }\n\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\") {\n scrollToHashOrTop(route);\n\n return;\n }\n\n // Restore branches (reload, back/traverse) MUST be evaluated before the\n // replace-skip below. Since #657 lifted `replace` into TransitionMeta, a\n // history TRAVERSAL (back/forward) under navigation-plugin carries\n // `transition.replace === true` — a traversal reuses an existing history\n // entry, which is replace-shaped at the history level. If the replace-skip\n // ran first it would swallow every back/forward navigation and restore\n // would never fire (the Scenario 6 e2e regression). Genuine in-place\n // replaces (`router.navigate({ replace: true })`, navigateToNotFound) are\n // not traversals and fall through to the skip below.\n //\n // Both arms of each check are required: `transition.reload` only fires for\n // programmatic `router.navigate({reload:true})`. F5 under navigation-plugin\n // primes `nav.navigationType === \"reload\"` via #531 getActivationType but\n // leaves opts.reload undefined, so dropping the plugin arm would regress F5\n // scroll-restore. Browser-plugin's F5 is not covered (no priming, out of\n // scope).\n if (route.transition.reload || nav?.navigationType === \"reload\") {\n const key = safeKeyOf(route);\n\n restorePos(key === null ? 0 : (loadStore()[key] ?? 0));\n\n return;\n }\n\n if (nav?.direction === \"back\" || nav?.navigationType === \"traverse\") {\n const key = safeKeyOf(route);\n\n restorePos(key === null ? 0 : (loadStore()[key] ?? 0));\n\n return;\n }\n\n // Genuine in-place replace (not a traversal) — leave scroll untouched.\n if (route.transition.replace || nav?.navigationType === \"replace\") {\n return;\n }\n\n scrollToHashOrTop(route);\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n const key = safeKeyOf(current);\n\n if (key !== null) {\n putPos(key, readPos());\n }\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\n/**\n * Internal cache-key builder for scroll-position storage.\n *\n * **Exported for testing only — not part of the public API** (intentionally\n * excluded from `index.ts` barrel). Adapter property tests import it via\n * the direct path to lock the `(name, canonicalJson(params))` key shape\n * as a regression guard (§8b H20 / audit-2026-05-16 #S3). A change to\n * key format would silently lose scroll positions across an upgrade —\n * the test set is the contract.\n *\n * ## Identity-based memoization (audit-2026-05-17 §8b #2)\n *\n * `State` objects emitted by core are frozen per-navigation: their\n * `name` / `params` are immutable for the lifetime of the snapshot, and\n * any change produces a new `State` reference. A `WeakMap<State, string>`\n * therefore safely caches the canonicalised key by identity — repeat\n * `keyOf(state)` calls on the same snapshot (typical on\n * back/forward/traverse where the same prior `State` is re-emitted)\n * skip the recursive `canonicalJson` pass entirely.\n *\n * The cache key is the `State` reference, so entries auto-release when\n * the snapshot is GC'd — no eviction needed.\n */\nconst KEY_CACHE = new WeakMap<State, string>();\n\nexport function keyOf(state: State): string {\n const cached = KEY_CACHE.get(state);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const key = `${state.name}:${canonicalJson(state.params)}`;\n\n KEY_CACHE.set(state, key);\n\n return key;\n}\n\n/**\n * Stable JSON serializer with sorted object keys.\n *\n * **Exported for testing only — not part of the public API** (intentionally\n * excluded from `index.ts` barrel). Adapter property tests import it via\n * the direct path to lock the key-order-insensitive property\n * (`canonicalJson({a:1,b:2}) === canonicalJson({b:2,a:1})`).\n *\n * ## Divergence from `@real-router/sources/canonicalJson` — by design\n *\n * Two independent implementations live in the monorepo:\n *\n * - **`shared/dom-utils/scroll-restore.canonicalJson`** (this file) — scroll\n * cache key builder. Uses `localeCompare` and a plain-object accumulator;\n * tolerates `__proto__`-keyed inputs only insofar as `JSON.stringify`'s\n * replacer happens to sort them; relies on `JSON.stringify`'s native cycle\n * detector. Designed to be cheap on the navigation hot path. The\n * surrounding [[safeKeyOf]] wrapper catches the two crash inputs (`BigInt`,\n * cyclic) and skips the offending capture/restore.\n *\n * - **`@real-router/sources/canonicalJson`** — sources cache key builder.\n * Uses byte-order compare (`< / >`) for locale-independence, a\n * `Object.create(null)` accumulator to prevent prototype pollution, and a\n * bespoke path-based cycle detector (the native one cannot see the cloned\n * graph). Throws eagerly on `Map`/`Set`/`RegExp`/cycles — the caller falls\n * back to a non-cached source.\n *\n * **They are intentionally NOT interchangeable.** Aligning them would either\n * regress scroll-restore performance (byte-order + recursive clone is heavier\n * per call) or weaken the sources cache (locale dependence breaks\n * deterministic cache keys across machines). No cross-package equivalence\n * test exists or should be added; the relationship is \"different invariants,\n * different costs, different consumers.\" Audit-2 / audit-2026-05-17 §2\n * documents the choice.\n */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n // audit-2026-05-17 §5 MEDIUM (Sprint A.3) — function/Symbol marker.\n // `JSON.stringify` silently drops function and symbol values from\n // object output. Two routes that differ ONLY in a function/Symbol\n // value would canonicalize to the same string → silent scroll-cache\n // key collision (positions clobber each other). Replacing the value\n // with a sentinel string breaks the collision while keeping the\n // canonical form deterministic. The sentinels are intentionally\n // ASCII-only and lexically distinct from valid JSON-stringified\n // values; consumers will see `\"<fn>\"` / `\"<sym>\"` if they ever\n // round-trip the cache key, signalling the substitution clearly.\n if (typeof val === \"function\") {\n return \"<fn>\";\n }\n if (typeof val === \"symbol\") {\n return \"<sym>\";\n }\n\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n // Null-prototype accumulator: a plain `{}` would interpret\n // `sorted[\"__proto__\"] = x` as a prototype assignment (silently dropped\n // from JSON.stringify output AND a prototype-pollution vector). Mirrors\n // the same guard in `@real-router/sources/canonicalJson`. The two\n // implementations are still intentionally divergent (see the doc-block\n // on [[canonicalJson]] above), but prototype-safety is non-negotiable\n // on both. Lock-test: scrollRestoreKey.properties.ts Invariant 11.\n const sorted = Object.create(null) as Record<string, unknown>;\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val).sort((left: string, right: string) =>\n left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import { getTransitionSource } from \"@real-router/sources\";\n\nimport type { NavigationOptions, Router } from \"@real-router/core\";\n\n/**\n * Router-coordinated scroll spy (#575).\n *\n * On `IntersectionObserver` notifications the utility picks the topmost\n * visible anchor inside the configured scroll container and emits a forced\n * same-route transition with `{ hash, replace: true, force: true, hashChange:\n * true }` through `router.navigate(...)`. The URL plugin\n * (`@real-router/browser-plugin` or `@real-router/navigation-plugin`) updates\n * `state.context.url.hash` so sibling hash-aware `<Link hash>` re-highlights\n * via the standard `createActiveRouteSource` pipeline.\n *\n * **Anti-flicker gates** (RFC §5.2):\n * 1. `getTransitionSource(router).getSnapshot().isTransitioning` — skip emits\n * while a transition is in-flight (re-entrant lock).\n * 2. `coolingDown` — set on a user-driven hash transition (e.g. `<Link hash>`\n * click + smooth `scrollIntoView`). Cleared on `scrollend` or after a\n * 500ms safety timeout. Spy's own emits are excluded via the synchronous\n * `selfEmitting` flag — required so the spy doesn't rate-limit itself.\n *\n * **Self-healing** (RFC §7.3): if the initial URL contains a hash without a\n * matching `id` (e.g. `/page#nonexistent`), the first IO event emitted right\n * after observe()-ing picks the topmost real anchor and corrects the URL.\n *\n * **Hash-only transition pipeline cost** (RFC §5.3): for same-route same-\n * params hash-only navigations, `getTransitionPath` returns empty\n * `toDeactivate` / `toActivate` arrays, so `runGuards` is a no-op. The only\n * work is the URL plugin's `onTransitionSuccess` write and the\n * `getTransitionSource` flip — cheap.\n *\n * **Architecture**: decomposed into 4 private subsystem closure factories\n * (`createUrlPluginDetector`, `createCooldown`, `createDebouncer`,\n * `createObserverPair`). The main `createScrollSpy` wires them together\n * around the shared `silenced` / `destroyed` / `selfEmitting` flags and the\n * `flush()` emit logic. Each subsystem owns its state + cleanup; `destroy()`\n * delegates to each. See section banners below.\n *\n * @returns A `ScrollSpy` handle whose `destroy()` is idempotent.\n */\nexport interface ScrollSpyOptions {\n /**\n * CSS selector for anchor candidates. Empty string `\"\"` or `undefined`\n * disables the spy (returns a NOOP handle). Common values:\n * `\"[id]\"`, `\"[id]:is(h1,h2,h3)\"`, `\"section[id]\"`.\n */\n selector: string;\n\n /**\n * `IntersectionObserver` `rootMargin`. Default\n * `\"-20% 0px -60% 0px\"` — an anchor is considered \"active\" once it crosses\n * into the top 20 % of the viewport (or scroll container).\n */\n rootMargin?: string | undefined;\n\n /**\n * Lazy getter for the scrollable container. Resolved on every event.\n * `null` (or missing getter) falls back to the window viewport\n * (`root: null` on the `IntersectionObserver`).\n */\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\nexport interface ScrollSpy {\n /** Tear down observer + listeners. Idempotent. */\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ScrollSpy = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n// Hardcoded internals (RFC §5.1 — promote only with evidence).\nconst RAF_DEBOUNCE_MS = 150;\nconst MUTATION_DEBOUNCE_MS = 250;\nconst COOLDOWN_TIMEOUT_MS = 500;\nconst DEFAULT_ROOT_MARGIN = \"-20% 0px -60% 0px\";\n\n// Local extension type — browser-plugin / navigation-plugin augment\n// `NavigationOptions` with `hash` and `hashChange`, but `shared/dom-utils`\n// is plugin-agnostic and cannot rely on the augmentation. Mirrors the\n// `HashAwareNavigationOptions` pattern in `link-utils.ts`.\ntype HashAwareNavigationOptions = NavigationOptions & {\n hash?: string;\n hashChange?: boolean;\n};\n\ninterface UrlContextSlice {\n hash?: string;\n hashChanged?: boolean;\n}\n\nconst getUrlContext = (state: {\n context?: unknown;\n}): UrlContextSlice | undefined =>\n (state.context as { url?: UrlContextSlice } | undefined)?.url;\n\n// =============================================================================\n// Picker — pure, no state. RFC §5.2 selection rule.\n// =============================================================================\n\n// Pick the anchor closest to the active zone top in viewport coordinates.\n// `entry.rootBounds.top` already reflects `rootMargin` (per W3C IO spec\n// §3.3) — for `rootMargin: \"-20% 0px -60% 0px\"` it returns 20% of root\n// height, for `\"-50% 0px -50% 0px\"` it returns the center, etc. Distance\n// = boundingClientRect.top − zoneTop in viewport pixels: positive = anchor\n// below zone top (just entered), negative = anchor above zone top (body\n// crossing zone from above). We prefer smallest non-negative; fall back to\n// least-negative when no entry has crossed yet.\n// Falls back to zoneTop = 0 when rootBounds is null (cross-origin roots,\n// unit tests). Single pass — handles `Iterable` so flushes can pass\n// `Map.values()` directly without realising the array.\nconst pickTopmost = (\n entries: Iterable<IntersectionObserverEntry>,\n): IntersectionObserverEntry | null => {\n let bestPositive: IntersectionObserverEntry | null = null;\n let bestPositiveDist = Number.POSITIVE_INFINITY;\n let bestNegative: IntersectionObserverEntry | null = null;\n let bestNegativeDist = Number.NEGATIVE_INFINITY;\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n continue;\n }\n\n const zoneTop = entry.rootBounds?.top ?? 0;\n const distance = entry.boundingClientRect.top - zoneTop;\n\n if (distance >= 0) {\n if (distance < bestPositiveDist) {\n bestPositive = entry;\n bestPositiveDist = distance;\n }\n } else if (distance > bestNegativeDist) {\n bestNegative = entry;\n bestNegativeDist = distance;\n }\n }\n\n return bestPositive ?? bestNegative;\n};\n\n// =============================================================================\n// Subsystem: URL plugin detector (RFC §5.5)\n// Calls `onMissing` if `state.context` is published but `url` key is missing\n// (i.e. no URL plugin installed). Either synchronous on start, or deferred\n// via a one-shot `router.subscribe` if the router has not started yet.\n// `silenced` flag itself lives in main scope — detector signals via callback\n// (per Oracle Q1 — `silenced` has multiple unrelated triggers; main scope\n// owns the kill switch).\n// =============================================================================\n\ninterface UrlPluginDetector {\n destroy: () => void;\n}\n\nconst createUrlPluginDetector = (\n router: Router,\n onMissing: () => void,\n): UrlPluginDetector => {\n let detectionUnsub: (() => void) | null = null;\n\n const verify = (state: { context?: unknown }): void => {\n const context = state.context as\n | (Record<string, unknown> & { url?: unknown })\n | undefined;\n\n if (context && context.url === undefined) {\n console.warn(\n \"[real-router] scroll-spy: state.context.url is not claimed. \" +\n \"Spy requires browser-plugin or navigation-plugin. Disabling.\",\n );\n onMissing();\n }\n };\n\n const peekState = router.getState();\n\n if (peekState) {\n verify(peekState);\n } else {\n // Re-entry guard: `router.subscribe` MAY invoke the callback synchronously\n // from inside `.subscribe(...)` before the function returns. In that case\n // `detectionUnsub` is still `null` when the callback fires. Without this\n // boolean, a hypothetical multi-fire would double-warn.\n let detectionConsumed = false;\n\n detectionUnsub = router.subscribe(({ route }) => {\n /* v8 ignore next 3 -- @preserve: the multi-fire is hypothetical (see above) — the real router never invokes a subscriber synchronously twice before unsub; defensive guard, not testable without a contract-violating fake */\n if (detectionConsumed) {\n return;\n }\n\n detectionConsumed = true;\n verify(route);\n\n detectionUnsub?.();\n detectionUnsub = null;\n });\n }\n\n return {\n destroy(): void {\n detectionUnsub?.();\n detectionUnsub = null;\n },\n };\n};\n\n// =============================================================================\n// Subsystem: Cooldown gate (RFC §5.2 — anti-flicker for smooth scrollIntoView)\n// Set on user-driven `<Link hash>` click → smooth scroll. Cleared on\n// `scrollend` (Baseline 2026) or 500ms safety timeout (older Safari).\n// =============================================================================\n\ninterface Cooldown {\n readonly active: boolean;\n start: () => void;\n destroy: () => void;\n}\n\nconst createCooldown = (getContainer: () => HTMLElement | null): Cooldown => {\n let active = false;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let listenerContainer: HTMLElement | null = null;\n let listener: (() => void) | null = null;\n\n const clear = (): void => {\n if (timeout !== null) {\n clearTimeout(timeout);\n timeout = null;\n }\n\n if (listener) {\n const target: EventTarget = listenerContainer ?? globalThis;\n\n target.removeEventListener(\"scrollend\", listener);\n }\n\n listener = null;\n listenerContainer = null;\n active = false;\n };\n\n return {\n get active(): boolean {\n return active;\n },\n start(): void {\n // Reset rather than stack timers if cooldown is already active.\n clear();\n\n active = true;\n\n const lift = (): void => {\n clear();\n };\n\n listener = lift;\n listenerContainer = getContainer();\n\n const target: EventTarget = listenerContainer ?? globalThis;\n\n target.addEventListener(\"scrollend\", lift, { once: true });\n\n timeout = setTimeout(lift, COOLDOWN_TIMEOUT_MS);\n },\n destroy(): void {\n clear();\n },\n };\n};\n\n// =============================================================================\n// Subsystem: rAF + trailing debounce (RFC §5.1)\n// Coalesces a burst of IO events into ≤ 1 callback per debounce window.\n// rAF reduces N setTimeout creations to 1 per animation frame; the trailing\n// 150ms setTimeout waits for the IO stream to quiesce.\n// =============================================================================\n\ninterface Debouncer {\n schedule: () => void;\n destroy: () => void;\n}\n\nconst createDebouncer = (\n callback: () => void,\n trailingMs: number,\n): Debouncer => {\n let raf: number | null = null;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return {\n schedule(): void {\n if (raf !== null) {\n return;\n }\n\n raf = requestAnimationFrame(() => {\n raf = null;\n\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => {\n timeout = null;\n callback();\n }, trailingMs);\n });\n },\n destroy(): void {\n if (raf !== null) {\n cancelAnimationFrame(raf);\n raf = null;\n }\n\n if (timeout !== null) {\n clearTimeout(timeout);\n timeout = null;\n }\n },\n };\n};\n\n// =============================================================================\n// Subsystem: Observer pair (IntersectionObserver + MutationObserver)\n// IO + MO genuinely form one subsystem — both write/read `observed` set and\n// `pending` map, and reconcile flow couples them. Per Oracle Q10, splitting\n// would force cross-subsystem references that re-introduce the wiring\n// problem we're trying to solve.\n//\n// Exposes `pending` directly (per Oracle Q4: hiding behind `consume()` adds\n// boilerplate without isolating the shared mutable state — observers write\n// from IO callbacks while main scope reads in `flush()`).\n// =============================================================================\n\ninterface ObserverPair {\n readonly pending: Map<Element, IntersectionObserverEntry>;\n destroy: () => void;\n}\n\nconst createObserverPair = (\n selector: string,\n rootMargin: string,\n getContainer: () => HTMLElement | null,\n onIntersection: () => void,\n onInvalidSelector: () => void,\n isStopped: () => boolean,\n): ObserverPair => {\n const observed = new Set<Element>();\n // Latest IO entry per target — accumulated across batches. IO delivers\n // entries only for targets whose intersection state CHANGED (W3C IO\n // §3.2.1), so a fast scroll that lands two callbacks inside the same\n // debounce window must merge by target, not overwrite. Entries are\n // dropped from the map when their target leaves the DOM (see `reconcile`)\n // and on `destroy()`.\n const pending = new Map<Element, IntersectionObserverEntry>();\n\n let duplicateIdWarned = false;\n let mutationTimer: ReturnType<typeof setTimeout> | null = null;\n\n const handleIntersection: IntersectionObserverCallback = (entries) => {\n // Defensive: IO callback may fire AFTER `destroy()` if a queued event\n // was already scheduled by the browser before `disconnect()`. Cheap\n // belt-and-suspenders.\n if (isStopped()) {\n return;\n }\n\n for (const entry of entries) {\n pending.set(entry.target, entry);\n }\n\n onIntersection();\n };\n\n const io = new IntersectionObserver(handleIntersection, {\n root: getContainer(),\n rootMargin,\n threshold: 0,\n });\n\n const observeMatches = (): void => {\n const scope = getContainer() ?? document;\n let candidates: NodeListOf<Element>;\n\n try {\n candidates = scope.querySelectorAll(selector);\n } catch {\n onInvalidSelector();\n\n return;\n }\n\n const seenIds = new Set<string>();\n\n for (const element of candidates) {\n // Detect duplicate ids once (RFC §7.7). The DOM permits duplicate ids\n // even though it is a markup bug; the spy keeps working but picks the\n // first one deterministically via the topmost-visible rule.\n const id = (element as HTMLElement).id;\n\n if (id && !duplicateIdWarned) {\n if (seenIds.has(id)) {\n duplicateIdWarned = true;\n\n console.warn(\n `[real-router] scroll-spy: duplicate id \"${id}\" observed. ` +\n \"Selection picks the topmost visible match deterministically.\",\n );\n }\n\n seenIds.add(id);\n }\n\n if (observed.has(element)) {\n continue;\n }\n\n io.observe(element);\n observed.add(element);\n }\n };\n\n const reconcile = (): void => {\n // Drop observed elements that left the DOM. Avoids observer holding\n // strong refs to detached nodes. Also drop their accumulated entry so\n // stale \"was intersecting\" state for a removed node cannot be picked\n // by `pickTopmost` after the node is gone.\n for (const element of observed) {\n if (!element.isConnected) {\n io.unobserve(element);\n observed.delete(element);\n pending.delete(element);\n }\n }\n\n observeMatches();\n };\n\n observeMatches();\n\n // MutationObserver targets the scroll container (or document.body for\n // window viewport). `childList: true, subtree: true` catches structural\n // changes; `attributes: true, attributeFilter: [\"id\"]` catches anchor\n // id renames (typical for client-rendered docs).\n const mutationTarget = getContainer() ?? document.body;\n\n const mo = new MutationObserver(() => {\n if (mutationTimer !== null) {\n clearTimeout(mutationTimer);\n }\n\n mutationTimer = setTimeout(() => {\n mutationTimer = null;\n reconcile();\n }, MUTATION_DEBOUNCE_MS);\n });\n\n mo.observe(mutationTarget, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"id\"],\n });\n\n return {\n pending,\n destroy(): void {\n io.disconnect();\n mo.disconnect();\n\n if (mutationTimer !== null) {\n clearTimeout(mutationTimer);\n mutationTimer = null;\n }\n\n observed.clear();\n pending.clear();\n },\n };\n};\n\n// =============================================================================\n// Main: compositional wiring\n// =============================================================================\n\nexport function createScrollSpy(\n router: Router,\n options: ScrollSpyOptions,\n): ScrollSpy {\n // SSR guard (RFC §7.5) — return early without warnings.\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n // Feature-detect IntersectionObserver — no polyfill ships (RFC §4).\n if (typeof IntersectionObserver === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const { selector } = options;\n\n // Empty selector → disabled. Documented opt-out for conditional enabling\n // (RFC §5.4 `scrollSpy={{ selector: enable ? \"[id]\" : \"\" }}`).\n if (!selector) {\n return NOOP_INSTANCE;\n }\n\n const rootMargin = options.rootMargin ?? DEFAULT_ROOT_MARGIN;\n const getContainer = options.scrollContainer;\n const resolveContainer = (): HTMLElement | null => getContainer?.() ?? null;\n\n // Shared lifecycle flags (Oracle Q1 — `silenced` has multiple unrelated\n // triggers; Oracle Q3 — `selfEmitting` synchronously bracketed around\n // `router.navigate()` cannot cleanly extract). Kept in main scope.\n let destroyed = false;\n let silenced = false;\n let selfEmitting = false;\n\n const isStopped = (): boolean => silenced || destroyed;\n\n // Symmetric late-binding (Oracle Q2): declare `flush` as nullable, wire\n // debouncer + observers, then assign the real implementation. Reads as\n // intentional wiring rather than accidental closure capture ordering.\n // The `flush?.()` call below safely no-ops if a callback somehow fires\n // before assignment (impossible in practice — IO/debounce are async).\n let flush: (() => void) | null = null;\n\n const transitionSource = getTransitionSource(router);\n\n const detector = createUrlPluginDetector(router, () => {\n silenced = true;\n });\n\n const cooldown = createCooldown(resolveContainer);\n\n const debouncer = createDebouncer(() => {\n flush?.();\n }, RAF_DEBOUNCE_MS);\n\n const observers = createObserverPair(\n selector,\n rootMargin,\n resolveContainer,\n () => {\n debouncer.schedule();\n },\n () => {\n if (silenced) {\n return;\n }\n\n silenced = true;\n\n console.warn(\n `[real-router] scroll-spy: invalid selector \"${selector}\". Disabling.`,\n );\n },\n isStopped,\n );\n\n flush = (): void => {\n if (destroyed || silenced) {\n observers.pending.clear();\n\n return;\n }\n\n // Gate-skipped flushes keep `pendingEntries` populated — the merged\n // state is still the best-known snapshot, and the next non-gated flush\n // consumes it. Clearing under a gate would re-introduce the overwrite\n // bug for any anchor whose intersection state did not change during\n // the gate window.\n if (transitionSource.getSnapshot().isTransitioning) {\n return;\n }\n\n if (cooldown.active) {\n return;\n }\n\n if (observers.pending.size === 0) {\n return;\n }\n\n // Successful flush consumes the merged snapshot. We clear so that the\n // next debounce window starts fresh; an anchor that is still\n // intersecting will only stay observable if IO emits another event for\n // it (which it does whenever the anchor's intersection state actually\n // changes). Skipping the clear here would leak state from one user-\n // perceived \"scroll stop\" into the next.\n const picked = pickTopmost(observers.pending.values());\n\n observers.pending.clear();\n\n if (!picked) {\n // No anchor visible / above zone — preserve last hash (RFC §10 #5).\n return;\n }\n\n const newHash = (picked.target as HTMLElement).id;\n\n if (!newHash) {\n return;\n }\n\n const state = router.getState();\n\n if (!state) {\n return;\n }\n\n const currentHash = getUrlContext(state)?.hash ?? \"\";\n\n if (newHash === currentHash) {\n return;\n }\n\n // Emit the same-route same-params hash-only transition. URL plugin\n // writes `state.context.url.hash = newHash` + `hashChanged = true` in\n // its `onTransitionSuccess` claim.\n const opts: HashAwareNavigationOptions = {\n hash: newHash,\n replace: true,\n force: true,\n hashChange: true,\n };\n\n // Self-emit guard (RFC §5.2): set synchronously around our own\n // `router.navigate()` so the `router.subscribe` callback skips the\n // cooldown setup for spy-emitted transitions — otherwise spy would\n // rate-limit itself to ≤ 2 emits/s, contradicting the ≤ 10/s benchmark\n // target. Test coupling (Q8): preserve exact `.catch(noop).finally(reset)`\n // chain — migrating to `try/finally` over `await router.navigate(...)`\n // changes microtask schedule and breaks \"spy continues after rejection\".\n selfEmitting = true;\n router\n .navigate(state.name, state.params, opts)\n .catch(() => {\n // Fire-and-forget — suppress expected rejections (concurrent\n // navigate, router stopped, etc.) consistent with `<Link>` adapter\n // patterns.\n })\n .finally(() => {\n selfEmitting = false;\n });\n };\n\n // Cooldown setup on user-driven hash transitions. Spy's own emits are\n // distinguished via the synchronous `selfEmitting` flag (see `flush`).\n const unsubscribeRouter = router.subscribe(({ route }) => {\n if (selfEmitting) {\n return;\n }\n\n if (getUrlContext(route)?.hashChanged) {\n cooldown.start();\n }\n });\n\n return {\n destroy(): void {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n\n // Unsubscribe FIRST to prevent late-arriving router transition\n // callback from calling `cooldown.start()` on a half-destroyed\n // instance. Without this ordering, a transition with `hashChanged:\n // true` firing between subsystem teardown and `unsubscribeRouter()`\n // would re-install a 500ms timer that survives `destroy()`. Verified\n // via Oracle review (Q5/Q7).\n unsubscribeRouter();\n\n observers.destroy();\n debouncer.destroy();\n cooldown.destroy();\n detector.destroy();\n },\n };\n}\n","import type { Router } from \"@real-router/core\";\n\nexport interface ViewTransitions {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ViewTransitions = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createViewTransitions(router: Router): ViewTransitions {\n if (\n typeof document === \"undefined\" ||\n typeof document.startViewTransition !== \"function\"\n ) {\n return NOOP_INSTANCE;\n }\n\n let closeVT: (() => void) | null = null;\n let currentVT: { skipTransition?: () => void } | null = null;\n // Tracks whether TRANSITION_SUCCESS fired for the current leave. Used to\n // distinguish \"benign cleanup abort\" (router's async path aborts its own\n // controller in a finally block after successful navigation) from \"real\n // cancellation\" (concurrent navigate, guard rejection, dispose).\n let successFired = false;\n\n const resolveAndClear = (): void => {\n closeVT?.();\n closeVT = null;\n };\n\n const offLeave = router.subscribeLeave(({ signal }) => {\n // Reentrant abort: signal already aborted when we're called. Open no VT\n // — router will fall through to TRANSITION_CANCELLED via isCurrentNav()\n // after leave resolves. addEventListener(\"abort\", ...) does not re-fire\n // for past events, so skipping startViewTransition is the safe path.\n if (signal.aborted) {\n return;\n }\n\n successFired = false;\n resolveAndClear();\n\n // Return a Promise so the router awaits until the browser invokes\n // updateCallback. This ensures old DOM snapshot is captured BEFORE the\n // router commits the new state — giving correct exit→state→entry\n // ordering (vs fire-and-forget, where URL changes before VT captures).\n return new Promise<void>((resolveLeave) => {\n // Capture the resolver synchronously BEFORE startViewTransition() is\n // called. The browser invokes updateCallback in a later task, but\n // router.subscribe (TRANSITION_SUCCESS) can fire before that. If we\n // captured `resolve` inside the callback, subscribe would see closeVT\n // still null and skip resolving — the deferred would hang for 4s\n // until the VT API aborts with TimeoutError.\n const deferred = new Promise<void>((resolve) => {\n closeVT = resolve;\n });\n\n signal.addEventListener(\n \"abort\",\n () => {\n if (successFired) {\n // Router's async path (#finishAsyncNavigation) aborts its own\n // controller in a finally block AFTER completeTransition (and\n // thus AFTER subscribe fired). This is cleanup, not\n // cancellation — VT is progressing normally, do nothing.\n return;\n }\n\n // Real cancellation (concurrent navigate, dispose). Resolve the\n // deferred so updateCallback can complete, skip the VT so no\n // stale animation leaks, and unblock the router if the abort\n // fires before updateCallback was invoked.\n resolveAndClear();\n currentVT?.skipTransition?.();\n resolveLeave();\n },\n { once: true },\n );\n\n try {\n currentVT = document.startViewTransition(() => {\n // Resolving here unblocks the router at the moment the browser\n // enters updateCallback — by spec, old DOM snapshot is captured\n // before this callback runs. Router now proceeds through\n // activation guards and setState; the VT animation waits on\n // `deferred`, which is resolved from router.subscribe after a\n // task-queue tick (see NOTE on setTimeout below).\n resolveLeave();\n\n return deferred;\n });\n } catch {\n // Defensive: spec says startViewTransition doesn't throw under\n // normal conditions, but Chromium has had edge cases (detached\n // document, extension interference). Clean up and unblock router.\n resolveAndClear();\n resolveLeave();\n }\n });\n });\n\n const offSuccess = router.subscribe(() => {\n const resolver = closeVT;\n\n successFired = true;\n closeVT = null;\n\n if (resolver === null) {\n currentVT = null;\n } else {\n // CRITICAL: CANNOT use requestAnimationFrame here. When the router\n // takes the async path (leave returned a Promise), subscribe fires\n // AFTER the browser has already transitioned VT into the\n // \"update-callback-called\" phase. In that phase Chromium sets\n // rendering suppression to true, which ALSO blocks rAF callbacks.\n // rAF would never fire → deferred never resolves → browser aborts\n // vt.ready with TimeoutError after 4s (observed in Chromium).\n //\n // setTimeout runs on the task queue independent of the rendering\n // pipeline, so it fires regardless of suppression. React's scheduler\n // uses MessageChannel tasks, which are queued before our setTimeout,\n // so the new DOM is committed by the time our callback runs.\n setTimeout(() => {\n resolver();\n currentVT = null;\n }, 0);\n }\n });\n\n return {\n destroy: () => {\n offLeave();\n offSuccess();\n currentVT?.skipTransition?.();\n currentVT = null;\n resolveAndClear();\n },\n };\n}\n","import type {\n NavigationOptions,\n Params,\n Router,\n State,\n} from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\n// Matches a single percent-escape triple (`%` + two hex digits). Used as\n// the \"already-encoded\" probe in `encodeFragmentInline` below — see the\n// idempotency rationale there.\nconst PERCENT_ESCAPE_PROBE = /%[\\dA-Fa-f]{2}/;\n\n/**\n * RFC 3986 fragment encoding: preserve sub-delims (`&`, `=`, `?`, `:`),\n * encode space, `%`, control chars, non-ASCII via encodeURI; defensively\n * escape `#` (encodeURI does not). Mirrors `encodeHashFragment` in\n * `shared/browser-env/url-context.ts` — duplicated here because the\n * shared/dom-utils symlink graph does not reach shared/browser-env.\n *\n * **Idempotency for pre-encoded input (audit-2026-05-17 §5 MEDIUM E.1).**\n * The doc-comment on `<Link hash>` says the value is a \"decoded fragment\n * without leading #\". But realistic consumers copy hashes out of\n * `location.hash` (which is percent-encoded) and pass them back, so the\n * naive `encodeURI(\"%20\")` would double-encode into `\"%2520\"` and break\n * anchor lookup. We detect a percent-escape triple in the input and, if\n * present, decode + re-encode for idempotency. Malformed `%XX` (e.g.\n * `\"%2\"` or `\"%ZZ\"`) makes `decodeURIComponent` throw — in that case we\n * fall through to plain `encodeURI`, which never throws.\n */\nfunction encodeFragmentInline(decoded: string): string {\n if (PERCENT_ESCAPE_PROBE.test(decoded)) {\n try {\n const roundtrip = decodeURIComponent(decoded);\n\n return encodeURI(roundtrip).replaceAll(\"#\", \"%23\");\n } catch {\n // Malformed `%XX` — fall through to the plain encoding path.\n // encodeURI does not throw on malformed escapes; it treats the\n // `%` as a literal and percent-encodes it (`%2` → `%252`).\n }\n }\n\n return encodeURI(decoded).replaceAll(\"#\", \"%23\");\n}\n\ntype BuildUrlFn = (\n name: string,\n params: Params,\n options?: { hash?: string },\n) => string | undefined;\n\n/**\n * Builds an href for a `<Link>` element.\n *\n * - Prefers the URL plugin's `buildUrl` (browser-plugin, navigation-plugin,\n * hash-plugin) when present.\n * - Falls back to `router.buildPath` for runtimes without a URL plugin\n * (memory-plugin, console UIs, NativeScript). In that fallback the hash\n * is appended manually so the rendered href is still correct.\n * - The optional 4th argument is an options object so the contract stays\n * extensible. The `hash` option is a decoded fragment without leading \"#\";\n * `<Link hash=\"#section\">` is accepted defensively (leading \"#\" stripped).\n * Frozen API: previous 3-arg call sites continue to work unchanged.\n */\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n options?: { hash?: string },\n): string | undefined {\n try {\n const rawHash = options?.hash;\n let normHash: string | undefined;\n\n if (rawHash !== undefined) {\n normHash = rawHash.startsWith(\"#\") ? rawHash.slice(1) : rawHash;\n }\n\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(\n routeName,\n routeParams,\n normHash === undefined ? undefined : { hash: normHash },\n );\n\n // Accept only non-empty strings. The BuildUrlFn type contract is\n // `string | undefined`, but defensive against:\n // - `\"\"` (empty string) → would render `<a href=\"\">`, which resolves\n // to the current page URL → silent self-navigation on click.\n // - `null` (type-contract violation) → would render `<a href={null}>`,\n // stringified to `\"null\"` in some renderers.\n // Either case falls through to the `router.buildPath` fallback below.\n if (typeof url === \"string\" && url.length > 0) {\n return url;\n }\n }\n\n const path = router.buildPath(routeName, routeParams);\n\n // Symmetric to the buildUrl guard above (#S1 audit, Invariant 12).\n // `router.buildPath` is typed `string`, but defends against:\n // - `\"\"` (empty string) — would render `<a href=\"\">`, which resolves\n // to the current page URL → silent self-navigation on click.\n // - non-string type-contract violations from custom path-matchers.\n // Both yield `undefined` (renderer drops the attribute) with a warning.\n if (typeof path !== \"string\" || path.length === 0) {\n console.error(\n `[real-router] Route \"${routeName}\" yielded an empty path. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n\n return normHash ? `${path}#${encodeFragmentInline(normHash)}` : path;\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\n/**\n * `<Link>` click-handler navigation helper (#532).\n *\n * Wraps `router.navigate(name, params, opts)` with same-route different-hash\n * detection: when the consumer clicks a hash-bearing Link that targets the\n * current route with the same params but a different fragment, core's\n * SAME_STATES check would otherwise reject the navigation. The helper adds\n * `force: true` and `hashChange: true` automatically — subscribers can then\n * disambiguate via `state.context.url.hashChanged`.\n *\n * For pure programmatic same-route hash-only navigation, callers are\n * documented to pass `{ force: true }` themselves; the auto-bypass here is\n * a UX convenience for `<Link hash>` that all 6 framework adapters share.\n */\n/**\n * Local extended-options type. Adapters that depend only on `@real-router/core`\n * (without a URL plugin) do not see the `NavigationOptions` augmentation that\n * declares `hash` / `hashChange`. Casting to this widened type inside the\n * helper keeps shared/dom-utils self-contained — adapters do not need to\n * augment NavigationOptions themselves to consume `<Link hash>`.\n */\ntype HashAwareNavigationOptions = NavigationOptions & {\n hash?: string;\n hashChange?: boolean;\n};\n\nexport function navigateWithHash(\n router: Router,\n routeName: string,\n routeParams: Params,\n hash: string | undefined,\n extraOptions?: NavigationOptions,\n): Promise<State> {\n const opts: HashAwareNavigationOptions = { ...extraOptions };\n\n if (hash !== undefined) {\n opts.hash = hash;\n }\n\n const current = router.getState();\n\n if (\n current?.name === routeName &&\n shallowEqual(current.params, routeParams)\n ) {\n const currentHash =\n (current.context as { url?: { hash?: string } } | undefined)?.url?.hash ??\n \"\";\n const newHash = hash ?? currentHash;\n\n if (currentHash !== newHash) {\n opts.force = true;\n opts.hashChange = true;\n }\n }\n\n return router.navigate(routeName, routeParams, opts);\n}\n\n// Match-any-whitespace regex shared across calls. RegExp literals at\n// call-site recompile in some engines; lifting it avoids that microcost\n// for the slow-path branch.\nconst WHITESPACE_PROBE = /\\s/;\nconst WHITESPACE_SPLIT = /\\S+/g;\n\n// `value` is always a truthy class string: both call sites narrow it first\n// (`if (isActive && activeClassName)` / `if (!baseClassName) return …`), so the\n// former `if (!value) return []` guard was unreachable dead code (#809).\nfunction parseTokens(value: string): string[] {\n // Hot-path fast-path (audit-2026-05-17 §8b #1): >99% of active-class\n // inputs at `<Link>` emit are single-token strings like `\"active\"` or\n // `\"is-current\"` — no whitespace, no leading/trailing pad. Skip the\n // regex match and Array result allocation: a literal `[value]` works\n // because the slow-path `match(/\\S+/g)` would return exactly `[value]`\n // for the same input. PBT lock: linkUtils.properties.ts Invariant 13.\n if (!WHITESPACE_PROBE.test(value)) {\n return [value];\n }\n\n return value.match(WHITESPACE_SPLIT) ?? [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\n/**\n * One-level structural equality using `Object.is` per key.\n *\n * **String-keyed properties only (Mini-sprint E.3 — audit-5 §4.2 #3).**\n * Implementation walks `Object.keys()` which by spec returns only\n * enumerable own STRING keys. Symbol-keyed properties — created via\n * `obj[Symbol(\"brand\")] = value` or `{ [Symbol(...)]: value }` — are\n * NOT compared. Two records that differ only in a Symbol-keyed value\n * will compare as equal.\n *\n * This is intentional: route params and Link options are documented as\n * string-keyed primitives (string | number | boolean) — Symbol-keyed\n * metadata (e.g. brand markers, private state) doesn't belong in a\n * cache-key comparison. Switching to `Reflect.ownKeys()` would extend\n * the contract to symbols at the cost of one extra allocation per call\n * (Reflect.ownKeys composes string-keys + symbol-keys arrays). If a\n * consumer relies on symbol-keyed metadata for navigation\n * disambiguation, they should encode it into a string key instead.\n *\n * Mirrors React's `shallowEqual` (packages/shared/shallowEqual.js) in\n * both the string-keys-only semantics and the `hasOwnProperty` guard\n * below.\n */\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n // hasOwnProperty guard: without it, a key missing in `next` reads as\n // `undefined` and falsely matches `prev[key] === undefined`. Same shape\n // as React's shallowEqual (packages/shared/shallowEqual.js).\n if (\n !Object.prototype.hasOwnProperty.call(next, key) ||\n !Object.is(prevRecord[key], nextRecord[key])\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n\n // Cross-realm safety (audit-2026-05-17 §5 HIGH #4):\n // `instanceof HTMLAnchorElement` compares against the constructor from\n // the CURRENT realm. An element created in a different window (iframe\n // contentDocument, micro-frontend, embedded widget) fails the check\n // even when it IS a real anchor — the helper would then inject\n // role=\"link\" + tabindex=\"0\" on top of native anchor semantics,\n // breaking screen reader output (\"link link\") and focus order.\n //\n // tagName is realm-agnostic and is uppercase for HTML-namespaced\n // elements in any document. SVG `<a>` has lowercase tagName plus a\n // different prototype (SVGAElement) — skipping it here is wrong by\n // accident: SVG anchors don't have keyboard activation semantics the\n // helper would add. But they also don't reach this helper in\n // practice (router Link components emit HTML anchors). Lock the\n // uppercase compare to keep the contract narrow.\n const tag = element.tagName;\n\n if (tag === \"A\" || tag === \"BUTTON\") {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { ApplicationRef, DestroyRef, inject } from \"@angular/core\";\n\nimport {\n createScrollRestoration,\n createScrollSpy,\n createViewTransitions,\n} from \"../dom-utils\";\nimport { ROUTER } from \"../providers\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"../dom-utils\";\n\n/**\n * Shared installation helpers for `provideRealRouter` and\n * `provideRealRouterFactory`. Must be called inside the body of a\n * `provideEnvironmentInitializer(() => { ... })` callback so the active\n * injection context resolves `ROUTER`, `ApplicationRef`, and `DestroyRef`.\n *\n * Closes review-2026-05-10 §8.1 MED — eliminates duplicate wiring between\n * `providers.ts` and `providersFactory.ts` (high drift risk noted in the\n * audit: the comment blocks were identical down to the punctuation).\n */\n\nexport function installScrollRestoration(\n options: ScrollRestorationOptions,\n): void {\n const router = inject(ROUTER);\n const sr = createScrollRestoration(router, options);\n\n inject(DestroyRef).onDestroy(() => {\n sr.destroy();\n });\n}\n\nexport function installScrollSpy(options: ScrollSpyOptions): void {\n const router = inject(ROUTER);\n const spy = createScrollSpy(router, options);\n\n inject(DestroyRef).onDestroy(() => {\n spy.destroy();\n });\n}\n\nexport function installViewTransitions(): void {\n const router = inject(ROUTER);\n\n // Feature-detect `document.startViewTransition` once at install time. The\n // `appRef.tick()` listener exists ONLY to feed Angular's zoneless CD into\n // the VT utility's `setTimeout(0)`-driven snapshot capture (see comment\n // below). When `startViewTransition` is unavailable (Firefox as of 2026-04,\n // SSR, older browsers), `createViewTransitions` short-circuits to its\n // frozen NOOP_INSTANCE — no leave subscriber registered, no\n // `setTimeout(0)` invariant to satisfy. Installing the per-navigation\n // tick listener anyway would force a synchronous CD pass on every\n // navigation with zero benefit, doubling CD work in zoneless apps.\n // Closes review-2026-05-10 §8.2 MED (view-transitions hot path).\n const vtAvailable =\n typeof document !== \"undefined\" &&\n typeof document.startViewTransition === \"function\";\n\n let offTick: (() => void) | undefined;\n\n if (vtAvailable) {\n // Force synchronous change detection on every transition success BEFORE\n // the VT utility resolves its deferred. The utility uses `setTimeout(0)`\n // to release the new-snapshot capture, which is load-bearing because\n // Chromium blocks rAF callbacks while VT sits in the\n // `update-callback-called` phase. Angular's zoneless CD is rAF-driven by\n // default — without this synchronous tick the new DOM is not committed\n // when the browser captures the new snapshot, so old and new snapshots\n // end up identical and animations finish in ~0 ms with no visible work\n // (the inner-route `products.list ↔ products.detail` morph in the\n // example app was the canary).\n //\n // Subscribers fire in registration order; this one runs BEFORE\n // `createViewTransitions` registers its own subscriber, guaranteeing CD\n // completes first.\n const appRef = inject(ApplicationRef);\n\n offTick = router.subscribe(() => {\n appRef.tick();\n });\n }\n\n const vt = createViewTransitions(router);\n\n inject(DestroyRef).onDestroy(() => {\n offTick?.();\n vt.destroy();\n });\n}\n","import { signal, type Signal, inject, DestroyRef } from \"@angular/core\";\n\nimport type { RouterSource } from \"@real-router/sources\";\n\n/** Must be called within an injection context (constructor, field initializer, runInInjectionContext). */\nexport function sourceToSignal<T>(source: RouterSource<T>): Signal<T> {\n const sig = signal<T>(source.getSnapshot());\n const destroyRef = inject(DestroyRef);\n\n const unsubscribe = source.subscribe(() => {\n sig.set(source.getSnapshot());\n });\n\n destroyRef.onDestroy(() => {\n // `try/finally` guarantees `source.destroy()` runs even if `unsubscribe`\n // throws. Cached sources from `@real-router/sources` keep `destroy()` as\n // a no-op (so they survive multi-consumer teardown), but non-cached\n // sources rely on this call to release their router subscription —\n // skipping it on an unsubscribe throw would leak the listener.\n try {\n unsubscribe();\n } finally {\n source.destroy();\n }\n });\n\n return sig.asReadonly();\n}\n","import {\n InjectionToken,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport { getNavigator, type Router, type Navigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport {\n installScrollRestoration,\n installScrollSpy,\n installViewTransitions,\n} from \"./internal/install\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\nexport const ROUTER = new InjectionToken<Router>(\"ROUTER\");\n\nexport const NAVIGATOR = new InjectionToken<Navigator>(\"NAVIGATOR\");\n\nexport const ROUTE = new InjectionToken<RouteSignals>(\"ROUTE\");\n\nexport interface RealRouterOptions {\n scrollRestoration?: ScrollRestorationOptions;\n scrollSpy?: ScrollSpyOptions;\n viewTransitions?: boolean;\n}\n\nexport function provideRealRouter(\n router: Router,\n options?: RealRouterOptions,\n): EnvironmentProviders {\n const navigator = getNavigator(router);\n\n // `Parameters<typeof makeEnvironmentProviders>[0]` is the actual union\n // `(Provider | EnvironmentProviders | EnvironmentProviders[])[]` —\n // `provideEnvironmentInitializer()` returns `EnvironmentProviders`, so the\n // narrower `Provider[]` would force a cast at every push (review §8a — the\n // proposed Provider[] swap was retracted after discovering this).\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: ROUTER, useValue: router },\n { provide: NAVIGATOR, useValue: navigator },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => ({\n routeState: sourceToSignal(createRouteSource(router)),\n navigator,\n }),\n },\n ];\n\n if (options?.scrollRestoration) {\n const scrollOpts = options.scrollRestoration;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollRestoration(scrollOpts);\n }),\n );\n }\n\n if (options?.scrollSpy && options.scrollSpy.selector !== \"\") {\n const spyOpts = options.scrollSpy;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollSpy(spyOpts);\n }),\n );\n }\n\n if (options?.viewTransitions === true) {\n providers.push(provideEnvironmentInitializer(installViewTransitions));\n }\n\n return makeEnvironmentProviders(providers);\n}\n","import {\n DestroyRef,\n REQUEST,\n TransferState,\n inject,\n makeEnvironmentProviders,\n makeStateKey,\n provideAppInitializer,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport {\n getNavigator,\n type DefaultDependencies,\n type PluginFactory,\n type Router,\n} from \"@real-router/core\";\nimport { cloneRouter } from \"@real-router/core/api\";\nimport { hydrateRouter, serializeRouterState } from \"@real-router/core/utils\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport {\n installScrollRestoration,\n installScrollSpy,\n installViewTransitions,\n} from \"./internal/install\";\nimport { NAVIGATOR, ROUTE, ROUTER } from \"./providers\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions, ScrollSpyOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\n/**\n * `TransferState` key carrying the SSR-resolved router state from server to\n * client as an XSS-safe JSON string (produced by `serializeRouterState`).\n * Populated server-side by the `provideAppInitializer` callback after\n * `router.start()` resolves; consumed client-side after hydration. Mirrors the\n * `<script>window.__SSR_STATE__ = …</script>` pattern used by every other\n * adapter — Angular's idiomatic transport is `TransferState` (#599).\n *\n * Stored as `string`: `serializeRouterState(state)` already produces JSON;\n * `hydrateRouter(router, json)` accepts a JSON string and parses it once\n * internally. Storing the parsed object would force a double round-trip\n * (TransferState wraps every value in JSON for transport).\n *\n * Internal implementation detail. Not re-exported.\n */\nconst ROUTER_STATE_KEY = makeStateKey<string>(\"@real-router/angular:ssrState\");\n\n/**\n * Factory function for deriving per-request dependencies from an SSR `Request`.\n *\n * - **Server:** receives the real `Request` exposed via Angular's `REQUEST` token.\n * - **SSG:** receives a mocked `Request` injected via `platformProviders`.\n * - **Client:** receives `null` — derive deps from `document.cookie` etc.\n *\n * The returned object becomes the second argument to\n * `cloneRouter(baseRouter, deps)`. Returning `undefined` clones the router with\n * no extra deps (cloneRouter accepts the optional 2nd argument).\n */\nexport type RequestDepsFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> = (request: Request | null) => TDeps | undefined;\n\n/**\n * Function form for conditional plugins (different sets server vs client).\n *\n * Use this when the plugin set must differ — typically because some plugins\n * (e.g. `browser-plugin`, `navigation-plugin`, `hash-plugin`) touch\n * `window.history` / `window.location` and cannot run on the server.\n */\nexport type RequestPluginsFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> = (request: Request | null) => readonly PluginFactory<TDeps>[];\n\nexport interface RealRouterFactoryOptions<\n TDeps extends DefaultDependencies = DefaultDependencies,\n> {\n /**\n * Base router instance — created once at app bootstrap (typically inside\n * `app.config.ts` module scope). Each request clones this router via\n * `cloneRouter(baseRouter, deps?.(request))`, producing an isolated\n * router with its own state, plugins, and subscriptions.\n *\n * **Important:** the `baseRouter` MUST NOT be started ahead of time —\n * `provideAppInitializer` is responsible for calling `router.start(url)`\n * inside the per-request DI scope.\n */\n baseRouter: Router<TDeps>;\n\n /**\n * Plugins applied to every per-request router clone.\n *\n * **Static form** — same plugins on both sides:\n * ```ts\n * plugins: [ssrDataPluginFactory(loaders)]\n * ```\n *\n * **Function form** — conditional client vs server (recommended when any\n * browser-only plugin is involved):\n * ```ts\n * plugins: (request) => request\n * ? [ssrDataPluginFactory(loaders)]\n * : [browserPluginFactory(), ssrDataPluginFactory(loaders)],\n * ```\n *\n * Function form is required if the plugin list contains\n * `browser-plugin`, `navigation-plugin`, or `hash-plugin` — those plugins\n * read `window.history` / `window.location` and crash on the server.\n */\n plugins?: readonly PluginFactory<TDeps>[] | RequestPluginsFactory<TDeps>;\n\n /**\n * Derive request-scoped deps (e.g. `currentUser` from cookies). The result\n * is passed to `cloneRouter(baseRouter, deps)` and merged with any deps\n * already registered on the base router.\n *\n * Receives `request: Request | null`:\n * - non-null on server (real `Request` from `@angular/ssr` runtime)\n * - non-null on SSG (mocked `Request` via `platformProviders`)\n * - null on client (derive deps externally — e.g. parse `document.cookie`)\n */\n deps?: RequestDepsFactory<TDeps>;\n\n /** Optional scroll restoration — same semantics as `provideRealRouter`. */\n scrollRestoration?: ScrollRestorationOptions;\n\n /** Optional scroll spy — same semantics as `provideRealRouter`. */\n scrollSpy?: ScrollSpyOptions;\n\n /** Optional view transitions — same semantics as `provideRealRouter`. */\n viewTransitions?: boolean;\n}\n\n/**\n * `provideRealRouterFactory` — environment providers for SSR / SSG scenarios.\n *\n * Unlike `provideRealRouter(router)` (single instance via `useValue`), this\n * factory uses `useFactory` to produce a per-request router clone:\n *\n * 1. Reads Angular's `REQUEST` token (`{ optional: true }`).\n * 2. Calls `cloneRouter(baseRouter, deps?.(request))` to create a request-scoped clone.\n * 3. Applies plugins (`plugins` array or `plugins(request)` factory).\n * 4. Registers `provideAppInitializer` that calls `await router.start(url)`.\n * 5. Schedules `router.dispose()` via `DestroyRef.onDestroy` — the request\n * Injector is destroyed after the response is sent, releasing all\n * subscriptions and plugins.\n *\n * Use cases:\n * - Angular SSR with `@angular/ssr` (`outputMode: \"server\"`).\n * - SSG build-time render via `renderApplication` + `platformProviders` `REQUEST` mock.\n * - Multi-tenant request-scoped routing.\n *\n * Existing single-instance scenarios (SPA, SSG client after hydration) continue\n * to use `provideRealRouter(router)` — both APIs ship in parallel.\n *\n * @param options - Factory configuration — see `RealRouterFactoryOptions`.\n * @returns `EnvironmentProviders` to spread into `ApplicationConfig.providers`.\n */\nexport function provideRealRouterFactory<\n TDeps extends DefaultDependencies = DefaultDependencies,\n>(options: RealRouterFactoryOptions<TDeps>): EnvironmentProviders {\n const {\n baseRouter,\n plugins,\n deps,\n scrollRestoration,\n scrollSpy,\n viewTransitions,\n } = options;\n\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n {\n provide: ROUTER,\n useFactory: (): Router => {\n const request = inject(REQUEST, { optional: true });\n const requestDeps = deps?.(request);\n const router = cloneRouter(baseRouter, requestDeps);\n\n const pluginList =\n typeof plugins === \"function\" ? plugins(request) : plugins;\n\n if (pluginList && pluginList.length > 0) {\n // Variadic — `usePlugin` accepts `(PluginFactory<D> | false | null | undefined)[]`.\n router.usePlugin(...pluginList);\n }\n\n // Per-request cleanup. The application Injector is destroyed:\n // - On server: after `writeResponseToNodeResponse` finishes the response\n // (request scope ends).\n // - On client: at `ApplicationRef.destroy` (rare in SPA, common in TestBed).\n // - In SSG build: after each `renderApplication` resolves.\n inject(DestroyRef).onDestroy(() => {\n router.dispose();\n });\n\n return router as unknown as Router;\n },\n },\n {\n provide: NAVIGATOR,\n useFactory: () => getNavigator(inject(ROUTER)),\n },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => {\n const router = inject(ROUTER);\n\n return {\n routeState: sourceToSignal(createRouteSource(router)),\n navigator: inject(NAVIGATOR),\n };\n },\n },\n // Async bootstrap — runs before the first component renders. Three\n // branches based on TransferState population:\n //\n // 1. **Client after hydration** — server populated TransferState with\n // the SSR-resolved router state. Consume it via `hydrateRouter`,\n // which deposits the parsed state into the one-shot\n // `RouterInternals.hydrationState` scratchpad before invoking\n // `router.start(state.path)`. SSR loader plugins\n // (`@real-router/ssr-data-plugin`, `@real-router/rsc-server-plugin`)\n // read the scratchpad and skip the loader on first paint — parity\n // with the other 5 adapters that consume `<script>__SSR_STATE__</script>` (#596, #599).\n //\n // 2. **Server / SSG** — TransferState empty; run the regular\n // `router.start(path)`. After it resolves, write the serialized\n // state back into TransferState so the matching client run lands\n // in branch 1. Angular's `TransferState` infrastructure\n // (provided by `provideClientHydration()`) carries this blob to\n // the client as a `<script id=\"ng-state\">` payload.\n //\n // 3. **Pure CSR** — TransferState empty (never populated by a server\n // pass), and `inject(REQUEST, { optional: true })` returns null.\n // Falls into the same `router.start(path)` branch as server-side\n // but skips the TransferState write (no client to hand off to).\n //\n // Errors propagate (Option A from RFC §10): the bootstrap fails and the\n // server returns 500. Custom error pages should be wired via\n // `RouterErrorBoundary` on subsequent renders.\n provideAppInitializer(async () => {\n const router = inject(ROUTER);\n const request = inject(REQUEST, { optional: true });\n const transferState = inject(TransferState);\n\n const ssrJson = transferState.get(ROUTER_STATE_KEY, null);\n\n if (ssrJson !== null) {\n // Branch 1: client after hydration — reuse server-resolved state.\n await hydrateRouter(router, ssrJson);\n // One-shot semantic, parity with `delete window.__SSR_STATE__`.\n transferState.remove(ROUTER_STATE_KEY);\n\n return;\n }\n\n // Branches 2 & 3: regular start.\n // Browser-plugin's `start` interceptor (when registered) wraps this call\n // with location-derived path. We always pass an explicit string — the\n // interceptor uses the explicit value because `next(path ?? location)`\n // short-circuits when `path` is non-nullish.\n const path = deriveStartPath(request);\n const state = await router.start(path);\n\n if (request !== null) {\n // Branch 2: running inside `@angular/ssr`'s request handler — write\n // serialized state to TransferState so the matching client run can\n // skip the loader on first paint.\n transferState.set(ROUTER_STATE_KEY, serializeRouterState(state));\n }\n }),\n ];\n\n if (scrollRestoration) {\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollRestoration(scrollRestoration);\n }),\n );\n }\n\n if (scrollSpy && scrollSpy.selector !== \"\") {\n providers.push(\n provideEnvironmentInitializer(() => {\n installScrollSpy(scrollSpy);\n }),\n );\n }\n\n if (viewTransitions === true) {\n providers.push(provideEnvironmentInitializer(installViewTransitions));\n }\n\n return makeEnvironmentProviders(providers);\n}\n\n/**\n * Derive the path passed to `router.start(path)`:\n * - Server / SSG: `request.url` → pathname + search.\n * - Client: `window.location` if available.\n * - Fallback: `\"/\"` (only reachable in synthetic non-browser non-SSR setups).\n */\nfunction deriveStartPath(request: Request | null): string {\n if (request) {\n const url = new URL(request.url);\n\n return url.pathname + url.search;\n }\n\n if (typeof globalThis.window !== \"undefined\") {\n return globalThis.location.pathname + globalThis.location.search;\n }\n\n return \"/\";\n}\n","import { inject } from \"@angular/core\";\n\nimport type { InjectionToken } from \"@angular/core\";\n\nexport function injectOrThrow<T>(token: InjectionToken<T>, fnName: string): T {\n const value = inject(token, { optional: true });\n\n // Explicit null / undefined check — falsy guard would misfire on\n // legitimately falsy values (`0`, `\"\"`, `false`) if the token were ever\n // typed for primitives. Today all our tokens hold object instances, but\n // pinning the check keeps the function safe for future typing changes.\n if (value === null || value === undefined) {\n throw new Error(\n `${fnName} must be used within a provideRealRouter context`,\n );\n }\n\n return value;\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTER } from \"../providers\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport function injectRouter(): Router {\n assertInInjectionContext(injectRouter);\n\n return injectOrThrow(ROUTER, \"injectRouter\");\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { NAVIGATOR } from \"../providers\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport function injectNavigator(): Navigator {\n assertInInjectionContext(injectNavigator);\n\n return injectOrThrow(NAVIGATOR, \"injectNavigator\");\n}\n","import { assertInInjectionContext } from \"@angular/core\";\n\nimport { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTE } from \"../providers\";\n\nimport type { RouteSignals } from \"../types\";\nimport type { Signal } from \"@angular/core\";\nimport type { Params, State } from \"@real-router/core\";\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\ntype NonNullRouteSignals<P extends Params> = Omit<\n RouteSignals<P>,\n \"routeState\"\n> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n};\n\nexport function injectRoute<\n P extends Params = Params,\n>(): NonNullRouteSignals<P> {\n assertInInjectionContext(injectRoute);\n\n const signals = injectOrThrow(ROUTE, \"injectRoute\") as RouteSignals<P>;\n\n // Read the snapshot once: the signal is reactive, but the throw-guard\n // and any future use of the snapshot within this call should observe the\n // SAME value to avoid races.\n const snapshot = signals.routeState();\n\n if (!snapshot.route) {\n throw new Error(\n \"injectRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?\",\n );\n }\n\n return signals as NonNullRouteSignals<P>;\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteSignals } from \"../types\";\n\nexport function injectRouteNode(nodeName: string): RouteSignals {\n assertInInjectionContext(injectRouteNode);\n\n const router = injectRouter();\n const navigator = getNavigator(router);\n const source = createRouteNodeSource(router, nodeName);\n const routeState = sourceToSignal(source);\n\n return { routeState, navigator };\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\nexport function injectRouteUtils(): RouteUtils {\n assertInInjectionContext(injectRouteUtils);\n\n const router = injectRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { getTransitionSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function injectRouterTransition(): Signal<RouterTransitionSnapshot> {\n assertInInjectionContext(injectRouterTransition);\n\n const router = injectRouter();\n const source = getTransitionSource(router);\n\n return sourceToSignal(source);\n}\n","import type { ActiveRouteSourceOptions } from \"@real-router/sources\";\n\n/**\n * Build the `options` literal for `createActiveRouteSource` while honoring\n * `exactOptionalPropertyTypes` — the type forbids passing `{ hash: undefined }`\n * literally (#532), so callers must conditionally include the `hash` key only\n * when a value was provided.\n *\n * Used by `RealLink`, `RealLinkActive`, and `injectIsActiveRoute` — extracted\n * from three identical ternaries (review-2026-05-16 §8a LOW).\n */\nexport function buildActiveRouteOptions(\n strict: boolean,\n ignoreQueryParams: boolean,\n hash: string | undefined,\n): ActiveRouteSourceOptions {\n return hash === undefined\n ? { strict, ignoreQueryParams }\n : { strict, ignoreQueryParams, hash };\n}\n","import { assertInInjectionContext } from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { Params } from \"@real-router/core\";\n\nexport function injectIsActiveRoute(\n routeName: string,\n params?: Params,\n options?: { strict?: boolean; ignoreQueryParams?: boolean; hash?: string },\n): Signal<boolean> {\n assertInInjectionContext(injectIsActiveRoute);\n\n const router = injectRouter();\n const source = createActiveRouteSource(\n router,\n routeName,\n params,\n buildActiveRouteOptions(\n options?.strict ?? false,\n options?.ignoreQueryParams ?? true,\n options?.hash,\n ),\n );\n\n return sourceToSignal(source);\n}\n","import { DestroyRef, assertInInjectionContext, inject } from \"@angular/core\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteExitContext {\n /** The route being left. */\n route: State;\n /** The route being navigated to. */\n nextRoute: State;\n /**\n * AbortSignal that fires when this navigation is superseded by a later\n * one (rapid clicks). Already filtered: when the handler runs,\n * `signal.aborted` is guaranteed to be `false`. Use\n * `signal.addEventListener(\"abort\", cleanup, { once: true })` for\n * cleanup that must run on cancellation.\n */\n signal: AbortSignal;\n}\n\nexport interface UseRouteExitOptions {\n /**\n * Skip the handler when `route.name === nextRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`.\n */\n skipSameRoute?: boolean;\n}\n\nexport type RouteExitHandler = (\n context: RouteExitContext,\n) => void | Promise<void>;\n\n/**\n * Subscribe to the router's leave-window with the universal guards baked\n * in. Wraps `router.subscribeLeave` so consumers don't repeat the same\n * boilerplate every time:\n *\n * - **Reentrant abort pre-check**: if `signal.aborted` is already `true`\n * when the handler would run (rapid navigation superseded a slower\n * one), the handler is skipped entirely.\n * - **Same-route skip**: by default, `route.name === nextRoute.name`\n * short-circuits the handler — query-only navigations skip the work.\n * Opt out with `skipSameRoute: false`.\n *\n * Cleanup is bound to the injection context's `DestroyRef`. Must be\n * called within an injection context (constructor, field initializer,\n * or `runInInjectionContext`).\n *\n * If the handler returns a Promise, the router blocks on it. If the\n * Promise resolves, navigation proceeds. If it rejects, the router emits\n * `TRANSITION_CANCELLED`.\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method\n * (`this.onExit.bind(this)` or an arrow-property) — its identity is\n * stable across change detection. To vary behavior over time, read\n * signals **inside** the handler body — do not rely on swapping the\n * handler reference.\n *\n * @example Animation\n * ```ts\n * \\@Component({ ... })\n * class FadeOutComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteExit(async ({ signal }) => {\n * const el = this.el.nativeElement;\n * el.classList.add(\"fade-out\");\n * const cleanup = () => el.classList.remove(\"fade-out\");\n * signal.addEventListener(\"abort\", cleanup, { once: true });\n * try {\n * el.getBoundingClientRect();\n * await Promise.allSettled(el.getAnimations().map((a) => a.finished));\n * } finally {\n * cleanup();\n * }\n * });\n * }\n * }\n * ```\n *\n * @example Auto-save form draft\n * ```ts\n * injectRouteExit(async ({ signal }) => {\n * if (this.formState.dirty) {\n * await this.api.saveDraft(this.formState, { signal });\n * }\n * });\n * ```\n */\nexport function injectRouteExit(\n handler: RouteExitHandler,\n options?: UseRouteExitOptions,\n): void {\n assertInInjectionContext(injectRouteExit);\n\n const router = injectRouter();\n const destroyRef = inject(DestroyRef);\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n const off = router.subscribeLeave(({ route, nextRoute, signal }) => {\n if (skipSameRoute && route.name === nextRoute.name) {\n return;\n }\n\n if (signal.aborted) {\n return;\n }\n\n return handler({ route, nextRoute, signal });\n });\n\n destroyRef.onDestroy(off);\n}\n","import { assertInInjectionContext, effect } from \"@angular/core\";\n\nimport { injectRoute } from \"./injectRoute\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteEnterContext {\n /** The route that was just activated. */\n route: State;\n /** The route that was active immediately before this navigation. */\n previousRoute: State;\n}\n\nexport type RouteEnterHandler = (context: RouteEnterContext) => void;\n\nexport interface UseRouteEnterOptions {\n /**\n * Skip the handler when `route.name === previousRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`. Symmetric with `injectRouteExit`'s same-name option.\n */\n skipSameRoute?: boolean;\n}\n\n/**\n * Fire `handler` once when the component is created as a result of a\n * navigation. Mirror of `injectRouteExit` for the entry side.\n *\n * What this function covers that an ad-hoc `effect()` + `injectRoute()`\n * doesn't:\n *\n * - **Skip-initial**: handler is skipped when there is no\n * `route.transition.from` (i.e. first-load mount). Most consumers\n * want to fire side effects only on real navigations, not on\n * hydration.\n * - **Same-route skip** (default): handler is skipped when\n * `route.transition.from === route.name`. Sort/filter/query-only\n * navigations re-run the effect (because the `route` reference\n * changes), but they are not \"entries\" in the animation / analytics\n * sense. Opt out with `skipSameRoute: false`.\n * - **Mount-time `route` / `previousRoute` snapshot**: handler receives\n * the values that were live at the moment of effect activation.\n *\n * Effect cleanup is wired through the injection context's `DestroyRef`\n * (Angular's `effect()` ties into the active context automatically).\n * Must be called within an injection context (constructor, field\n * initializer, or `runInInjectionContext`).\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method —\n * its identity is stable across change detection. To vary behavior\n * over time, read signals **inside** the handler body.\n *\n * @example Direction-aware entry animation\n * ```ts\n * \\@Component({ ... })\n * class PageComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteEnter(({ route }) => {\n * const direction = route.context.browser?.direction;\n * this.el.nativeElement.classList.add(\n * direction === \"back\" ? \"slide-from-left\" : \"slide-from-right\",\n * );\n * });\n * }\n * }\n * ```\n *\n * @example Analytics page-enter event (skip-initial built-in)\n * ```ts\n * injectRouteEnter(({ route, previousRoute }) => {\n * analytics.track(\"page_enter\", {\n * route: route.name,\n * from: previousRoute.name,\n * });\n * });\n * ```\n */\nexport function injectRouteEnter(\n handler: RouteEnterHandler,\n options?: UseRouteEnterOptions,\n): void {\n assertInInjectionContext(injectRouteEnter);\n\n const { routeState } = injectRoute();\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n effect(() => {\n const { route, previousRoute } = routeState();\n\n // Early-exit guards, top-down:\n //\n // - **Skip-initial**: `state.transition.from` is undefined only\n // for the very first state committed by `router.start()`.\n // - **Skip-same-route**: query-only navigations have\n // `transition.from === route.name`. Opt-out via\n // `skipSameRoute: false`.\n if (!route.transition.from) {\n return;\n }\n if (skipSameRoute && route.transition.from === route.name) {\n return;\n }\n // `previousRoute` is guaranteed populated whenever `route.transition.from`\n // is set — core writes them together. The dead-code throw-guard that used\n // to live here (review §8a LOW) is removed; the narrowing below is the\n // type-safe equivalent and avoids the no-non-null-assertion lint.\n if (!previousRoute) {\n return;\n }\n\n handler({ route, previousRoute });\n });\n}\n","import { Directive, TemplateRef, inject, input } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeMatch]\" })\nexport class RouteMatch {\n readonly routeMatch = input.required<string>();\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeNotFound]\" })\nexport class RouteNotFound {\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeSelf]\" })\nexport class RouteSelf {\n readonly templateRef = inject(TemplateRef);\n}\n","import type { RouterSource } from \"@real-router/sources\";\n\n/**\n * Subscribe a `RouterSource<T>` to a write-callback and return a cleanup\n * function. The shape is the per-effect-run pattern that `RealLink`,\n * `RealLinkActive`, and `RouteView` all share inside their constructor\n * `effect(...)` (review-2026-05-16 §8a MEDIUM — identical 8-line block\n * repeated in 3 directives):\n *\n * 1. Read initial snapshot and apply it via `onSnapshot(snap)`.\n * 2. Subscribe — every subsequent emission calls `onSnapshot(snap)` again.\n * 3. Return a cleanup that unsubscribes and destroys the source. For\n * cached factories from `@real-router/sources` (`createActiveRouteSource`,\n * `createRouteNodeSource`, `getTransitionSource`, `getErrorSource`,\n * `createDismissableError`) `destroy()` is a no-op on the shared\n * wrapper, so this helper is safe to invoke from rapid effect re-runs\n * under signal-input changes.\n *\n * Callers pass the result to `onCleanup(...)` from Angular's `effect()`.\n *\n * @example\n * ```ts\n * effect((onCleanup) => {\n * const source = createActiveRouteSource(router, routeName(), params());\n * onCleanup(\n * subscribeSourceToSignal(source, (snap) => {\n * this.isActive.set(snap);\n * this.updateDom();\n * }),\n * );\n * });\n * ```\n */\nexport function subscribeSourceToSignal<T>(\n source: RouterSource<T>,\n onSnapshot: (snapshot: T) => void,\n): () => void {\n onSnapshot(source.getSnapshot());\n\n const unsub = source.subscribe(() => {\n onSnapshot(source.getSnapshot());\n });\n\n return () => {\n unsub();\n source.destroy();\n };\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n Component,\n computed,\n contentChildren,\n effect,\n input,\n signal,\n type TemplateRef,\n} from \"@angular/core\";\nimport { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { RouteMatch } from \"../directives/RouteMatch\";\nimport { RouteNotFound } from \"../directives/RouteNotFound\";\nimport { RouteSelf } from \"../directives/RouteSelf\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nconst EMPTY_SNAPSHOT: RouteSnapshot = {\n route: undefined,\n previousRoute: undefined,\n};\n\n@Component({\n selector: \"route-view\",\n template: `\n @if (activeTemplate()) {\n <ng-container [ngTemplateOutlet]=\"activeTemplate()!\" />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouteView {\n readonly nodeName = input<string>(\"\", { alias: \"routeNode\" });\n\n readonly matches = contentChildren(RouteMatch, { descendants: true });\n readonly selfs = contentChildren(RouteSelf, { descendants: true });\n readonly notFounds = contentChildren(RouteNotFound, { descendants: true });\n\n readonly activeTemplate = computed<TemplateRef<unknown> | null>(\n () => this.matchedTemplate() ?? this.fallbackTemplate(),\n );\n\n private readonly router = injectRouter();\n private readonly routeState = signal<RouteSnapshot>(EMPTY_SNAPSHOT);\n\n private readonly matchEntries = computed(() => {\n const nodeName = this.nodeName();\n\n return this.matches().map((match) => {\n const segment = match.routeMatch();\n\n return {\n match,\n fullSegmentName: nodeName ? `${nodeName}.${segment}` : segment,\n };\n });\n });\n\n // The matched template (Match priority) is independent of the Self /\n // NotFound fallback chain. Splitting the two paths into separate computeds\n // localises re-runs: a change to `selfs()` / `notFounds()` no longer\n // re-evaluates the Match loop (review §8a LOW — RouteView activeTemplate\n // split).\n private readonly matchedTemplate = computed<TemplateRef<unknown> | null>(\n () => {\n const route = this.routeState().route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n\n for (const { match, fullSegmentName } of this.matchEntries()) {\n if (startsWithSegment(routeName, fullSegmentName)) {\n return match.templateRef;\n }\n }\n\n return null;\n },\n );\n\n // Fallback chain — only consulted when `matchedTemplate()` returned `null`.\n // Template priority: Self → NotFound. Selection rules differ on purpose:\n // - **Self uses first-wins** (`.at(0)`) for parity with React / Preact /\n // Solid / Vue, where the first matching `<Self>` token in declaration\n // order wins.\n // - **NotFound uses last-wins** (`.at(-1)`) intentionally — the fallback\n // should be the most-recently-declared template so that consumers can\n // override an inherited `<ng-template routeNotFound>` simply by\n // re-declaring it lower in the projected content.\n private readonly fallbackTemplate = computed<TemplateRef<unknown> | null>(\n () => {\n const route = this.routeState().route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n\n if (routeName === this.nodeName()) {\n const first = this.selfs().at(0);\n\n if (first) {\n return first.templateRef;\n }\n }\n\n if (routeName === UNKNOWN_ROUTE) {\n const last = this.notFounds().at(-1);\n\n if (last) {\n return last.templateRef;\n }\n }\n\n return null;\n },\n );\n\n constructor() {\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n effect((onCleanup) => {\n const source = createRouteNodeSource(this.router, this.nodeName());\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n this.routeState.set(snap);\n }),\n );\n });\n }\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport { Component, computed, effect, input, output } from \"@angular/core\";\nimport { createDismissableError } from \"@real-router/sources\";\n\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { sourceToSignal } from \"../sourceToSignal\";\n\nimport type { ErrorContext } from \"../types\";\nimport type { TemplateRef } from \"@angular/core\";\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { DismissableErrorSnapshot } from \"@real-router/sources\";\n\n@Component({\n selector: \"router-error-boundary\",\n template: `\n <ng-content />\n @if (errorContext() && errorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"errorTemplate()!\"\n [ngTemplateOutletContext]=\"errorContext()!\"\n />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouterErrorBoundary {\n readonly errorTemplate = input<TemplateRef<ErrorContext>>();\n\n readonly onError = output<{\n error: RouterError;\n toRoute: State | null;\n fromRoute: State | null;\n }>();\n\n readonly errorContext = computed<ErrorContext | null>(() => {\n const snap = this.snapshot();\n\n if (!snap.error) {\n return null;\n }\n\n return {\n $implicit: snap.error,\n resetError: snap.resetError,\n };\n });\n\n private readonly router = injectRouter();\n private readonly snapshot = sourceToSignal<DismissableErrorSnapshot>(\n createDismissableError(this.router),\n );\n\n constructor() {\n // `effect()` registers itself with the current injection context's\n // `DestroyRef` and tears down automatically when the component is\n // destroyed. The earlier manual `effectRef.destroy()` wired through\n // `inject(DestroyRef).onDestroy(...)` duplicated that built-in cleanup\n // (audit §8.1 LOW — confirmed: no behavior change without the manual\n // path).\n effect(() => {\n const snap = this.snapshot();\n\n if (snap.error) {\n this.onError.emit({\n error: snap.error,\n toRoute: snap.toRoute,\n fromRoute: snap.fromRoute,\n });\n }\n });\n }\n}\n","import { Component, inject, DestroyRef } from \"@angular/core\";\n\nimport { createRouteAnnouncer } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\n@Component({\n selector: \"navigation-announcer\",\n template: \"\",\n})\nexport class NavigationAnnouncer {\n private readonly announcer = createRouteAnnouncer(injectRouter());\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.announcer.destroy();\n });\n }\n}\n","import {\n Directive,\n ElementRef,\n computed,\n effect,\n inject,\n input,\n signal,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildHref, navigateWithHash, shouldNavigate } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { Params, NavigationOptions } from \"@real-router/core\";\n\nconst NOOP_CATCH = (): void => {};\n\n@Directive({\n selector: \"a[realLink]\",\n host: {\n \"(click)\": \"onClick($event)\",\n },\n})\nexport class RealLink {\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly routeOptions = input<NavigationOptions>({});\n readonly activeClassName = input<string>(\"active\");\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n /**\n * URL fragment (decoded form, no leading \"#\") (#532).\n * - omitted/`undefined` → preserve current fragment on same-route navigation\n * - `\"\"` → clear fragment\n * - non-empty → set fragment\n */\n readonly hash = input<string | undefined>(undefined);\n\n private readonly router = injectRouter();\n private readonly anchor = inject(ElementRef)\n .nativeElement as HTMLAnchorElement;\n private readonly isActive = signal(false);\n // `href` is computed from signal inputs only — Angular's default Object.is\n // equality already collapses repeated `string` results, so no custom\n // comparator is required (review §8b note 3 — applies after verifying that\n // `buildHref` returns a primitive).\n private readonly href = computed(() => {\n const hashValue = this.hash();\n\n return buildHref(\n this.router,\n this.routeName(),\n this.routeParams(),\n hashValue === undefined ? undefined : { hash: hashValue },\n );\n });\n private prevActiveClass = \"\";\n private prevHref: string | undefined = undefined;\n // Skip-same-value: only re-touch the DOM `class` list when the active state\n // actually flipped. Without this, every navigation that re-fires the active\n // source still issues a `classList.toggle` no-op (review §8b MEDIUM).\n private prevActive: boolean | undefined = undefined;\n\n constructor() {\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n // Reading signal inputs inside `effect()` re-creates the active-route\n // source whenever any input changes; `onCleanup` tears the previous\n // subscription down.\n effect((onCleanup) => {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n buildActiveRouteOptions(\n this.activeStrict(),\n this.ignoreQueryParams(),\n this.hash(),\n ),\n );\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n // Pure-href refresh: when the active flag did not change, only the\n // href may have moved (e.g. param-only update on a parent route).\n // Skip the classList work in that branch (review §8b MEDIUM).\n if (snap === this.prevActive) {\n this.isActive.set(snap);\n this.updateHref();\n\n return;\n }\n\n this.prevActive = snap;\n this.isActive.set(snap);\n this.updateHref();\n this.updateActiveClass();\n }),\n );\n });\n }\n\n onClick(event: MouseEvent): void {\n if (!shouldNavigate(event) || this.anchor.target === \"_blank\") {\n return;\n }\n\n event.preventDefault();\n navigateWithHash(\n this.router,\n this.routeName(),\n this.routeParams(),\n this.hash(),\n this.routeOptions(),\n ).catch(NOOP_CATCH);\n }\n\n private updateHref(): void {\n const href = this.href();\n\n if (href !== undefined && href !== this.prevHref) {\n this.anchor.setAttribute(\"href\", href);\n }\n\n this.prevHref = href;\n }\n\n private updateActiveClass(): void {\n const activeClass = this.activeClassName();\n\n if (this.prevActiveClass && this.prevActiveClass !== activeClass) {\n this.anchor.classList.remove(this.prevActiveClass);\n }\n\n if (activeClass) {\n this.anchor.classList.toggle(activeClass, this.isActive());\n }\n\n this.prevActiveClass = activeClass;\n }\n}\n","import {\n Directive,\n ElementRef,\n effect,\n inject,\n input,\n signal,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { applyLinkA11y } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { buildActiveRouteOptions } from \"../internal/buildActiveRouteOptions\";\nimport { subscribeSourceToSignal } from \"../internal/subscribeSourceToSignal\";\n\nimport type { Params } from \"@real-router/core\";\n\n@Directive({ selector: \"[realLinkActive]\" })\nexport class RealLinkActive {\n readonly realLinkActive = input<string>(\"\");\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n\n private readonly router = injectRouter();\n private readonly element = inject(ElementRef).nativeElement as HTMLElement;\n private readonly isActive = signal(false);\n // Skip-same-value: only touch `classList.toggle` when the active flag\n // actually flipped. Saves one DOM write per RealLinkActive per unrelated\n // navigation (review §8b MEDIUM).\n private prevActive: boolean | undefined = undefined;\n\n constructor() {\n // One-time a11y setup — doesn't depend on signal inputs, stays in\n // constructor body. `applyLinkA11y` is idempotent so re-running would\n // be safe, but we only need it once per element.\n applyLinkA11y(this.element);\n\n // Reactive source-creation effect (#630 fix) — see\n // `packages/angular/CLAUDE.md` → \"Directives use constructor + effect()\".\n effect((onCleanup) => {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n buildActiveRouteOptions(\n this.activeStrict(),\n this.ignoreQueryParams(),\n undefined,\n ),\n );\n\n onCleanup(\n subscribeSourceToSignal(source, (snap) => {\n if (snap === this.prevActive) {\n return;\n }\n\n this.prevActive = snap;\n this.isActive.set(snap);\n this.updateClass();\n }),\n );\n });\n }\n\n private updateClass(): void {\n const className = this.realLinkActive();\n\n if (!className) {\n return;\n }\n\n this.element.classList.toggle(className, this.isActive());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NOOP_INSTANCE"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-router/angular",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "type": "commonjs",
5
5
  "description": "Angular 21 integration for Real-Router",
6
6
  "exports": {
@@ -40,17 +40,17 @@
40
40
  "license": "MIT",
41
41
  "sideEffects": false,
42
42
  "dependencies": {
43
- "@real-router/core": "^0.56.0",
43
+ "@real-router/core": "^0.57.0",
44
44
  "@real-router/route-utils": "^0.2.3",
45
- "@real-router/sources": "^0.8.5"
45
+ "@real-router/sources": "^0.8.6"
46
46
  },
47
47
  "devDependencies": {
48
- "@analogjs/vitest-angular": "2.6.0",
49
- "@angular/common": "21.2.13",
50
- "@angular/compiler": "21.2.13",
51
- "@angular/compiler-cli": "21.2.13",
52
- "@angular/core": "21.2.13",
53
- "@angular/platform-browser": "21.2.13",
48
+ "@analogjs/vitest-angular": "2.6.1",
49
+ "@angular/common": "21.2.17",
50
+ "@angular/compiler": "21.2.17",
51
+ "@angular/compiler-cli": "21.2.17",
52
+ "@angular/core": "21.2.17",
53
+ "@angular/platform-browser": "21.2.17",
54
54
  "ng-packagr": "21.2.3",
55
55
  "typescript": "6.0.3"
56
56
  },