@absolutejs/absolute 0.20.0-beta.169 → 0.20.0-beta.170

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 (238) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +232 -0
  3. package/changelog.json +228 -0
  4. package/dist/angular/browser.js +7 -8
  5. package/dist/angular/browser.js.map +6 -5
  6. package/dist/angular/components/core/streamingSlotRegistrar.js +6 -2
  7. package/dist/angular/components/core/streamingSlotRegistry.js +7 -3
  8. package/dist/angular/index.js +555 -156
  9. package/dist/angular/index.js.map +29 -23
  10. package/dist/angular/server.js +555 -156
  11. package/dist/angular/server.js.map +29 -23
  12. package/dist/build/buildWorker.js +14 -8
  13. package/dist/build.js +4949 -1941
  14. package/dist/build.js.map +72 -42
  15. package/dist/cli/{add-7azr0c83.js → add-6a7pjkn9.js} +11 -7
  16. package/dist/cli/{analyze-3cyek6v3.js → analyze-606fshwa.js} +1 -1
  17. package/dist/cli/{build-25rz8v25.js → build-g81xqbb9.js} +1 -1
  18. package/dist/cli/{compile-4jnfxts9.js → compile-9y1w9zpj.js} +3 -3
  19. package/dist/cli/config/server.js +10699 -1538
  20. package/dist/cli/{dev-9tk5hn2e.js → dev-hyeb89hp.js} +5 -1
  21. package/dist/cli/{doctor-4nv2c2j3.js → doctor-h55y9hj1.js} +1 -1
  22. package/dist/cli/{generate-v75p2fct.js → generate-20x1pkf7.js} +4 -4
  23. package/dist/cli/{htmx-427swtdz.js → htmx-6mz2h7k1.js} +2 -2
  24. package/dist/cli/{index-bhbs6d5z.js → index-32ge2w1f.js} +12 -4
  25. package/dist/cli/{index-a4ws2jwd.js → index-3wz3mktm.js} +1 -1
  26. package/dist/cli/{index-b7hjgknf.js → index-9sksd8c8.js} +13 -4
  27. package/dist/cli/{index-eyzwc7gz.js → index-qbrzvmh9.js} +4 -2
  28. package/dist/cli/index-qw98g1p6.js +269 -0
  29. package/dist/cli/{index-434b7j4a.js → index-vtp20gwf.js} +69 -1
  30. package/dist/cli/{index-h7qhz02e.js → index-wk0pyxrg.js} +3 -0
  31. package/dist/cli/{index-k3y8cb6c.js → index-z6f43b20.js} +1 -1
  32. package/dist/cli/index.js +16 -16
  33. package/dist/cli/{islands-8sgky9gh.js → islands-dc54e5y1.js} +1 -1
  34. package/dist/cli/{ls-4m4yqwww.js → ls-b6zz24nt.js} +1 -1
  35. package/dist/cli/{mobile-hcxjr2gf.js → mobile-ajnnvqtv.js} +3 -3
  36. package/dist/cli/prerender-fqpp0m1j.js +10 -0
  37. package/dist/cli/{remove-1ycjx85k.js → remove-t8x1mrxg.js} +4 -4
  38. package/dist/cli/{start-mbaejxhm.js → start-d6p831ny.js} +3 -3
  39. package/dist/cli/{typecheck-dr068pmh.js → typecheck-stbt0qt5.js} +6 -1
  40. package/dist/cli/{workspace-1sycp9g1.js → workspace-61hh6jq1.js} +1 -1
  41. package/dist/client/chunks/index-6b66nzyf.js +381 -0
  42. package/dist/client/chunks/index-6b66nzyf.js.map +11 -0
  43. package/dist/client/chunks/{islands-rc28k5sx.js → islands-s2ta5ajb.js} +5 -2
  44. package/dist/client/chunks/{islands-rc28k5sx.js.map → islands-s2ta5ajb.js.map} +7 -6
  45. package/dist/client/index.js +160 -3
  46. package/dist/client/index.js.map +6 -4
  47. package/dist/client/navigation.js +764 -0
  48. package/dist/client/navigation.js.map +10 -0
  49. package/dist/client/prefetch.js +33 -375
  50. package/dist/client/prefetch.js.map +3 -4
  51. package/dist/core/streamingSlotRegistrar.js +5 -2
  52. package/dist/core/streamingSlotRegistrar.js.map +5 -4
  53. package/dist/core/streamingSlotRegistry.js +5 -2
  54. package/dist/core/streamingSlotRegistry.js.map +5 -4
  55. package/dist/dev/client/cspNonce.ts +28 -0
  56. package/dist/dev/client/handlers/html.ts +4 -3
  57. package/dist/dev/client/handlers/htmx.ts +3 -2
  58. package/dist/dev/client/handlers/svelte.ts +15 -90
  59. package/dist/dev/client/syncDevtools.ts +2 -1
  60. package/dist/dev/serverBootstrap.js +11 -4
  61. package/dist/i18n/index.js +543 -0
  62. package/dist/i18n/index.js.map +15 -0
  63. package/dist/index.js +6339 -2233
  64. package/dist/index.js.map +89 -54
  65. package/dist/islands/index.js +282 -40
  66. package/dist/islands/index.js.map +14 -10
  67. package/dist/mobile/browser.js +7 -2
  68. package/dist/mobile/browser.js.map +5 -4
  69. package/dist/mobile/index.js +7 -2
  70. package/dist/mobile/index.js.map +5 -4
  71. package/dist/mobile/remoteMacAgentEntry.js +1 -1
  72. package/dist/react/components/browser/index.js +94 -4
  73. package/dist/react/components/index.js +150 -10
  74. package/dist/react/components/index.js.map +15 -10
  75. package/dist/react/hooks/index.js +479 -13
  76. package/dist/react/hooks/index.js.map +12 -4
  77. package/dist/react/index.js +769 -166
  78. package/dist/react/index.js.map +32 -21
  79. package/dist/react/router/browser.js +21 -4
  80. package/dist/react/router/browser.js.map +5 -4
  81. package/dist/react/router/index.js +21 -4
  82. package/dist/react/router/index.js.map +5 -4
  83. package/dist/react/server.js +597 -203
  84. package/dist/react/server.js.map +25 -15
  85. package/dist/src/angular/zoneRuntime.d.ts +5 -0
  86. package/dist/src/build/buildReactServerComponents.d.ts +22 -0
  87. package/dist/src/build/downlevelAsyncForZone.d.ts +1 -0
  88. package/dist/src/build/fileRoutes.d.ts +65 -0
  89. package/dist/src/build/fonts/buildFonts.d.ts +25 -0
  90. package/dist/src/build/fonts/fallbackMetrics.d.ts +13 -0
  91. package/dist/src/build/fonts/googleFonts.d.ts +18 -0
  92. package/dist/src/build/fonts/injectFontTags.d.ts +7 -0
  93. package/dist/src/build/fonts/parseFontMetrics.d.ts +4 -0
  94. package/dist/src/build/generateReactIndexes.d.ts +7 -1
  95. package/dist/src/build/htmlIncludes.d.ts +16 -0
  96. package/dist/src/build/inlineSourceMapComment.d.ts +1 -0
  97. package/dist/src/build/scanConventions.d.ts +3 -0
  98. package/dist/src/build/vitals.d.ts +21 -0
  99. package/dist/src/client/formActions.d.ts +29 -0
  100. package/dist/src/client/index.d.ts +2 -0
  101. package/dist/src/client/navigation.d.ts +16 -0
  102. package/dist/src/client/prefetch.d.ts +2 -30
  103. package/dist/src/core/build.d.ts +2 -2
  104. package/dist/src/core/cspNonce.d.ts +12 -0
  105. package/dist/src/core/fileRouteAdapter.d.ts +15 -0
  106. package/dist/src/core/fileRoutes.d.ts +5 -0
  107. package/dist/src/core/formActionFlash.d.ts +25 -0
  108. package/dist/src/core/formActions.d.ts +249 -0
  109. package/dist/src/core/index.d.ts +5 -0
  110. package/dist/src/core/partialPrerender.d.ts +28 -0
  111. package/dist/src/core/partialPrerenderServe.d.ts +24 -0
  112. package/dist/src/core/precompressed.d.ts +11 -1
  113. package/dist/src/core/prerenderNonce.d.ts +9 -0
  114. package/dist/src/core/productionRuntime.d.ts +4 -2
  115. package/dist/src/core/serverOnlyStaticFiles.d.ts +8 -0
  116. package/dist/src/core/staticHtmlNonce.d.ts +2 -0
  117. package/dist/src/core/vitals.d.ts +108 -0
  118. package/dist/src/dev/angular/fastHmrCompiler.d.ts +1 -1
  119. package/dist/src/dev/client/cspNonce.d.ts +2 -0
  120. package/dist/src/dev/fileRouteRefresher.d.ts +5 -0
  121. package/dist/src/dev/importCost/instrument.d.ts +1 -1
  122. package/dist/src/dev/reactServerComponentsRebuild.d.ts +3 -0
  123. package/dist/src/i18n/defineMessages.d.ts +5 -0
  124. package/dist/src/i18n/formatMessage.d.ts +26 -0
  125. package/dist/src/i18n/index.d.ts +6 -0
  126. package/dist/src/i18n/intlCache.d.ts +5 -0
  127. package/dist/src/i18n/routing.d.ts +28 -0
  128. package/dist/src/i18n/translator.d.ts +11 -0
  129. package/dist/src/mobile/androidRelease.d.ts +2 -2
  130. package/dist/src/mobile/iosRelease.d.ts +4 -4
  131. package/dist/src/mobile/materializedBundle.d.ts +1 -1
  132. package/dist/src/mobile/mobileInspect.d.ts +1 -1
  133. package/dist/src/mobile/releaseArtifact.d.ts +2 -2
  134. package/dist/src/mobile/remoteMacProtocol.d.ts +2 -2
  135. package/dist/src/plugins/i18n.d.ts +30 -0
  136. package/dist/src/plugins/index.d.ts +2 -1
  137. package/dist/src/plugins/secureHeaders.d.ts +48 -0
  138. package/dist/src/react/components/Head.d.ts +1 -1
  139. package/dist/src/react/components/StreamSlot.browser.d.ts +1 -0
  140. package/dist/src/react/components/StreamSlot.d.ts +5 -1
  141. package/dist/src/react/components/SuspenseSlot.browser.d.ts +2 -0
  142. package/dist/src/react/components/SuspenseSlot.d.ts +12 -0
  143. package/dist/src/react/fileRoute.d.ts +18 -0
  144. package/dist/src/react/hooks/index.d.ts +4 -0
  145. package/dist/src/react/hooks/useFormAction.d.ts +42 -0
  146. package/dist/src/react/hooks/useI18n.d.ts +15 -0
  147. package/dist/src/react/index.d.ts +2 -0
  148. package/dist/src/react/server.d.ts +2 -0
  149. package/dist/src/react/serverComponents/constants.d.ts +11 -0
  150. package/dist/src/react/serverComponents/flightPayload.d.ts +2 -0
  151. package/dist/src/react/serverComponents/pageHandler.d.ts +14 -0
  152. package/dist/src/svelte/browser.d.ts +1 -0
  153. package/dist/src/svelte/fileRoute.d.ts +15 -0
  154. package/dist/src/svelte/i18n.d.ts +8 -0
  155. package/dist/src/svelte/index.d.ts +2 -0
  156. package/dist/src/svelte/lowerAwaitSlotSyntax.d.ts +5 -1
  157. package/dist/src/svelte/renderToReadableStream.d.ts +10 -2
  158. package/dist/src/svelte/router/browser.d.ts +3 -1
  159. package/dist/src/svelte/router/goto.d.ts +13 -10
  160. package/dist/src/svelte/router/guards.d.ts +43 -0
  161. package/dist/src/svelte/router/index.d.ts +3 -1
  162. package/dist/src/svelte/router/lazy.d.ts +17 -0
  163. package/dist/src/svelte/router/lazyModule.d.ts +29 -0
  164. package/dist/src/svelte/router/navigation.d.ts +55 -0
  165. package/dist/src/svelte/router/pushState.d.ts +4 -2
  166. package/dist/src/svelte/router/scroll.d.ts +34 -0
  167. package/dist/src/svelte/routerSsr.d.ts +9 -0
  168. package/dist/src/svelte/server.d.ts +1 -0
  169. package/dist/src/utils/cspNonceRef.d.ts +8 -0
  170. package/dist/src/utils/fontAssets.d.ts +17 -0
  171. package/dist/src/utils/formActionProtocol.d.ts +10 -0
  172. package/dist/src/utils/generateHeadElement.d.ts +1 -1
  173. package/dist/src/utils/index.d.ts +1 -0
  174. package/dist/src/utils/inlinePageCss.d.ts +18 -0
  175. package/dist/src/utils/loadConfig.d.ts +5 -0
  176. package/dist/src/utils/localeRef.d.ts +10 -0
  177. package/dist/src/utils/resolveConvention.d.ts +6 -1
  178. package/dist/src/utils/streamingSlots.d.ts +5 -0
  179. package/dist/src/vue/browser.d.ts +2 -0
  180. package/dist/src/vue/components/Image.d.ts +2 -2
  181. package/dist/src/vue/index.d.ts +2 -0
  182. package/dist/src/vue/serverDataPayload.d.ts +32 -0
  183. package/dist/src/vue/serverDataState.d.ts +9 -0
  184. package/dist/src/vue/useServerData.browser.d.ts +6 -0
  185. package/dist/src/vue/useServerData.d.ts +24 -0
  186. package/dist/svelte/browser.js +330 -3
  187. package/dist/svelte/browser.js.map +8 -4
  188. package/dist/svelte/components/AwaitSlot.svelte +5 -0
  189. package/dist/svelte/components/Head.svelte +50 -0
  190. package/dist/svelte/components/JsonLd.svelte +9 -1
  191. package/dist/svelte/components/StreamSlot.svelte +5 -0
  192. package/dist/svelte/index.js +1017 -117
  193. package/dist/svelte/index.js.map +38 -24
  194. package/dist/svelte/router/Link.svelte +40 -8
  195. package/dist/svelte/router/Route.svelte +157 -12
  196. package/dist/svelte/router/Route.svelte.d.ts +39 -5
  197. package/dist/svelte/router/Router.svelte +140 -25
  198. package/dist/svelte/router/Router.svelte.d.ts +5 -1
  199. package/dist/svelte/router/browser.ts +10 -0
  200. package/dist/svelte/router/goto.ts +15 -86
  201. package/dist/svelte/router/guards.ts +112 -0
  202. package/dist/svelte/router/index.ts +10 -0
  203. package/dist/svelte/router/lazy.ts +82 -0
  204. package/dist/svelte/router/lazyModule.ts +74 -0
  205. package/dist/svelte/router/navigation.ts +412 -0
  206. package/dist/svelte/router/pushState.ts +7 -4
  207. package/dist/svelte/router/scroll.ts +286 -0
  208. package/dist/svelte/server.js +747 -252
  209. package/dist/svelte/server.js.map +30 -20
  210. package/dist/types/angular.d.ts +2 -0
  211. package/dist/types/build.d.ts +37 -0
  212. package/dist/types/conventions.d.ts +3 -0
  213. package/dist/types/fileRoutes.d.ts +72 -0
  214. package/dist/types/fonts.d.ts +86 -0
  215. package/dist/types/formAction.d.ts +54 -0
  216. package/dist/types/globals.d.ts +10 -0
  217. package/dist/types/i18n.d.ts +185 -0
  218. package/dist/types/index.d.ts +4 -0
  219. package/dist/types/metadata.d.ts +11 -0
  220. package/dist/types/navigation.d.ts +37 -0
  221. package/dist/types/prefetch.d.ts +10 -0
  222. package/dist/types/sitemap.d.ts +4 -0
  223. package/dist/types/svelteRouter.d.ts +89 -2
  224. package/dist/types/svelteRouter.ts +112 -2
  225. package/dist/types/vue.d.ts +46 -1
  226. package/dist/utils/iconVersion.ts +34 -0
  227. package/dist/vue/browser.js +107 -11
  228. package/dist/vue/browser.js.map +7 -4
  229. package/dist/vue/components/index.js +5 -2
  230. package/dist/vue/components/index.js.map +5 -4
  231. package/dist/vue/index.js +712 -158
  232. package/dist/vue/index.js.map +32 -23
  233. package/dist/vue/server.js +310 -79
  234. package/dist/vue/server.js.map +20 -15
  235. package/package.json +9 -1
  236. package/dist/cli/prerender-mfnwsvyt.js +0 -7
  237. package/dist/src/plugins/pageRouter.d.ts +0 -1
  238. /package/dist/cli/{index-j7m8pq48.js → index-rervww4p.js} +0 -0
@@ -46,11 +46,98 @@ export type GotoOptions = {
46
46
  replaceState?: boolean;
47
47
  /** Don't reset focus to body on navigation. */
48
48
  keepFocus?: boolean;
49
- /** Don't scroll to top on navigation. */
49
+ /** Leave the scroll position alone: no scroll to the top, no scroll to
50
+ * the `#hash` target. */
50
51
  noScroll?: boolean;
51
- /** Value attached to `history.state`. */
52
+ /** Value attached to `history.state`, read back as `page.state`. */
52
53
  state?: unknown;
53
54
  };
55
+ /** How a navigation started.
56
+ *
57
+ * - `'link'` — a `<Link>` click.
58
+ * - `'goto'` — a programmatic `goto()` call.
59
+ * - `'popstate'` — the browser's back / forward buttons (or `history.go`).
60
+ * - `'enter'` — the first render of the page: the server render, or the
61
+ * first client render in hash mode (the server never sees the hash). */
62
+ export type NavigationType = 'link' | 'goto' | 'popstate' | 'enter';
63
+ /** What a guard sees about the navigation it is asked to allow. */
64
+ export type NavigationContext = {
65
+ /** The URL being left. `null` on the first render (`type: 'enter'`). */
66
+ from: URL | null;
67
+ /** The URL being entered. In hash mode `to.pathname` is the routed path. */
68
+ to: URL;
69
+ /** Params of the route the guard belongs to, matched against `to`.
70
+ * Empty for `beforeNavigate` guards and for a `<Router guard>` whose
71
+ * routes don't match `to`. */
72
+ params: Record<string, string | undefined>;
73
+ type: NavigationType;
74
+ /** The incoming request during the server render, so a guard can read
75
+ * cookies or headers. `undefined` in the browser. */
76
+ request: Request | undefined;
77
+ };
78
+ /** Redirect the navigation somewhere else. `replace: true` replaces the
79
+ * current history entry instead of adding one (browser only; the server
80
+ * always answers a redirect with a 302). */
81
+ export type NavigationRedirectTarget = {
82
+ redirect: string;
83
+ replace?: boolean;
84
+ };
85
+ /** What a guard returns.
86
+ *
87
+ * - nothing / `undefined` / `true` — allow.
88
+ * - `false` — cancel: the URL and the rendered route stay as they were.
89
+ * - a URL string or `{ redirect }` — navigate there instead. */
90
+ export type RouteGuardResult = undefined | void | boolean | string | NavigationRedirectTarget;
91
+ export type RouteGuard = (navigation: NavigationContext) => RouteGuardResult | Promise<RouteGuardResult>;
92
+ /** What `goto()` resolves to once the navigation has settled. */
93
+ export type NavigationOutcome = 'committed' | 'cancelled' | 'redirected' | 'superseded' | 'external';
94
+ /** A lazily loaded route component: the module namespace returned by
95
+ * `import('./Page.svelte')`, or the component itself. */
96
+ export type LazyRouteModule<Props extends Record<string, unknown> = Record<string, unknown>> = {
97
+ default: import('svelte').Component<Props>;
98
+ } | import('svelte').Component<Props>;
99
+ export type LazyRouteLoader<Props extends Record<string, unknown> = Record<string, unknown>> = () => Promise<LazyRouteModule<Props>>;
100
+ export type ScrollPosition = {
101
+ x: number;
102
+ y: number;
103
+ };
104
+ /** Router bookkeeping stored in `history.state`, next to the user's own
105
+ * state (which `page.state` exposes unchanged). */
106
+ export type RouterHistoryMeta = {
107
+ index: number;
108
+ key: string;
109
+ scroll?: ScrollPosition;
110
+ };
111
+ /** @internal What the server records for a lazy route it rendered. */
112
+ export type SvelteRouterSsrResolved = {
113
+ component: import('svelte').Component<Record<string, unknown>>;
114
+ source: string | undefined;
115
+ } | {
116
+ error: unknown;
117
+ };
118
+ /** @internal What a server-side guard decided for the whole request. */
119
+ export type SvelteRouterSsrOutcome = {
120
+ kind: 'redirect';
121
+ location: string;
122
+ } | {
123
+ kind: 'cancel';
124
+ };
125
+ /** @internal Per-request state the Svelte page handler passes the router
126
+ * through Svelte context, so guards and lazy routes can be awaited
127
+ * between render passes. */
128
+ export type SvelteRouterSsrState = {
129
+ /** Queue work (a guard chain) to run once the current pass ends. */
130
+ afterRender: (task: () => Promise<void>) => void;
131
+ /** Start loading a lazy route's component; the page handler awaits it
132
+ * and renders again with the component in `resolved`. */
133
+ load: (key: string, loader: () => Promise<unknown>) => void;
134
+ outcome: () => SvelteRouterSsrOutcome | undefined;
135
+ request: Request | undefined;
136
+ resolved: Map<string, SvelteRouterSsrResolved>;
137
+ /** Guard chains already run, so a later pass doesn't run them again. */
138
+ settledGuards: Set<string>;
139
+ setOutcome: (outcome: SvelteRouterSsrOutcome) => void;
140
+ };
54
141
  export type LinkPrefetchMode = 'hover' | 'viewport' | 'none';
55
142
  export type PageState = {
56
143
  url: URL;
@@ -69,12 +69,122 @@ export type GotoOptions = {
69
69
  replaceState?: boolean;
70
70
  /** Don't reset focus to body on navigation. */
71
71
  keepFocus?: boolean;
72
- /** Don't scroll to top on navigation. */
72
+ /** Leave the scroll position alone: no scroll to the top, no scroll to
73
+ * the `#hash` target. */
73
74
  noScroll?: boolean;
74
- /** Value attached to `history.state`. */
75
+ /** Value attached to `history.state`, read back as `page.state`. */
75
76
  state?: unknown;
76
77
  };
77
78
 
79
+ /** How a navigation started.
80
+ *
81
+ * - `'link'` — a `<Link>` click.
82
+ * - `'goto'` — a programmatic `goto()` call.
83
+ * - `'popstate'` — the browser's back / forward buttons (or `history.go`).
84
+ * - `'enter'` — the first render of the page: the server render, or the
85
+ * first client render in hash mode (the server never sees the hash). */
86
+ export type NavigationType = 'link' | 'goto' | 'popstate' | 'enter';
87
+
88
+ /** What a guard sees about the navigation it is asked to allow. */
89
+ export type NavigationContext = {
90
+ /** The URL being left. `null` on the first render (`type: 'enter'`). */
91
+ from: URL | null;
92
+ /** The URL being entered. In hash mode `to.pathname` is the routed path. */
93
+ to: URL;
94
+ /** Params of the route the guard belongs to, matched against `to`.
95
+ * Empty for `beforeNavigate` guards and for a `<Router guard>` whose
96
+ * routes don't match `to`. */
97
+ params: Record<string, string | undefined>;
98
+ type: NavigationType;
99
+ /** The incoming request during the server render, so a guard can read
100
+ * cookies or headers. `undefined` in the browser. */
101
+ request: Request | undefined;
102
+ };
103
+
104
+ /** Redirect the navigation somewhere else. `replace: true` replaces the
105
+ * current history entry instead of adding one (browser only; the server
106
+ * always answers a redirect with a 302). */
107
+ export type NavigationRedirectTarget = {
108
+ redirect: string;
109
+ replace?: boolean;
110
+ };
111
+
112
+ /** What a guard returns.
113
+ *
114
+ * - nothing / `undefined` / `true` — allow.
115
+ * - `false` — cancel: the URL and the rendered route stay as they were.
116
+ * - a URL string or `{ redirect }` — navigate there instead. */
117
+ export type RouteGuardResult =
118
+ | undefined
119
+ | void
120
+ | boolean
121
+ | string
122
+ | NavigationRedirectTarget;
123
+
124
+ export type RouteGuard = (
125
+ navigation: NavigationContext
126
+ ) => RouteGuardResult | Promise<RouteGuardResult>;
127
+
128
+ /** What `goto()` resolves to once the navigation has settled. */
129
+ export type NavigationOutcome =
130
+ | 'committed'
131
+ | 'cancelled'
132
+ | 'redirected'
133
+ | 'superseded'
134
+ | 'external';
135
+
136
+ /** A lazily loaded route component: the module namespace returned by
137
+ * `import('./Page.svelte')`, or the component itself. */
138
+ export type LazyRouteModule<
139
+ Props extends Record<string, unknown> = Record<string, unknown>
140
+ > =
141
+ | { default: import('svelte').Component<Props> }
142
+ | import('svelte').Component<Props>;
143
+
144
+ export type LazyRouteLoader<
145
+ Props extends Record<string, unknown> = Record<string, unknown>
146
+ > = () => Promise<LazyRouteModule<Props>>;
147
+
148
+ export type ScrollPosition = { x: number; y: number };
149
+
150
+ /** Router bookkeeping stored in `history.state`, next to the user's own
151
+ * state (which `page.state` exposes unchanged). */
152
+ export type RouterHistoryMeta = {
153
+ index: number;
154
+ key: string;
155
+ scroll?: ScrollPosition;
156
+ };
157
+
158
+ /** @internal What the server records for a lazy route it rendered. */
159
+ export type SvelteRouterSsrResolved =
160
+ | {
161
+ component: import('svelte').Component<Record<string, unknown>>;
162
+ source: string | undefined;
163
+ }
164
+ | { error: unknown };
165
+
166
+ /** @internal What a server-side guard decided for the whole request. */
167
+ export type SvelteRouterSsrOutcome =
168
+ | { kind: 'redirect'; location: string }
169
+ | { kind: 'cancel' };
170
+
171
+ /** @internal Per-request state the Svelte page handler passes the router
172
+ * through Svelte context, so guards and lazy routes can be awaited
173
+ * between render passes. */
174
+ export type SvelteRouterSsrState = {
175
+ /** Queue work (a guard chain) to run once the current pass ends. */
176
+ afterRender: (task: () => Promise<void>) => void;
177
+ /** Start loading a lazy route's component; the page handler awaits it
178
+ * and renders again with the component in `resolved`. */
179
+ load: (key: string, loader: () => Promise<unknown>) => void;
180
+ outcome: () => SvelteRouterSsrOutcome | undefined;
181
+ request: Request | undefined;
182
+ resolved: Map<string, SvelteRouterSsrResolved>;
183
+ /** Guard chains already run, so a later pass doesn't run them again. */
184
+ settledGuards: Set<string>;
185
+ setOutcome: (outcome: SvelteRouterSsrOutcome) => void;
186
+ };
187
+
78
188
  export type LinkPrefetchMode = 'hover' | 'viewport' | 'none';
79
189
 
80
190
  export type PageState = {
@@ -1,4 +1,4 @@
1
- import type { AllowedComponentProps, App, ComponentCustomProps, VNodeProps } from 'vue';
1
+ import type { AllowedComponentProps, App, ComponentCustomProps, Ref, VNodeProps } from 'vue';
2
2
  import type { Router } from 'vue-router';
3
3
  /** The vue-router instance AbsoluteJS auto-creates from a page's `routes`
4
4
  * export. Aliased to vue-router's own `Router` so consumers get the full,
@@ -51,4 +51,49 @@ export type VueComponentInstance = {
51
51
  setupState?: Record<string, unknown>;
52
52
  subTree?: VueVNode;
53
53
  };
54
+ /** Loads the value `useServerData` stores under its key. Receives an
55
+ * `AbortSignal` that aborts when the component unmounts or `refresh()` runs
56
+ * again; pass it to `fetch` so stale requests are cancelled. */
57
+ export type ServerDataFetcher<T> = (signal: AbortSignal) => Promise<T>;
58
+ export type ServerDataOptions = {
59
+ /** Run the fetcher during server rendering and send the result to the
60
+ * browser with the page. Default: `true`. Set `false` to always load on
61
+ * the client (the server renders the pending state). */
62
+ server?: boolean;
63
+ };
64
+ export type ServerData<T> = {
65
+ /** The loaded value, or `null` before the first successful load. */
66
+ data: Ref<T | null>;
67
+ /** The last load failure, or `null`. A failure on the server reaches the
68
+ * browser as an `Error` with the same `name`; its message is replaced
69
+ * with a generic one in production. */
70
+ error: Ref<Error | null>;
71
+ /** True while a load is in flight. */
72
+ pending: Ref<boolean>;
73
+ /** Runs the fetcher again in the browser. An in-flight load is aborted
74
+ * first. */
75
+ refresh: () => Promise<void>;
76
+ };
77
+ /** A serialized server failure, as written into the page. */
78
+ export type ServerDataErrorEntry = {
79
+ error: {
80
+ message: string;
81
+ name: string;
82
+ };
83
+ };
84
+ /** One key's server result, as written into the page. */
85
+ export type ServerDataEntry = {
86
+ data: unknown;
87
+ } | ServerDataErrorEntry;
88
+ /** Per-request store the Vue page handler puts on the SSR context. Keys are
89
+ * claimed during `setup()`; `json` holds each result already serialized so
90
+ * a value that cannot be serialized fails while the page renders, not
91
+ * while the tail is written. */
92
+ export type ServerDataCollector = {
93
+ claimed: Set<string>;
94
+ /** A render error recorded while setup() ran (a repeated key in
95
+ * development), thrown by the page handler once rendering ends. */
96
+ failure: Error | null;
97
+ json: Map<string, string>;
98
+ };
54
99
  export {};
@@ -0,0 +1,34 @@
1
+ // Browsers — Chrome especially — cache favicons in a store that is separate
2
+ // from (and far stickier than) the HTTP cache. It ignores `must-revalidate`
3
+ // and even survives a hard reload, and it caches *negative* results ("this
4
+ // origin has no favicon") when an early request 404s. The only reliable way
5
+ // to force a re-fetch is to change the icon's URL. Rather than make every app
6
+ // hand-rename `favicon-v2.ico`, `favicon-v3.ico`, ... on each change, the
7
+ // framework appends a content-hash query (`?v=<hash>`) to the favicon href so
8
+ // the URL changes automatically whenever the icon bytes change.
9
+ //
10
+ // The hash is computed server-side (it needs filesystem access to the build
11
+ // dir), so this module holds an optional resolver that `prepare` registers at
12
+ // startup. `generateHeadElement` — which also runs in client bundles where no
13
+ // resolver is set — calls `applyIconVersion`, which is a no-op until the
14
+ // resolver is registered. That keeps the head builder isomorphic-safe.
15
+
16
+ type IconVersionResolver = (href: string) => string;
17
+
18
+ export const iconMimeType = (icon: string) => {
19
+ if (icon.endsWith('.svg')) return 'image/svg+xml';
20
+ if (icon.endsWith('.png')) return 'image/png';
21
+
22
+ return 'image/x-icon';
23
+ };
24
+
25
+ let resolver: IconVersionResolver | undefined;
26
+
27
+ export const applyIconVersion = (href: string) =>
28
+ resolver ? resolver(href) : href;
29
+
30
+ export const setIconVersionResolver = (
31
+ resolverFn: IconVersionResolver | undefined
32
+ ) => {
33
+ resolver = resolverFn;
34
+ };
@@ -440,6 +440,84 @@ var useIslandStore = (store, selector) => {
440
440
  });
441
441
  return state;
442
442
  };
443
+ // src/vue/serverDataState.ts
444
+ import { getCurrentScope, onScopeDispose, ref, shallowRef } from "vue";
445
+ var toError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
446
+ var createServerDataState = (fetcher, initiallyPending) => {
447
+ const data = shallowRef(null);
448
+ const error = shallowRef(null);
449
+ const pending = ref(initiallyPending);
450
+ let controller = null;
451
+ let disposed = false;
452
+ const cancel = () => {
453
+ controller?.abort();
454
+ controller = null;
455
+ };
456
+ const finish = (current) => {
457
+ if (controller === current)
458
+ controller = null;
459
+ if (!current.signal.aborted)
460
+ pending.value = false;
461
+ };
462
+ const refresh = async () => {
463
+ if (disposed)
464
+ return;
465
+ cancel();
466
+ const current = new AbortController;
467
+ controller = current;
468
+ pending.value = true;
469
+ error.value = null;
470
+ try {
471
+ const result = await fetcher(current.signal);
472
+ if (!current.signal.aborted)
473
+ data.value = result;
474
+ } catch (cause) {
475
+ if (!current.signal.aborted)
476
+ error.value = toError(cause);
477
+ } finally {
478
+ finish(current);
479
+ }
480
+ };
481
+ if (getCurrentScope()) {
482
+ onScopeDispose(() => {
483
+ disposed = true;
484
+ cancel();
485
+ });
486
+ }
487
+ const result = { data, error, pending, refresh };
488
+ return result;
489
+ };
490
+ var errorFromEntry = ({ error }) => {
491
+ const restored = new Error(error.message);
492
+ restored.name = error.name;
493
+ return restored;
494
+ };
495
+ var isFetcherResult = (_fetcher, _value) => true;
496
+
497
+ // src/vue/useServerData.browser.ts
498
+ var takeServerDataEntry = (key) => {
499
+ const payload = typeof window === "undefined" ? undefined : window.__ABSOLUTE_SERVER_DATA__;
500
+ if (!payload || !Object.hasOwn(payload, key))
501
+ return null;
502
+ const entry = payload[key];
503
+ Reflect.deleteProperty(payload, key);
504
+ return entry ?? null;
505
+ };
506
+ var useServerData = (key, fetcher, _options = {}) => {
507
+ const entry = takeServerDataEntry(key);
508
+ const state = createServerDataState(fetcher, entry === null);
509
+ if (entry === null) {
510
+ state.refresh();
511
+ return state;
512
+ }
513
+ if ("error" in entry) {
514
+ state.error.value = errorFromEntry(entry);
515
+ return state;
516
+ }
517
+ if (isFetcherResult(fetcher, entry.data))
518
+ state.data.value = entry.data;
519
+ return state;
520
+ };
443
521
  // src/client/browserTranslation.ts
444
522
  init_browserTranslationAttributes();
445
523
  var translatedFontText = (node, baselines) => {
@@ -618,6 +696,20 @@ var applyVueRouterRedirect = (router, requestedUrl, setRedirect, status = DEFAUL
618
696
  // src/vue/router/Link.ts
619
697
  import { defineComponent as defineComponent3, getCurrentInstance, h as h3 } from "vue";
620
698
 
699
+ // src/dev/client/cspNonce.ts
700
+ var applyPageNonce = (element) => {
701
+ const nonce = readPageNonce();
702
+ if (nonce)
703
+ element.nonce = nonce;
704
+ return element;
705
+ };
706
+ var readPageNonce = () => {
707
+ if (typeof document === "undefined")
708
+ return;
709
+ const carrier = document.querySelector("script[nonce], style[nonce]");
710
+ return carrier?.nonce || undefined;
711
+ };
712
+
621
713
  // src/client/prefetch.ts
622
714
  var PREFETCH_CACHE_LIMIT = 16;
623
715
  var HOVER_DEBOUNCE_MS = 250;
@@ -892,7 +984,7 @@ var speculate = (url) => {
892
984
  liveSpeculationRules.get(oldest.value)?.remove();
893
985
  liveSpeculationRules.delete(oldest.value);
894
986
  }
895
- const script = document.createElement("script");
987
+ const script = applyPageNonce(document.createElement("script"));
896
988
  script.type = "speculationrules";
897
989
  script.textContent = JSON.stringify({
898
990
  prerender: [{ eagerness: "immediate", urls: [url] }]
@@ -911,6 +1003,7 @@ var scheduleHoverPrefetch = (url, options = {}) => {
911
1003
  prefetch(url, { kind: options.kind ?? "route" });
912
1004
  if (options.prerender)
913
1005
  speculate(url);
1006
+ options.onPrefetch?.();
914
1007
  }, HOVER_DEBOUNCE_MS);
915
1008
  return {
916
1009
  cancel: () => window.clearTimeout(timer)
@@ -925,8 +1018,10 @@ var handleIntersections = (entries) => {
925
1018
  const target = viewportTargets.get(entry.target);
926
1019
  viewportObserver?.unobserve(entry.target);
927
1020
  viewportTargets.delete(entry.target);
928
- if (target)
929
- prefetch(target.url, target.options);
1021
+ if (!target)
1022
+ continue;
1023
+ prefetch(target.url, { kind: target.options.kind });
1024
+ target.options.onVisible?.();
930
1025
  }
931
1026
  };
932
1027
  var getViewportObserver = () => {
@@ -955,16 +1050,16 @@ var observeViewport = (element, url, options = {}) => {
955
1050
 
956
1051
  // src/vue/usePrefetch.ts
957
1052
  import {
958
- getCurrentScope,
959
- onScopeDispose,
960
- ref,
1053
+ getCurrentScope as getCurrentScope2,
1054
+ onScopeDispose as onScopeDispose2,
1055
+ ref as ref2,
961
1056
  toValue,
962
1057
  watchEffect
963
1058
  } from "vue";
964
1059
  var usePrefetch = (href, options = {}) => {
965
1060
  const viewportKind = options.kind ?? "document";
966
1061
  const triggerKind = options.kind ?? "route";
967
- const element = ref(null);
1062
+ const element = ref2(null);
968
1063
  let hoverHandle = null;
969
1064
  const currentHref = () => toValue(href);
970
1065
  const currentMode = () => toValue(options.mode) ?? resolveDefaultPrefetchMode();
@@ -1009,8 +1104,8 @@ var usePrefetch = (href, options = {}) => {
1009
1104
  onCleanup(observeViewport(node, target, { kind: viewportKind }));
1010
1105
  }, { flush: "post" });
1011
1106
  }
1012
- if (getCurrentScope())
1013
- onScopeDispose(cancelHover);
1107
+ if (getCurrentScope2())
1108
+ onScopeDispose2(cancelHover);
1014
1109
  return {
1015
1110
  element,
1016
1111
  onBlur: cancelHover,
@@ -1106,8 +1201,9 @@ export {
1106
1201
  prepareBrowserTranslationHydration,
1107
1202
  preserveBrowserTranslation,
1108
1203
  useIslandStore,
1109
- usePrefetch
1204
+ usePrefetch,
1205
+ useServerData
1110
1206
  };
1111
1207
 
1112
- //# debugId=A73C3B0A98113D7964756E2164756E21
1208
+ //# debugId=14B61170EEA73C5764756E2164756E21
1113
1209
  //# sourceMappingURL=browser.js.map