@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
@@ -1,4 +1,339 @@
1
1
  // @bun
2
+ // src/utils/formActionProtocol.ts
3
+ var ACTION_ERROR_ATTRIBUTE = "data-action-error", ACTION_FORM_ATTRIBUTE = "data-absolute-action", ACTION_MESSAGE_ATTRIBUTE = "data-action-message", ACTION_REQUEST_HEADER = "x-absolute-action", ACTION_STATUS_ATTRIBUTE = "data-action-status", ACTION_SUCCESS_ATTRIBUTE = "data-action-success", isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isStringRecord = (value) => isRecord3(value) && Object.values(value).every((entry) => typeof entry === "string"), isOptionalString = (value) => value === undefined || typeof value === "string", isActionResult = (value) => {
4
+ if (!isRecord3(value))
5
+ return false;
6
+ if (value.status === "success")
7
+ return isOptionalString(value.redirect);
8
+ return value.status === "error" && isStringRecord(value.errors) && isOptionalString(value.message);
9
+ };
10
+ // src/react/hooks/useI18n.ts
11
+ import {
12
+ createContext,
13
+ createElement,
14
+ useContext,
15
+ useMemo
16
+ } from "react";
17
+
18
+ // src/i18n/intlCache.ts
19
+ var numberFormats = new Map;
20
+ var dateTimeFormats = new Map;
21
+ var pluralRules = new Map;
22
+ var relativeTimeFormats = new Map;
23
+ var listFormats = new Map;
24
+ var cacheKey = (locale, options) => `${locale}|${options ? JSON.stringify(options) : ""}`;
25
+ var cached = (cache, key, create) => {
26
+ const existing = cache.get(key);
27
+ if (existing)
28
+ return existing;
29
+ const created = create();
30
+ cache.set(key, created);
31
+ return created;
32
+ };
33
+ var getDateTimeFormat = (locale, options) => cached(dateTimeFormats, cacheKey(locale, options), () => new Intl.DateTimeFormat(locale, options));
34
+ var getListFormat = (locale, options) => cached(listFormats, cacheKey(locale, options), () => new Intl.ListFormat(locale, options));
35
+ var getNumberFormat = (locale, options) => cached(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options));
36
+ var getPluralRules = (locale, options) => cached(pluralRules, cacheKey(locale, options), () => new Intl.PluralRules(locale, options));
37
+ var getRelativeTimeFormat = (locale, options) => cached(relativeTimeFormats, cacheKey(locale, options), () => new Intl.RelativeTimeFormat(locale, options));
38
+
39
+ // src/i18n/formatMessage.ts
40
+ var SYNTAX_CHARS = new Set(["{", "}", "#", "|"]);
41
+ var WHITESPACE = /\s/;
42
+ var isBranchKind = (value) => value === "plural" || value === "select" || value === "selectordinal";
43
+ var skipWhitespace = (cursor) => {
44
+ while (cursor.index < cursor.source.length && WHITESPACE.test(cursor.source.charAt(cursor.index))) {
45
+ cursor.index += 1;
46
+ }
47
+ };
48
+ var syntaxError = (cursor, expected) => new SyntaxError(`Invalid ICU message (expected ${expected} at ${cursor.index}): ${cursor.source}`);
49
+ var readToken = (cursor, stops) => {
50
+ const start = cursor.index;
51
+ while (cursor.index < cursor.source.length && !stops.includes(cursor.source.charAt(cursor.index))) {
52
+ cursor.index += 1;
53
+ }
54
+ return cursor.source.slice(start, cursor.index).trim();
55
+ };
56
+ var expectChar = (cursor, char) => {
57
+ skipWhitespace(cursor);
58
+ if (cursor.source.charAt(cursor.index) !== char)
59
+ throw syntaxError(cursor, `"${char}"`);
60
+ cursor.index += 1;
61
+ };
62
+ var readQuoted = (cursor, inPlural) => {
63
+ const next = cursor.source.charAt(cursor.index + 1);
64
+ if (next === "'") {
65
+ cursor.index += 2;
66
+ return "'";
67
+ }
68
+ const opensQuote = SYNTAX_CHARS.has(next) && (next !== "#" || inPlural);
69
+ if (!opensQuote) {
70
+ cursor.index += 1;
71
+ return "'";
72
+ }
73
+ cursor.index += 1;
74
+ let text = "";
75
+ while (cursor.index < cursor.source.length) {
76
+ const char = cursor.source.charAt(cursor.index);
77
+ const isEscapedQuote = char === "'" && cursor.source.charAt(cursor.index + 1) === "'";
78
+ if (char === "'" && !isEscapedQuote)
79
+ break;
80
+ text += char;
81
+ cursor.index += isEscapedQuote ? 2 : 1;
82
+ }
83
+ cursor.index += 1;
84
+ return text;
85
+ };
86
+ var pushText = (nodes, value) => {
87
+ const last = nodes[nodes.length - 1];
88
+ if (last?.kind === "text") {
89
+ last.value += value;
90
+ return;
91
+ }
92
+ nodes.push({ kind: "text", value });
93
+ };
94
+ var parseBranchOption = (cursor, kind, branches) => {
95
+ if (cursor.index >= cursor.source.length)
96
+ throw syntaxError(cursor, '"}"');
97
+ const selector = readToken(cursor, `{}
98
+ \r`);
99
+ const offsetMatch = /^offset:(\d+)$/.exec(selector);
100
+ if (offsetMatch && kind !== "select") {
101
+ branches.offset = Number(offsetMatch[1]);
102
+ skipWhitespace(cursor);
103
+ return;
104
+ }
105
+ if (selector === "")
106
+ throw syntaxError(cursor, "a selector");
107
+ expectChar(cursor, "{");
108
+ branches.options[selector] = parseNodes(cursor, kind !== "select");
109
+ expectChar(cursor, "}");
110
+ skipWhitespace(cursor);
111
+ };
112
+ var parseBranchOptions = (cursor, kind) => {
113
+ const branches = { offset: 0, options: {} };
114
+ skipWhitespace(cursor);
115
+ while (cursor.source.charAt(cursor.index) !== "}") {
116
+ parseBranchOption(cursor, kind, branches);
117
+ }
118
+ if (branches.options.other === undefined)
119
+ throw syntaxError(cursor, 'an "other" branch');
120
+ return branches;
121
+ };
122
+ var parseArgument = (cursor) => {
123
+ skipWhitespace(cursor);
124
+ const name = readToken(cursor, ",}");
125
+ if (name === "")
126
+ throw syntaxError(cursor, "an argument name");
127
+ if (cursor.source.charAt(cursor.index) === "}") {
128
+ cursor.index += 1;
129
+ return { format: undefined, kind: "argument", name, style: undefined };
130
+ }
131
+ cursor.index += 1;
132
+ const format = readToken(cursor, ",}");
133
+ if (isBranchKind(format)) {
134
+ expectChar(cursor, ",");
135
+ const { offset, options } = parseBranchOptions(cursor, format);
136
+ expectChar(cursor, "}");
137
+ return { kind: format, name, offset, options };
138
+ }
139
+ let style;
140
+ if (cursor.source.charAt(cursor.index) === ",") {
141
+ cursor.index += 1;
142
+ style = readToken(cursor, "}");
143
+ }
144
+ expectChar(cursor, "}");
145
+ return { format, kind: "argument", name, style };
146
+ };
147
+ var parseNode = (cursor, inPlural, nodes) => {
148
+ const char = cursor.source.charAt(cursor.index);
149
+ if (char === "{") {
150
+ cursor.index += 1;
151
+ nodes.push(parseArgument(cursor));
152
+ return;
153
+ }
154
+ if (char === "#" && inPlural) {
155
+ cursor.index += 1;
156
+ nodes.push({ kind: "pound" });
157
+ return;
158
+ }
159
+ if (char === "'") {
160
+ pushText(nodes, readQuoted(cursor, inPlural));
161
+ return;
162
+ }
163
+ pushText(nodes, char);
164
+ cursor.index += 1;
165
+ };
166
+ var parseNodes = (cursor, inPlural) => {
167
+ const nodes = [];
168
+ while (cursor.index < cursor.source.length && cursor.source.charAt(cursor.index) !== "}") {
169
+ parseNode(cursor, inPlural, nodes);
170
+ }
171
+ return nodes;
172
+ };
173
+ var parseMessage = (source) => {
174
+ const cursor = { index: 0, source };
175
+ const nodes = parseNodes(cursor, false);
176
+ if (cursor.index < source.length)
177
+ throw syntaxError(cursor, "end of message");
178
+ return nodes;
179
+ };
180
+ var parsedCache = new Map;
181
+ var parseCached = (source) => {
182
+ const cached = parsedCache.get(source);
183
+ if (cached)
184
+ return cached;
185
+ let parsed;
186
+ try {
187
+ parsed = parseMessage(source);
188
+ } catch (error) {
189
+ parsed = error instanceof SyntaxError ? error : new SyntaxError(String(error));
190
+ }
191
+ parsedCache.set(source, parsed);
192
+ return parsed;
193
+ };
194
+ var INTEGER_OPTIONS = { maximumFractionDigits: 0 };
195
+ var PERCENT_OPTIONS = { style: "percent" };
196
+ var numberOptions = (style) => {
197
+ if (style === "integer")
198
+ return INTEGER_OPTIONS;
199
+ if (style === "percent")
200
+ return PERCENT_OPTIONS;
201
+ const currency = /^::currency\/([A-Za-z]{3})$/.exec(style ?? "");
202
+ const options = currency?.[1] ? { currency: currency[1].toUpperCase(), style: "currency" } : {};
203
+ return options;
204
+ };
205
+ var toDate = (value) => {
206
+ if (value instanceof Date)
207
+ return value;
208
+ if (typeof value === "number" || typeof value === "string")
209
+ return new Date(value);
210
+ return;
211
+ };
212
+ var dateStyleOf = (style) => {
213
+ if (style === "full" || style === "long" || style === "short")
214
+ return style;
215
+ return "medium";
216
+ };
217
+ var formatDateArgument = (locale, value, format, style) => {
218
+ const date = toDate(value);
219
+ if (!date || Number.isNaN(date.getTime()))
220
+ return String(value);
221
+ const resolvedStyle = dateStyleOf(style);
222
+ const options = format === "date" ? { dateStyle: resolvedStyle } : { timeStyle: resolvedStyle };
223
+ return getDateTimeFormat(locale, options).format(date);
224
+ };
225
+ var formatValue = (locale, value) => {
226
+ if (typeof value === "number" || typeof value === "bigint")
227
+ return getNumberFormat(locale).format(value);
228
+ if (value instanceof Date)
229
+ return getDateTimeFormat(locale).format(value);
230
+ return String(value);
231
+ };
232
+ var formatArgument = (locale, node, params) => {
233
+ if (!(node.name in params))
234
+ return `{${node.name}}`;
235
+ const value = params[node.name];
236
+ if (node.format === "number") {
237
+ const numeric = typeof value === "bigint" ? value : Number(value);
238
+ return getNumberFormat(locale, numberOptions(node.style)).format(numeric);
239
+ }
240
+ if (node.format === "date" || node.format === "time")
241
+ return formatDateArgument(locale, value, node.format, node.style);
242
+ return formatValue(locale, value);
243
+ };
244
+ var selectBranch = (locale, node, value) => {
245
+ if (node.kind === "select") {
246
+ return node.options[String(value)] ?? node.options.other ?? [];
247
+ }
248
+ const numeric = Number(value);
249
+ const exact = node.options[`=${numeric}`];
250
+ if (exact)
251
+ return exact;
252
+ const category = getPluralRules(locale, {
253
+ type: node.kind === "selectordinal" ? "ordinal" : "cardinal"
254
+ }).select(numeric - node.offset);
255
+ return node.options[category] ?? node.options.other ?? [];
256
+ };
257
+ var formatNodes = (locale, nodes, params, pound) => nodes.map((node) => {
258
+ if (node.kind === "text")
259
+ return node.value;
260
+ if (node.kind === "pound")
261
+ return pound ?? "#";
262
+ if (node.kind === "argument")
263
+ return formatArgument(locale, node, params);
264
+ if (!(node.name in params))
265
+ return `{${node.name}}`;
266
+ const value = params[node.name];
267
+ const branch = selectBranch(locale, node, value);
268
+ const branchPound = node.kind === "select" ? pound : getNumberFormat(locale).format(Number(value) - node.offset);
269
+ return formatNodes(locale, branch, params, branchPound);
270
+ }).join("");
271
+ var formatMessage = (locale, message, params = {}) => {
272
+ if (!message.includes("{") && !message.includes("'"))
273
+ return message;
274
+ const parsed = parseCached(message);
275
+ if (parsed instanceof SyntaxError)
276
+ return message;
277
+ return formatNodes(locale, parsed, params, undefined);
278
+ };
279
+
280
+ // src/i18n/translator.ts
281
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
282
+ var lookupMessage = (messages, key) => {
283
+ let node = messages;
284
+ for (const segment of key.split(".")) {
285
+ if (typeof node !== "object")
286
+ return;
287
+ node = node[segment];
288
+ }
289
+ return typeof node === "string" ? node : undefined;
290
+ };
291
+ var isMessageTreeValue = (value) => typeof value === "string" || isMessageTree(value);
292
+ var isI18nPayload = (value) => isRecord(value) && typeof value.locale === "string" && typeof value.defaultLocale === "string" && (value.dir === "ltr" || value.dir === "rtl") && isMessageTree(value.messages);
293
+ var isMessageTree = (value) => isRecord(value) && Object.values(value).every(isMessageTreeValue);
294
+ var toDate2 = (value) => value instanceof Date ? value : new Date(value);
295
+ var warnedKeys = new Set;
296
+ var warnMissing = (locale, key) => {
297
+ const id = `${locale}:${key}`;
298
+ if (warnedKeys.has(id))
299
+ return;
300
+ warnedKeys.add(id);
301
+ console.warn(`[i18n] Missing message "${key}" for locale "${locale}"`);
302
+ };
303
+ var createTranslator = (payload) => {
304
+ const { locale, messages } = payload;
305
+ const t = (key, ...args) => {
306
+ const message = lookupMessage(messages, key);
307
+ if (message === undefined) {
308
+ warnMissing(locale, key);
309
+ return key;
310
+ }
311
+ const [params] = args;
312
+ return formatMessage(locale, message, isRecord(params) ? params : {});
313
+ };
314
+ const translator = {
315
+ dir: payload.dir,
316
+ locale,
317
+ t,
318
+ formatDate: (value, options) => getDateTimeFormat(locale, options).format(toDate2(value)),
319
+ formatList: (items, options) => getListFormat(locale, options).format(items),
320
+ formatNumber: (value, options) => getNumberFormat(locale, options).format(value),
321
+ formatRelativeTime: (value, unit, options) => getRelativeTimeFormat(locale, options).format(value, unit),
322
+ has: (key) => lookupMessage(messages, key) !== undefined
323
+ };
324
+ return translator;
325
+ };
326
+
327
+ // src/react/hooks/useI18n.ts
328
+ var I18nContext = createContext(null);
329
+ var I18nProvider = ({ value, children }) => createElement(I18nContext.Provider, { value }, children);
330
+ var useI18n = () => {
331
+ const payload = useContext(I18nContext);
332
+ if (payload === null) {
333
+ throw new Error("useI18n must be used within an I18nProvider");
334
+ }
335
+ return useMemo(() => createTranslator(payload), [payload]);
336
+ };
2
337
  // src/react/hooks/useIslandStore.ts
3
338
  import { useSyncExternalStore } from "react";
4
339
 
@@ -105,14 +440,14 @@ var useIslandStore = (store, selector) => useSyncExternalStore((listener) => sub
105
440
  }), () => readIslandStore(store, selector), () => getIslandStoreServerSnapshot(store, selector));
106
441
  // src/react/hooks/useMediaQuery.ts
107
442
  import {
108
- createContext,
109
- useContext,
443
+ createContext as createContext2,
444
+ useContext as useContext2,
110
445
  useSyncExternalStore as useSyncExternalStore2
111
446
  } from "react";
112
- var UserAgentContext = createContext(null);
447
+ var UserAgentContext = createContext2(null);
113
448
  var UserAgentProvider = UserAgentContext.Provider;
114
449
  var useUserAgentType = () => {
115
- const context = useContext(UserAgentContext);
450
+ const context = useContext2(UserAgentContext);
116
451
  if (context === null) {
117
452
  throw new Error("useMediaQuery must be used within a UserAgentProvider");
118
453
  }
@@ -188,6 +523,20 @@ var useMediaQuery = (customBreakpoints = defaultBreakpoints) => {
188
523
  // src/react/hooks/usePrefetch.ts
189
524
  import { useCallback, useEffect, useRef } from "react";
190
525
 
526
+ // src/dev/client/cspNonce.ts
527
+ var applyPageNonce = (element) => {
528
+ const nonce = readPageNonce();
529
+ if (nonce)
530
+ element.nonce = nonce;
531
+ return element;
532
+ };
533
+ var readPageNonce = () => {
534
+ if (typeof document === "undefined")
535
+ return;
536
+ const carrier = document.querySelector("script[nonce], style[nonce]");
537
+ return carrier?.nonce || undefined;
538
+ };
539
+
191
540
  // src/client/prefetch.ts
192
541
  var PREFETCH_CACHE_LIMIT = 16;
193
542
  var HOVER_DEBOUNCE_MS = 250;
@@ -206,7 +555,7 @@ var prefetchedStyles = new Set;
206
555
  var liveSpeculationRules = new Map;
207
556
  var offlineResponse = () => new Response(null, { status: 0 });
208
557
  var storageKind = (kind) => kind === "route" ? "document" : kind;
209
- var cacheKey = (kind, url) => `${storageKind(kind)}:${url}`;
558
+ var cacheKey2 = (kind, url) => `${storageKind(kind)}:${url}`;
210
559
  var resolveHref = (url) => {
211
560
  if (typeof window === "undefined")
212
561
  return url;
@@ -379,13 +728,13 @@ var preloadModule = (href) => {
379
728
  injectLink("modulepreload", href);
380
729
  return true;
381
730
  };
382
- var isRecord = (value) => typeof value === "object" && value !== null;
731
+ var isRecord2 = (value) => typeof value === "object" && value !== null;
383
732
  var isHref = (value) => typeof value === "string" && value.length > 0;
384
733
  var warmRouteDataAssets = (envelope) => {
385
- if (!isRecord(envelope))
734
+ if (!isRecord2(envelope))
386
735
  return;
387
736
  const { assets } = envelope;
388
- if (!isRecord(assets))
737
+ if (!isRecord2(assets))
389
738
  return;
390
739
  const { client, css, index } = assets;
391
740
  for (const href of [index, client].filter(isHref))
@@ -431,7 +780,7 @@ var prefetch = (url, options = {}) => {
431
780
  prefetch(url, { kind: "data" });
432
781
  return;
433
782
  }
434
- const key = cacheKey(kind, url);
783
+ const key = cacheKey2(kind, url);
435
784
  const existing = cache.get(key);
436
785
  if (existing) {
437
786
  touch(key, existing);
@@ -462,7 +811,7 @@ var speculate = (url) => {
462
811
  liveSpeculationRules.get(oldest.value)?.remove();
463
812
  liveSpeculationRules.delete(oldest.value);
464
813
  }
465
- const script = document.createElement("script");
814
+ const script = applyPageNonce(document.createElement("script"));
466
815
  script.type = "speculationrules";
467
816
  script.textContent = JSON.stringify({
468
817
  prerender: [{ eagerness: "immediate", urls: [url] }]
@@ -481,6 +830,7 @@ var scheduleHoverPrefetch = (url, options = {}) => {
481
830
  prefetch(url, { kind: options.kind ?? "route" });
482
831
  if (options.prerender)
483
832
  speculate(url);
833
+ options.onPrefetch?.();
484
834
  }, HOVER_DEBOUNCE_MS);
485
835
  return {
486
836
  cancel: () => window.clearTimeout(timer)
@@ -495,8 +845,10 @@ var handleIntersections = (entries) => {
495
845
  const target = viewportTargets.get(entry.target);
496
846
  viewportObserver?.unobserve(entry.target);
497
847
  viewportTargets.delete(entry.target);
498
- if (target)
499
- prefetch(target.url, target.options);
848
+ if (!target)
849
+ continue;
850
+ prefetch(target.url, { kind: target.options.kind });
851
+ target.options.onVisible?.();
500
852
  }
501
853
  };
502
854
  var getViewportObserver = () => {
@@ -576,12 +928,126 @@ var usePrefetch = (href, options = {}) => {
576
928
  ref: elementRef
577
929
  };
578
930
  };
931
+ // src/react/hooks/useFormAction.ts
932
+ import {
933
+ useCallback as useCallback2,
934
+ useEffect as useEffect2,
935
+ useRef as useRef2,
936
+ useState
937
+ } from "react";
938
+
939
+ // src/client/formActions.ts
940
+ var failure = (message) => ({
941
+ errors: {},
942
+ message,
943
+ status: "error"
944
+ });
945
+ var readPayload = async (response) => {
946
+ try {
947
+ const payload = await response.json();
948
+ return payload;
949
+ } catch {
950
+ return;
951
+ }
952
+ };
953
+ var formActionReducer = (path) => async (_previous, body) => submitFormAction(path, body);
954
+ var submitFormAction = async (path, body, options = {}) => {
955
+ const response = await fetch(path, {
956
+ body,
957
+ credentials: "same-origin",
958
+ headers: { accept: "application/json", [ACTION_REQUEST_HEADER]: "1" },
959
+ method: "POST",
960
+ signal: options.signal
961
+ }).catch((error) => {
962
+ if (options.signal?.aborted)
963
+ throw error;
964
+ return;
965
+ });
966
+ if (!response) {
967
+ const result = failure("Network error: the form was not sent.");
968
+ return result;
969
+ }
970
+ const payload = await readPayload(response);
971
+ if (isActionResult(payload))
972
+ return payload;
973
+ const result = failure(`The server could not handle the form (HTTP ${response.status}).`);
974
+ return result;
975
+ };
976
+
977
+ // src/react/hooks/useFormAction.ts
978
+ var IDLE = { status: "idle" };
979
+ var submitterOf = (event) => {
980
+ const { nativeEvent } = event;
981
+ return "submitter" in nativeEvent && nativeEvent.submitter instanceof HTMLElement ? nativeEvent.submitter : null;
982
+ };
983
+ var useFormAction = (path, options = {}) => {
984
+ const [state, setState] = useState(() => options.initialState ?? IDLE);
985
+ const [pending, setPending] = useState(false);
986
+ const controllerRef = useRef2(null);
987
+ const resetOnSuccess = options.resetOnSuccess !== false;
988
+ useEffect2(() => () => controllerRef.current?.abort(), []);
989
+ const submit = useCallback2(async (body) => {
990
+ controllerRef.current?.abort();
991
+ const controller = new AbortController;
992
+ controllerRef.current = controller;
993
+ setPending(true);
994
+ try {
995
+ const result = await submitFormAction(path, body, {
996
+ signal: controller.signal
997
+ });
998
+ setState(result);
999
+ if (result.status === "success" && result.redirect)
1000
+ window.location.assign(result.redirect);
1001
+ return result;
1002
+ } finally {
1003
+ if (controllerRef.current === controller)
1004
+ setPending(false);
1005
+ }
1006
+ }, [path]);
1007
+ const onSubmit = useCallback2((event) => {
1008
+ event.preventDefault();
1009
+ const form = event.currentTarget;
1010
+ const body = new FormData(form, submitterOf(event));
1011
+ const clearOnSuccess = async () => {
1012
+ const result = await submit(body);
1013
+ if (result.status === "success" && !result.redirect && resetOnSuccess)
1014
+ form.reset();
1015
+ };
1016
+ clearOnSuccess().catch(() => {
1017
+ return;
1018
+ });
1019
+ }, [resetOnSuccess, submit]);
1020
+ const reset = useCallback2(() => setState(IDLE), []);
1021
+ const errors = state.status === "error" ? state.errors : {};
1022
+ const values = state.status === "error" ? state.values ?? {} : {};
1023
+ return {
1024
+ data: state.status === "success" ? state.data : undefined,
1025
+ errors,
1026
+ formProps: {
1027
+ action: path,
1028
+ encType: "multipart/form-data",
1029
+ method: "post",
1030
+ onSubmit
1031
+ },
1032
+ message: state.status === "error" ? state.message : undefined,
1033
+ pending,
1034
+ reset,
1035
+ state,
1036
+ submit,
1037
+ values
1038
+ };
1039
+ };
579
1040
  export {
1041
+ I18nProvider,
580
1042
  UserAgentProvider,
1043
+ formActionReducer,
1044
+ submitFormAction,
1045
+ useFormAction,
1046
+ useI18n,
581
1047
  useIslandStore,
582
1048
  useMediaQuery,
583
1049
  usePrefetch
584
1050
  };
585
1051
 
586
- //# debugId=6C56035ACADC29DB64756E2164756E21
1052
+ //# debugId=B1E13CF34C32092B64756E2164756E21
587
1053
  //# sourceMappingURL=index.js.map