@real-router/solid 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +170 -15
  2. package/dist/cjs/index.d.ts +20 -1
  3. package/dist/cjs/index.js +0 -0
  4. package/dist/cjs/ssr.d.ts +163 -0
  5. package/dist/cjs/ssr.js +263 -0
  6. package/dist/esm/index.d.mts +20 -1
  7. package/dist/esm/index.mjs +0 -0
  8. package/dist/esm/ssr.d.mts +163 -0
  9. package/dist/esm/ssr.mjs +254 -0
  10. package/dist/types/RouterProvider.d.ts.map +1 -1
  11. package/dist/types/components/Await.d.ts +30 -0
  12. package/dist/types/components/Await.d.ts.map +1 -0
  13. package/dist/types/components/ClientOnly.d.ts +7 -0
  14. package/dist/types/components/ClientOnly.d.ts.map +1 -0
  15. package/dist/types/components/HttpStatusCode.d.ts +52 -0
  16. package/dist/types/components/HttpStatusCode.d.ts.map +1 -0
  17. package/dist/types/components/HttpStatusProvider.d.ts +9 -0
  18. package/dist/types/components/HttpStatusProvider.d.ts.map +1 -0
  19. package/dist/types/components/Link.d.ts.map +1 -1
  20. package/dist/types/components/RouteView/RouteView.d.ts.map +1 -1
  21. package/dist/types/components/RouteView/components.d.ts.map +1 -1
  22. package/dist/types/components/RouteView/helpers.d.ts.map +1 -1
  23. package/dist/types/components/ServerOnly.d.ts +7 -0
  24. package/dist/types/components/ServerOnly.d.ts.map +1 -0
  25. package/dist/types/components/Streamed.d.ts +18 -0
  26. package/dist/types/components/Streamed.d.ts.map +1 -0
  27. package/dist/types/constants.d.ts +20 -2
  28. package/dist/types/constants.d.ts.map +1 -1
  29. package/dist/types/context.d.ts +9 -0
  30. package/dist/types/context.d.ts.map +1 -1
  31. package/dist/types/createSignalFromSource.d.ts.map +1 -1
  32. package/dist/types/createStoreFromSource.d.ts +19 -0
  33. package/dist/types/createStoreFromSource.d.ts.map +1 -1
  34. package/dist/types/directives/link.d.ts.map +1 -1
  35. package/dist/types/dom-utils/__test-helpers/expected-fragment.d.ts +31 -0
  36. package/dist/types/dom-utils/__test-helpers/expected-fragment.d.ts.map +1 -0
  37. package/dist/types/dom-utils/__test-helpers/index.d.ts +9 -0
  38. package/dist/types/dom-utils/__test-helpers/index.d.ts.map +1 -0
  39. package/dist/types/dom-utils/link-utils.d.ts +23 -0
  40. package/dist/types/dom-utils/link-utils.d.ts.map +1 -1
  41. package/dist/types/dom-utils/route-announcer.d.ts.map +1 -1
  42. package/dist/types/dom-utils/scroll-restore.d.ts +38 -1
  43. package/dist/types/dom-utils/scroll-restore.d.ts.map +1 -1
  44. package/dist/types/hooks/useDeferred.d.ts +16 -0
  45. package/dist/types/hooks/useDeferred.d.ts.map +1 -0
  46. package/dist/types/hooks/useNavigator.d.ts.map +1 -1
  47. package/dist/types/hooks/useRouteUtils.d.ts.map +1 -1
  48. package/dist/types/hooks/useRouter.d.ts.map +1 -1
  49. package/dist/types/index.d.ts +1 -0
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/types/ssr.d.ts +16 -0
  52. package/dist/types/ssr.d.ts.map +1 -0
  53. package/dist/types/utils/createHttpStatusSink.d.ts +29 -0
  54. package/dist/types/utils/createHttpStatusSink.d.ts.map +1 -0
  55. package/dist/types/utils/createMountedSignal.d.ts +16 -0
  56. package/dist/types/utils/createMountedSignal.d.ts.map +1 -0
  57. package/package.json +21 -5
  58. package/src/RouterProvider.tsx +36 -30
  59. package/src/components/Await.tsx +56 -0
  60. package/src/components/ClientOnly.tsx +20 -0
  61. package/src/components/HttpStatusCode.tsx +65 -0
  62. package/src/components/HttpStatusProvider.tsx +21 -0
  63. package/src/components/Link.tsx +21 -15
  64. package/src/components/RouteView/RouteView.tsx +19 -18
  65. package/src/components/RouteView/components.tsx +34 -28
  66. package/src/components/RouteView/helpers.tsx +0 -0
  67. package/src/components/ServerOnly.tsx +20 -0
  68. package/src/components/Streamed.tsx +23 -0
  69. package/src/constants.ts +20 -2
  70. package/src/context.ts +21 -1
  71. package/src/createSignalFromSource.ts +48 -5
  72. package/src/createStoreFromSource.ts +49 -2
  73. package/src/directives/link.tsx +41 -16
  74. package/src/hooks/useDeferred.tsx +36 -0
  75. package/src/hooks/useNavigator.tsx +3 -12
  76. package/src/hooks/useRouteUtils.tsx +39 -1
  77. package/src/hooks/useRouter.tsx +3 -12
  78. package/src/index.tsx +2 -0
  79. package/src/ssr.tsx +39 -0
  80. package/src/utils/createHttpStatusSink.ts +31 -0
  81. package/src/utils/createMountedSignal.ts +26 -0
@@ -0,0 +1,254 @@
1
+ import { createComponent } from 'solid-js/web';
2
+ import { createSignal, onMount, Show, createContext, useContext, createResource, Suspense } from 'solid-js';
3
+
4
+ /**
5
+ * Returns a boolean accessor that is `false` during initial render (SSR
6
+ * and the first client paint) and flips to `true` once the component
7
+ * has mounted in the browser.
8
+ *
9
+ * Solid guarantees that `onMount` does NOT fire during `renderToString` /
10
+ * `renderToStream`, so the accessor stays `false` server-side — this is
11
+ * the building block for SSR boundary components (`<ClientOnly>` /
12
+ * `<ServerOnly>`).
13
+ *
14
+ * Consolidates the identical `createSignal(false) + onMount(setMounted)`
15
+ * pattern across the two boundary components (§8a Q15).
16
+ */
17
+ function createMountedSignal() {
18
+ const [mounted, setMounted] = createSignal(false);
19
+ onMount(() => {
20
+ setMounted(true);
21
+ });
22
+ return mounted;
23
+ }
24
+
25
+ function ClientOnly(props) {
26
+ const mounted = createMountedSignal();
27
+ return createComponent(Show, {
28
+ get when() {
29
+ return mounted();
30
+ },
31
+ get fallback() {
32
+ return props.fallback;
33
+ },
34
+ get children() {
35
+ return props.children;
36
+ }
37
+ });
38
+ }
39
+
40
+ function ServerOnly(props) {
41
+ const mounted = createMountedSignal();
42
+ return createComponent(Show, {
43
+ get when() {
44
+ return mounted();
45
+ },
46
+ get fallback() {
47
+ return props.children;
48
+ },
49
+ get children() {
50
+ return props.fallback;
51
+ }
52
+ });
53
+ }
54
+
55
+ createContext(null);
56
+ const RouteContext = createContext(null);
57
+
58
+ const useRoute = () => {
59
+ const routeSignal = useContext(RouteContext);
60
+ if (!routeSignal) {
61
+ throw new Error("useRoute must be used within a RouterProvider");
62
+ }
63
+ if (!routeSignal().route) {
64
+ throw new Error("useRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?");
65
+ }
66
+ return routeSignal;
67
+ };
68
+
69
+ const NEVER_PROMISE = new Promise(() => {
70
+ // Intentionally never resolves — surfaces a forever-pending Suspense boundary
71
+ // when a key is requested that the loader never declared.
72
+ });
73
+
74
+ /**
75
+ * Read a deferred promise published by `defer({ deferred: { <key>: Promise } })`
76
+ * inside an SSR data loader.
77
+ *
78
+ * Returns a Solid `Accessor<Promise<T>>` so the value tracks the active route
79
+ * — re-reading on navigation picks up the new state's deferred map. Wrap with
80
+ * `<Await name="key">{(value) => …}</Await>` (this package), which builds on
81
+ * `createResource` + `<Suspense>` for native Solid streaming.
82
+ *
83
+ * Returns a forever-pending promise when the key is missing — surfaces
84
+ * loader/consumer key drift as a visible Suspense fallback rather than a
85
+ * silent runtime error.
86
+ */
87
+ function useDeferred(key) {
88
+ const routeAccessor = useRoute();
89
+ return () => {
90
+ const context = routeAccessor().route.context;
91
+ const deferred = context.ssrDataDeferred;
92
+ return deferred?.[key] ?? NEVER_PROMISE;
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Reads `useDeferred(name)` and hands the resolved value to the render-prop.
98
+ * Wraps the deferred promise in `createResource` so Solid's reactivity tracks
99
+ * resolution and `<Suspense>` gets the standard suspend signal.
100
+ *
101
+ * ```tsx
102
+ * <Streamed fallback={<Spinner />}>
103
+ * <Await<Review[]> name="reviews">
104
+ * {(reviews) => <ReviewList items={reviews} />}
105
+ * </Await>
106
+ * </Streamed>
107
+ * ```
108
+ *
109
+ * Implementation: returns a Solid accessor (function child) that reads
110
+ * `resource()` — this both (a) triggers `<Suspense>` suspension while pending
111
+ * and (b) re-throws on `errored` for the nearest `<ErrorBoundary>` to catch.
112
+ * The render-prop is gated on `resource.state === "ready"` rather than on
113
+ * truthiness so falsy resolved values (`0`, `false`, `null`, `""`) still
114
+ * reach `props.children`.
115
+ */
116
+ function Await(props) {
117
+ const promiseAccessor = useDeferred(props.name);
118
+ const [resource] = createResource(promiseAccessor, promise => promise);
119
+
120
+ // The double cast `as unknown as JSX.Element` (audit-2026-05-17 §8a) is
121
+ // load-bearing: this returns a Solid accessor *function*, not an element
122
+ // node. `JSX.Element` in Solid is a union that includes function-as-child
123
+ // for reactive bindings, but the type machinery can't narrow the bare
124
+ // arrow's signature to that union — going through `unknown` is the
125
+ // standard escape hatch used elsewhere in solid-router-style adapters.
126
+ // Removing either cast yields a "Type '() => unknown' is not assignable
127
+ // to type 'JSX.Element'" error.
128
+ return () => {
129
+ const value = resource();
130
+ if (resource.state !== "ready") {
131
+ return;
132
+ }
133
+ return props.children(value);
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Cross-adapter alias for Solid's `<Suspense fallback={…}>`. Symmetric naming
139
+ * with the React/Preact/Svelte/Vue/Angular `<Streamed>` components — pick
140
+ * `<Streamed>` for cross-framework consistency, or use Solid's native
141
+ * `<Suspense>` directly when team conventions prefer that.
142
+ *
143
+ * Solid's `<Suspense>` is a built-in primitive; out-of-order resolution +
144
+ * splice scripts during `renderToStream` are part of the runtime. See
145
+ * Solid's SSR docs for the wire-format details.
146
+ */
147
+ function Streamed(props) {
148
+ return createComponent(Suspense, {
149
+ get fallback() {
150
+ return props.fallback;
151
+ },
152
+ get children() {
153
+ return props.children;
154
+ }
155
+ });
156
+ }
157
+
158
+ const HttpStatusContext = createContext(null);
159
+ function HttpStatusProvider(props) {
160
+ return createComponent(HttpStatusContext.Provider, {
161
+ get value() {
162
+ return props.sink;
163
+ },
164
+ get children() {
165
+ return props.children;
166
+ }
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Render-time HTTP status declaration. Mount inside a route component (typical
172
+ * use case: a glob `*` route's NotFound page) when the status is decided by
173
+ * the rendered tree rather than a loader.
174
+ *
175
+ * Writes `code` to the nearest `<HttpStatusProvider>`'s sink during render and
176
+ * returns `null`. With no provider mounted (the standard client-side case)
177
+ * the component is a silent no-op — same component tree hydrates without
178
+ * touching the DOM or warning about mismatches.
179
+ *
180
+ * Loader-driven errors (`LoaderNotFound` → 404, `LoaderRedirect` → 30x) keep
181
+ * working as before; this component covers render-time decisions only.
182
+ *
183
+ * Last write wins when several `<HttpStatusCode />` instances mount in the
184
+ * same render pass — sink reflects the last component that ran.
185
+ *
186
+ * ```tsx
187
+ * // entry-server.tsx
188
+ * import { renderToString } from "solid-js/web";
189
+ * import { createHttpStatusSink, HttpStatusProvider } from "@real-router/solid/ssr";
190
+ *
191
+ * const sink = createHttpStatusSink();
192
+ * const html = renderToString(() => (
193
+ * <HttpStatusProvider sink={sink}>
194
+ * <RouterProvider router={router}>
195
+ * <App />
196
+ * </RouterProvider>
197
+ * </HttpStatusProvider>
198
+ * ));
199
+ * response.status(sink.code ?? 200).send(html);
200
+ * ```
201
+ *
202
+ * **Streaming SSR (`renderToStream`):** the response status MUST be sent
203
+ * before the first body byte flushes. If `<HttpStatusCode />` is mounted
204
+ * inside a late-resolving `<Suspense>` boundary, the sink write may happen
205
+ * AFTER the headers are already on the wire — the override is then lost.
206
+ * Mount the component in the shell (above every `<Suspense>` that could
207
+ * delay it), or use `renderToStringAsync` (single-shot, awaits all Suspense
208
+ * before returning HTML).
209
+ *
210
+ * **Valid `code` range:** Node's `res.end()` throws `Invalid status code` on
211
+ * `NaN`, `0`, negative values, or values `> 999` — this surfaces as a 5xx /
212
+ * dropped connection, not silent corruption. Pass a real HTTP status integer
213
+ * (commonly 4xx/5xx; 100-999 is what Node accepts).
214
+ */
215
+ function HttpStatusCode(props) {
216
+ const sink = useContext(HttpStatusContext);
217
+ if (sink) {
218
+ sink.code = props.code;
219
+ }
220
+ return null;
221
+ }
222
+
223
+ /**
224
+ * Render-scoped HTTP status sink. Created per request on the server, passed to
225
+ * `<HttpStatusProvider sink={...}>`, and read after `renderToString` /
226
+ * `renderToStream` to apply the value to the HTTP response.
227
+ *
228
+ * Last write wins: if the rendered tree mounts more than one
229
+ * `<HttpStatusCode />`, the value reflects the last component that ran during
230
+ * the render pass.
231
+ *
232
+ * No-op on the client — `<HttpStatusCode />` reads the optional context and
233
+ * skips the write when no provider is mounted, so the same component tree can
234
+ * be hydrated without changing behaviour.
235
+ *
236
+ * Constraints:
237
+ * - **Per-request only.** Don't share a sink across requests; the rendered
238
+ * tree mutates `code` in place. Module-level singletons leak status
239
+ * between concurrent requests.
240
+ * - **Don't `Object.freeze` the sink.** The component writes to `.code`;
241
+ * freezing makes the assignment throw under ESM strict mode.
242
+ * - **Hydration symmetry:** mount `<HttpStatusProvider>` on both server and
243
+ * client (with a throwaway client sink). Solid emits `data-hk` markers
244
+ * per component boundary; an extra provider on one side desyncs the
245
+ * counter and breaks the hydration walker.
246
+ */
247
+
248
+ function createHttpStatusSink() {
249
+ return {
250
+ code: undefined
251
+ };
252
+ }
253
+
254
+ export { Await, ClientOnly, HttpStatusCode, HttpStatusProvider, ServerOnly, Streamed, createHttpStatusSink, useDeferred };
@@ -1 +1 @@
1
- {"version":3,"file":"RouterProvider.d.ts","sourceRoot":"","sources":["../../src/RouterProvider.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;IAC7C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAKT;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,GACrC,GAAG,CAAC,OAAO,CAuDb"}
1
+ {"version":3,"file":"RouterProvider.d.ts","sourceRoot":"","sources":["../../src/RouterProvider.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;IAC7C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAKT;AAwBD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,GACrC,GAAG,CAAC,OAAO,CAuCb"}
@@ -0,0 +1,30 @@
1
+ import type { JSX } from "solid-js";
2
+ export interface AwaitProps<T> {
3
+ /** Deferred key declared in the loader's `defer({ deferred: { <name>: ... } })`. */
4
+ readonly name: string;
5
+ /** Render the resolved value. Surrounding `<Suspense>` shows fallback while
6
+ * pending; rejection bubbles through Solid's `<ErrorBoundary>`. */
7
+ readonly children: (value: T) => JSX.Element;
8
+ }
9
+ /**
10
+ * Reads `useDeferred(name)` and hands the resolved value to the render-prop.
11
+ * Wraps the deferred promise in `createResource` so Solid's reactivity tracks
12
+ * resolution and `<Suspense>` gets the standard suspend signal.
13
+ *
14
+ * ```tsx
15
+ * <Streamed fallback={<Spinner />}>
16
+ * <Await<Review[]> name="reviews">
17
+ * {(reviews) => <ReviewList items={reviews} />}
18
+ * </Await>
19
+ * </Streamed>
20
+ * ```
21
+ *
22
+ * Implementation: returns a Solid accessor (function child) that reads
23
+ * `resource()` — this both (a) triggers `<Suspense>` suspension while pending
24
+ * and (b) re-throws on `errored` for the nearest `<ErrorBoundary>` to catch.
25
+ * The render-prop is gated on `resource.state === "ready"` rather than on
26
+ * truthiness so falsy resolved values (`0`, `false`, `null`, `""`) still
27
+ * reach `props.children`.
28
+ */
29
+ export declare function Await<T = unknown>(props: AwaitProps<T>): JSX.Element;
30
+ //# sourceMappingURL=Await.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Await.d.ts","sourceRoot":"","sources":["../../../src/components/Await.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;uEACmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAqBpE"}
@@ -0,0 +1,7 @@
1
+ import type { JSX } from "solid-js";
2
+ export interface ClientOnlyProps {
3
+ readonly children: JSX.Element;
4
+ readonly fallback?: JSX.Element;
5
+ }
6
+ export declare function ClientOnly(props: ClientOnlyProps): JSX.Element;
7
+ //# sourceMappingURL=ClientOnly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientOnly.d.ts","sourceRoot":"","sources":["../../../src/components/ClientOnly.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,GAAG,CAAC,OAAO,CAQ9D"}
@@ -0,0 +1,52 @@
1
+ import type { JSX } from "solid-js";
2
+ export interface HttpStatusCodeProps {
3
+ /** HTTP status to apply to the response. Common values: 404, 410, 451, 503. */
4
+ readonly code: number;
5
+ }
6
+ /**
7
+ * Render-time HTTP status declaration. Mount inside a route component (typical
8
+ * use case: a glob `*` route's NotFound page) when the status is decided by
9
+ * the rendered tree rather than a loader.
10
+ *
11
+ * Writes `code` to the nearest `<HttpStatusProvider>`'s sink during render and
12
+ * returns `null`. With no provider mounted (the standard client-side case)
13
+ * the component is a silent no-op — same component tree hydrates without
14
+ * touching the DOM or warning about mismatches.
15
+ *
16
+ * Loader-driven errors (`LoaderNotFound` → 404, `LoaderRedirect` → 30x) keep
17
+ * working as before; this component covers render-time decisions only.
18
+ *
19
+ * Last write wins when several `<HttpStatusCode />` instances mount in the
20
+ * same render pass — sink reflects the last component that ran.
21
+ *
22
+ * ```tsx
23
+ * // entry-server.tsx
24
+ * import { renderToString } from "solid-js/web";
25
+ * import { createHttpStatusSink, HttpStatusProvider } from "@real-router/solid/ssr";
26
+ *
27
+ * const sink = createHttpStatusSink();
28
+ * const html = renderToString(() => (
29
+ * <HttpStatusProvider sink={sink}>
30
+ * <RouterProvider router={router}>
31
+ * <App />
32
+ * </RouterProvider>
33
+ * </HttpStatusProvider>
34
+ * ));
35
+ * response.status(sink.code ?? 200).send(html);
36
+ * ```
37
+ *
38
+ * **Streaming SSR (`renderToStream`):** the response status MUST be sent
39
+ * before the first body byte flushes. If `<HttpStatusCode />` is mounted
40
+ * inside a late-resolving `<Suspense>` boundary, the sink write may happen
41
+ * AFTER the headers are already on the wire — the override is then lost.
42
+ * Mount the component in the shell (above every `<Suspense>` that could
43
+ * delay it), or use `renderToStringAsync` (single-shot, awaits all Suspense
44
+ * before returning HTML).
45
+ *
46
+ * **Valid `code` range:** Node's `res.end()` throws `Invalid status code` on
47
+ * `NaN`, `0`, negative values, or values `> 999` — this surfaces as a 5xx /
48
+ * dropped connection, not silent corruption. Pass a real HTTP status integer
49
+ * (commonly 4xx/5xx; 100-999 is what Node accepts).
50
+ */
51
+ export declare function HttpStatusCode(props: HttpStatusCodeProps): JSX.Element;
52
+ //# sourceMappingURL=HttpStatusCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpStatusCode.d.ts","sourceRoot":"","sources":["../../../src/components/HttpStatusCode.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAQtE"}
@@ -0,0 +1,9 @@
1
+ import type { HttpStatusSink } from "../utils/createHttpStatusSink";
2
+ import type { JSX } from "solid-js";
3
+ export declare const HttpStatusContext: import("solid-js", { with: { "resolution-mode": "import" } }).Context<HttpStatusSink | null>;
4
+ export interface HttpStatusProviderProps {
5
+ readonly sink: HttpStatusSink;
6
+ readonly children: JSX.Element;
7
+ }
8
+ export declare function HttpStatusProvider(props: HttpStatusProviderProps): JSX.Element;
9
+ //# sourceMappingURL=HttpStatusProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpStatusProvider.d.ts","sourceRoot":"","sources":["../../../src/components/HttpStatusProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,eAAO,MAAM,iBAAiB,8FAA6C,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,GAAG,CAAC,OAAO,CAMb"}
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/components/Link.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC5B,GAAG,CAAC,OAAO,CAkHb"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/components/Link.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC5B,GAAG,CAAC,OAAO,CAwHb"}
@@ -1 +1 @@
1
- {"version":3,"file":"RouteView.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/RouteView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,iBAAS,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,OAAO,CAgCnE;kBAhCQ,aAAa;;;AAoCtB,eAAO,MAAM,SAAS;;;;CAIpB,CAAC;AAEH,YAAY,EACV,cAAc,EACd,UAAU,IAAI,mBAAmB,EACjC,SAAS,IAAI,kBAAkB,EAC/B,aAAa,IAAI,sBAAsB,GACxC,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"RouteView.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/RouteView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,iBAAS,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,OAAO,CAiCnE;kBAjCQ,aAAa;;;AAqCtB,eAAO,MAAM,SAAS;;;;CAIpB,CAAC;AAEH,YAAY,EACV,cAAc,EACd,UAAU,IAAI,mBAAmB,EACjC,SAAS,IAAI,kBAAkB,EAC/B,aAAa,IAAI,sBAAsB,GACxC,MAAM,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/components.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC,eAAO,MAAM,YAAY,eAA4B,CAAC;AAEtD,eAAO,MAAM,WAAW,eAA2B,CAAC;AAEpD,eAAO,MAAM,gBAAgB,eAA+B,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,YAAY,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC;AAExE,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAepD;yBAfe,KAAK;;;AAmBrB,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,CAWlD;yBAXe,IAAI;;;AAepB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAU1D;yBAVe,QAAQ"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/components.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC,eAAO,MAAM,YAAY,eAA4B,CAAC;AAEtD,eAAO,MAAM,WAAW,eAA2B,CAAC;AAEpD,eAAO,MAAM,gBAAgB,eAA+B,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,YAAY,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC;AAgCxE,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAMpD;yBANe,KAAK;;;AAUrB,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,CAIlD;yBAJe,IAAI;;;AAQpB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAE1D;yBAFe,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/helpers.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,eAAe,EAEhB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,GACb,OAAO,CAMT;AA6BD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAoBN;AAqCD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,OAAO,EAAE,CAsCf"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/helpers.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,eAAe,EAEhB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,GACb,OAAO,CAMT;AA8BD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAoBN;AA8HD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,OAAO,EAAE,CAmEf"}
@@ -0,0 +1,7 @@
1
+ import type { JSX } from "solid-js";
2
+ export interface ServerOnlyProps {
3
+ readonly children: JSX.Element;
4
+ readonly fallback?: JSX.Element;
5
+ }
6
+ export declare function ServerOnly(props: ServerOnlyProps): JSX.Element;
7
+ //# sourceMappingURL=ServerOnly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerOnly.d.ts","sourceRoot":"","sources":["../../../src/components/ServerOnly.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,GAAG,CAAC,OAAO,CAQ9D"}
@@ -0,0 +1,18 @@
1
+ import type { JSX } from "solid-js";
2
+ export interface StreamedProps {
3
+ /** Shown while any descendant `<Await>` / `createResource` suspends. */
4
+ readonly fallback: JSX.Element;
5
+ readonly children: JSX.Element;
6
+ }
7
+ /**
8
+ * Cross-adapter alias for Solid's `<Suspense fallback={…}>`. Symmetric naming
9
+ * with the React/Preact/Svelte/Vue/Angular `<Streamed>` components — pick
10
+ * `<Streamed>` for cross-framework consistency, or use Solid's native
11
+ * `<Suspense>` directly when team conventions prefer that.
12
+ *
13
+ * Solid's `<Suspense>` is a built-in primitive; out-of-order resolution +
14
+ * splice scripts during `renderToStream` are part of the runtime. See
15
+ * Solid's SSR docs for the wire-format details.
16
+ */
17
+ export declare function Streamed(props: StreamedProps): JSX.Element;
18
+ //# sourceMappingURL=Streamed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Streamed.d.ts","sourceRoot":"","sources":["../../../src/components/Streamed.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAE1D"}
@@ -1,9 +1,27 @@
1
1
  /**
2
- * Stable empty object for default params
2
+ * Stable empty object for default params.
3
+ *
4
+ * `Object.freeze` makes mutation throw under ESM strict mode — this guards
5
+ * against accidental writes that would corrupt the shared default across
6
+ * every Link without explicit params.
7
+ *
8
+ * §8.1 audit note (LOW #19): consumers cast `EMPTY_PARAMS as P` at usage
9
+ * sites (e.g. `Link.tsx`, `directives/link.tsx`). The cast is required for
10
+ * type compatibility with the generic `P extends Params` and DOES technically
11
+ * widen the `Readonly<{}>` type, but the underlying object stays frozen at
12
+ * runtime — any attempt to mutate fails at the JS engine level regardless
13
+ * of TS-level visibility. The frozen sentinel is also used by Link's
14
+ * fast-path identity check (`props.routeParams === undefined` after the
15
+ * §8.1 audit fix); changing this object's identity would silently break
16
+ * that path.
3
17
  */
4
18
  export declare const EMPTY_PARAMS: Readonly<{}>;
5
19
  /**
6
- * Stable empty options object
20
+ * Stable empty options object.
21
+ *
22
+ * Same freeze/cast guarantees as `EMPTY_PARAMS` — the sentinel is shared
23
+ * across all default `routeOptions` consumers (`Link`, `use:link`) to
24
+ * avoid per-render `{}` allocations.
7
25
  */
8
26
  export declare const EMPTY_OPTIONS: Readonly<{}>;
9
27
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY,cAAoB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,aAAa,cAAoB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,cAAoB,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,cAAoB,CAAC"}
@@ -8,4 +8,13 @@ export interface RouterContextValue {
8
8
  }
9
9
  export declare const RouterContext: import("solid-js", { with: { "resolution-mode": "import" } }).Context<RouterContextValue | null>;
10
10
  export declare const RouteContext: import("solid-js", { with: { "resolution-mode": "import" } }).Context<Accessor<RouteState<import("@real-router/core").Params>> | null>;
11
+ /**
12
+ * Read the required RouterContext or throw a labelled error. Internal helper
13
+ * — consolidates 4 copies of the same `useContext + null-check + throw`
14
+ * block across the public hooks/components/directives. The `consumerName`
15
+ * parameter keeps each callsite's error message specific (so the consumer
16
+ * sees "useRouter must be used within a RouterProvider", not a generic
17
+ * "context missing" message).
18
+ */
19
+ export declare function useRequiredRouterContext(consumerName: string): RouterContextValue;
11
20
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/C;AAED,eAAO,MAAM,aAAa,kGAAiD,CAAC;AAE5E,eAAO,MAAM,YAAY,wIAAmD,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/C;AAED,eAAO,MAAM,aAAa,kGAAiD,CAAC;AAE5E,eAAO,MAAM,YAAY,wIAAmD,CAAC;AAE7E;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,GACnB,kBAAkB,CAQpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSignalFromSource.d.ts","sourceRoot":"","sources":["../../src/createSignalFromSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,QAAQ,CAAC,CAAC,CAAC,CAoBb"}
1
+ {"version":3,"file":"createSignalFromSource.d.ts","sourceRoot":"","sources":["../../src/createSignalFromSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,QAAQ,CAAC,CAAC,CAAC,CA+Db"}
@@ -1,3 +1,22 @@
1
1
  import type { RouterSource } from "@real-router/sources";
2
+ /**
3
+ * Bridges a `RouterSource<T>` into a Solid store (`createStore` + `reconcile`).
4
+ *
5
+ * Unlike `createSignalFromSource` (whole-value replacement via `===`), this
6
+ * bridge uses `reconcile` on every emit so **unchanged nested paths retain
7
+ * their object identity**. Components that read only `state.route.name` will
8
+ * not re-run when `state.route.params` changes — granular reactivity without
9
+ * manual memoisation.
10
+ *
11
+ * **Ownership**: calls `onCleanup` — must be called inside a reactive owner
12
+ * (component body or `createRoot`). Same contract as `createSignalFromSource`.
13
+ *
14
+ * **Lazy-source re-sync**: after `source.subscribe()`, a cached lazy source
15
+ * may reconcile its snapshot in `onFirstSubscribe`. The listener is not
16
+ * notified for that internal update, so we re-read immediately after
17
+ * subscribing (`setState(reconcile(source.getSnapshot()))`) — mirrors the
18
+ * same pattern in `createSignalFromSource`. `reconcile` is a no-op when the
19
+ * snapshot is structurally unchanged, so there is no spurious reactivity cost.
20
+ */
2
21
  export declare function createStoreFromSource<T extends object>(source: RouterSource<T>): T;
3
22
  //# sourceMappingURL=createStoreFromSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createStoreFromSource.d.ts","sourceRoot":"","sources":["../../src/createStoreFromSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,CAAC,CAUH"}
1
+ {"version":3,"file":"createStoreFromSource.d.ts","sourceRoot":"","sources":["../../src/createStoreFromSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,CAAC,CAsCH"}
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/directives/link.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,oBAAoB,CAAC,CAAC,CAAC,GACtC,IAAI,CA+DN"}
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/directives/link.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,oBAAoB,CAAC,CAAC,CAAC,GACtC,IAAI,CAwFN"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Test helper: mirror of `encodeFragmentInline` from `link-utils.ts` used by
3
+ * property tests in every adapter (`packages/{vue,preact,react,solid}/tests/
4
+ * property/linkUtils.properties.ts` and `packages/svelte/tests/property/
5
+ * buildHref.properties.ts`).
6
+ *
7
+ * Why a mirror, not an import of the real function: a property test that uses
8
+ * the production implementation to compute its own expected value is a
9
+ * tautology — any regression in `encodeFragmentInline` would be invisible.
10
+ * We hand-roll the same algorithm so the test asserts an independent
11
+ * derivation. Drift between this mirror and `encodeFragmentInline` is exactly
12
+ * the signal property tests are supposed to surface.
13
+ *
14
+ * This file lives under `__test-helpers/` so the sync-dom-utils script can
15
+ * exclude it from the Angular copy (it ships no production code), and so
16
+ * bundlers (tsdown, svelte-package) tree-shake it out — nothing in
17
+ * `src/index.ts` of any adapter imports from this directory.
18
+ */
19
+ /**
20
+ * Compute the expected fragment portion of an href for a given raw hash input.
21
+ *
22
+ * Mirrors the contract of `encodeFragmentInline`:
23
+ * 1. If input contains `%XX`, try `decodeURIComponent` → `encodeURI` (idempotent
24
+ * re-encoding so consumers can copy-paste `location.hash` back in without
25
+ * `%20` becoming `%2520`).
26
+ * 2. If `decodeURIComponent` throws (malformed `%XX`), fall through to plain
27
+ * `encodeURI` on the original input.
28
+ * 3. Defensive `#` → `%23` (encodeURI does not encode `#`).
29
+ */
30
+ export declare function computeExpectedFragment(rawHash: string): string;
31
+ //# sourceMappingURL=expected-fragment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expected-fragment.d.ts","sourceRoot":"","sources":["../../../../src/dom-utils/__test-helpers/expected-fragment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAa/D"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Test-only barrel. Intentionally NOT re-exported from
3
+ * `shared/dom-utils/index.ts` so the helpers don't leak into adapters'
4
+ * public API surface. Property tests import from this path directly:
5
+ *
6
+ * import { computeExpectedFragment } from "../../src/dom-utils/__test-helpers";
7
+ */
8
+ export { computeExpectedFragment } from "./expected-fragment.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/dom-utils/__test-helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -18,6 +18,29 @@ export declare function buildHref(router: Router, routeName: string, routeParams
18
18
  }): string | undefined;
19
19
  export declare function navigateWithHash(router: Router, routeName: string, routeParams: Params, hash: string | undefined, extraOptions?: NavigationOptions): Promise<State>;
20
20
  export declare function buildActiveClassName(isActive: boolean, activeClassName: string | undefined, baseClassName: string | undefined): string | undefined;
21
+ /**
22
+ * One-level structural equality using `Object.is` per key.
23
+ *
24
+ * **String-keyed properties only (Mini-sprint E.3 — audit-5 §4.2 #3).**
25
+ * Implementation walks `Object.keys()` which by spec returns only
26
+ * enumerable own STRING keys. Symbol-keyed properties — created via
27
+ * `obj[Symbol("brand")] = value` or `{ [Symbol(...)]: value }` — are
28
+ * NOT compared. Two records that differ only in a Symbol-keyed value
29
+ * will compare as equal.
30
+ *
31
+ * This is intentional: route params and Link options are documented as
32
+ * string-keyed primitives (string | number | boolean) — Symbol-keyed
33
+ * metadata (e.g. brand markers, private state) doesn't belong in a
34
+ * cache-key comparison. Switching to `Reflect.ownKeys()` would extend
35
+ * the contract to symbols at the cost of one extra allocation per call
36
+ * (Reflect.ownKeys composes string-keys + symbol-keys arrays). If a
37
+ * consumer relies on symbol-keyed metadata for navigation
38
+ * disambiguation, they should encode it into a string key instead.
39
+ *
40
+ * Mirrors React's `shallowEqual` (packages/shared/shallowEqual.js) in
41
+ * both the string-keys-only semantics and the `hasOwnProperty` guard
42
+ * below.
43
+ */
21
44
  export declare function shallowEqual(prev: object | undefined, next: object | undefined): boolean;
22
45
  export declare function applyLinkA11y(element: HTMLElement | null | undefined): void;
23
46
  //# sourceMappingURL=link-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/link-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,mBAAmB,CAAC;AAE3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAQvD;AAmBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,MAAM,GAAG,SAAS,CAiCpB;AA4BD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,YAAY,CAAC,EAAE,iBAAiB,GAC/B,OAAO,CAAC,KAAK,CAAC,CAyBhB;AAMD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAyBpB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAwBT;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAgB3E"}
1
+ {"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/link-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,mBAAmB,CAAC;AAE3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAQvD;AA8CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,MAAM,GAAG,SAAS,CAsDpB;AA4BD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,YAAY,CAAC,EAAE,iBAAiB,GAC/B,OAAO,CAAC,KAAK,CAAC,CAyBhB;AA0BD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAyBpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CA8BT;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CA+B3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"route-announcer.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/route-announcer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AASvD,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;CAChD;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAsFzB"}
1
+ {"version":3,"file":"route-announcer.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/route-announcer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AASvD,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;CAChD;AAQD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAmGzB"}