void 0.1.6 → 0.7.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 (333) hide show
  1. package/AGENT_PROMPT.md +15 -0
  2. package/README.md +62 -123
  3. package/dist/auth-BdsJ0Aff.d.mts +43 -0
  4. package/dist/auth-cmd-Dx8oPKZC.mjs +43 -0
  5. package/dist/auth-migrations-BAtAck2g.mjs +117 -0
  6. package/dist/better-auth-shared-C9_GHSkR.d.mts +71 -0
  7. package/dist/better-auth-shared-CdYmQGry.mjs +163 -0
  8. package/dist/cache-W82I8ihI.mjs +47 -0
  9. package/dist/cancel-deploy-BOBTqqh0.mjs +59 -0
  10. package/dist/cf-access-Dee5cXxL.mjs +22 -0
  11. package/dist/chunk-DJd-R1mw.mjs +34 -0
  12. package/dist/cli/cli.d.mts +1 -0
  13. package/dist/cli/cli.mjs +1807 -0
  14. package/dist/client-snXOjrp1.mjs +565 -0
  15. package/dist/collect-CjeZgz5D.mjs +55 -0
  16. package/dist/config-BIa9HwVX.mjs +573 -0
  17. package/dist/config-BzM9Dy7T.mjs +37 -0
  18. package/dist/config-CvHtTM0q.mjs +30 -0
  19. package/dist/create-project-BIA15W7z.mjs +90 -0
  20. package/dist/db-DsRoMcfN.mjs +895 -0
  21. package/dist/defer-DcxEsVH1.mjs +49 -0
  22. package/dist/delete-DAP6yDc7.mjs +64 -0
  23. package/dist/deploy-BPKblFx6.mjs +2424 -0
  24. package/dist/discover-B7FkXBLB.mjs +40 -0
  25. package/dist/dist-DUyXJLkq.mjs +2667 -0
  26. package/dist/dist-Dayj3gCK.mjs +1287 -0
  27. package/dist/domain-BGofcQ6I.mjs +79 -0
  28. package/dist/dotenv-DwO4ti0Z.mjs +173 -0
  29. package/dist/drizzle-NnudE_UN.mjs +232 -0
  30. package/dist/env-CyG3tvU0.mjs +301 -0
  31. package/dist/env-helpers-Dr9Y7RnE.d.mts +52 -0
  32. package/dist/env-raw-BDL4TvdN.mjs +32 -0
  33. package/dist/env-types-DknSA4SO.mjs +64 -0
  34. package/dist/env-validation-DJKjR_8q.mjs +163 -0
  35. package/dist/fetch-error-BQ8sZ5Nd.mjs +266 -0
  36. package/dist/fetch-error-CVZ5CGA-.d.mts +20 -0
  37. package/dist/gen-U0Ktr4Zd.mjs +761 -0
  38. package/dist/handler-B0ds0OHJ.d.mts +269 -0
  39. package/dist/head-P-egrtFE.d.mts +45 -0
  40. package/dist/headers-DCXc7mDs.mjs +279 -0
  41. package/dist/index.d.mts +32 -0
  42. package/dist/index.mjs +4695 -0
  43. package/dist/init-C7wS5iGP.mjs +2625 -0
  44. package/dist/link-p2R6NbgN.mjs +49 -0
  45. package/dist/list-Bfel-QLc.mjs +113 -0
  46. package/dist/log-DXdqnmhF.mjs +26 -0
  47. package/dist/login-CkcXUiIu.mjs +72 -0
  48. package/dist/logs-DmkrRvx6.mjs +98 -0
  49. package/dist/magic-string.es-D6g9UnIy.mjs +1011 -0
  50. package/dist/mcp-CaQzfeUi.mjs +373 -0
  51. package/dist/node-DDfXj10V.mjs +54 -0
  52. package/dist/output-BwlcIYSR.mjs +139 -0
  53. package/dist/pages/client.d.mts +198 -0
  54. package/dist/pages/client.mjs +980 -0
  55. package/dist/pages/head-client.d.mts +15 -0
  56. package/dist/pages/head-client.mjs +90 -0
  57. package/dist/pages/head.d.mts +2 -0
  58. package/dist/pages/head.mjs +112 -0
  59. package/dist/pages/index.d.mts +38 -0
  60. package/dist/pages/index.mjs +76 -0
  61. package/dist/pages/islands-plugin.d.mts +50 -0
  62. package/dist/pages/islands-plugin.mjs +195 -0
  63. package/dist/pages/prefetch.d.mts +31 -0
  64. package/dist/pages/prefetch.mjs +90 -0
  65. package/dist/pages/protocol.d.mts +3 -0
  66. package/dist/pages/protocol.mjs +193 -0
  67. package/dist/pages/serialize.d.mts +10 -0
  68. package/dist/pages/serialize.mjs +14 -0
  69. package/dist/pathe.M-eThtNZ-D-kmWkCS.mjs +150 -0
  70. package/dist/plugin-inference-oZ6Ybu2_.mjs +2447 -0
  71. package/dist/prepare-BAtWufvm.mjs +99 -0
  72. package/dist/preset-D4I73kT4.mjs +221 -0
  73. package/dist/project-TqORyHn8.mjs +72 -0
  74. package/dist/project-cmd-B7lQp3F3.mjs +67 -0
  75. package/dist/project-slug-CKam8lF9.mjs +11 -0
  76. package/dist/project-tsconfig-DfkESbDL.mjs +63 -0
  77. package/dist/protocol-BWzXs2A2.d.mts +34 -0
  78. package/dist/providers-B3aMxWzP.mjs +67 -0
  79. package/dist/resolve-project-Br5BR03U.mjs +29 -0
  80. package/dist/rollback-gyC59l7U.mjs +92 -0
  81. package/dist/route-types-DReF1gUY.mjs +255 -0
  82. package/dist/routes-stub.d.mts +55 -0
  83. package/dist/routes-stub.mjs +1 -0
  84. package/dist/runner-6Ep3fNQu.mjs +123 -0
  85. package/dist/runner-pg-D0wWHYnr.mjs +57 -0
  86. package/dist/runtime/ai.d.mts +127 -0
  87. package/dist/runtime/ai.mjs +348 -0
  88. package/dist/runtime/auth-client-react.d.mts +8 -0
  89. package/dist/runtime/auth-client-react.mjs +6 -0
  90. package/dist/runtime/auth-client-solid.d.mts +8 -0
  91. package/dist/runtime/auth-client-solid.mjs +6 -0
  92. package/dist/runtime/auth-client-svelte.d.mts +8 -0
  93. package/dist/runtime/auth-client-svelte.mjs +6 -0
  94. package/dist/runtime/auth-client-vue.d.mts +8 -0
  95. package/dist/runtime/auth-client-vue.mjs +6 -0
  96. package/dist/runtime/auth-client.d.mts +8 -0
  97. package/dist/runtime/auth-client.mjs +6 -0
  98. package/dist/runtime/auth.d.mts +2 -0
  99. package/dist/runtime/auth.mjs +22 -0
  100. package/dist/runtime/better-auth-pg.d.mts +11 -0
  101. package/dist/runtime/better-auth-pg.mjs +51 -0
  102. package/dist/runtime/better-auth.d.mts +11 -0
  103. package/dist/runtime/better-auth.mjs +33 -0
  104. package/dist/runtime/client.d.mts +6 -0
  105. package/dist/runtime/client.mjs +5 -0
  106. package/dist/runtime/db-pg.d.mts +2 -0
  107. package/dist/runtime/db-pg.mjs +1 -0
  108. package/dist/runtime/db.d.mts +17 -0
  109. package/dist/runtime/db.mjs +30 -0
  110. package/dist/runtime/drizzle-arktype.d.mts +1 -0
  111. package/dist/runtime/drizzle-arktype.mjs +2 -0
  112. package/dist/runtime/drizzle-valibot.d.mts +1 -0
  113. package/dist/runtime/drizzle-valibot.mjs +2 -0
  114. package/dist/runtime/drizzle-zod.d.mts +1 -0
  115. package/dist/runtime/drizzle-zod.mjs +2 -0
  116. package/dist/runtime/env-helpers.d.mts +2 -0
  117. package/dist/runtime/env-helpers.mjs +173 -0
  118. package/dist/runtime/env-public-client.d.mts +22 -0
  119. package/dist/runtime/env-public-client.mjs +54 -0
  120. package/dist/runtime/env-public.d.mts +143 -0
  121. package/dist/runtime/env-public.mjs +366 -0
  122. package/dist/runtime/env.d.mts +13 -0
  123. package/dist/runtime/env.mjs +51 -0
  124. package/dist/runtime/fetch-stream.d.mts +51 -0
  125. package/dist/runtime/fetch-stream.mjs +81 -0
  126. package/dist/runtime/fetch.d.mts +59 -0
  127. package/dist/runtime/fetch.mjs +18 -0
  128. package/dist/runtime/handler.d.mts +3 -0
  129. package/dist/runtime/handler.mjs +85 -0
  130. package/dist/runtime/isr.d.mts +26 -0
  131. package/dist/runtime/isr.mjs +43 -0
  132. package/dist/runtime/kv.d.mts +48 -0
  133. package/dist/runtime/kv.mjs +106 -0
  134. package/dist/runtime/log.d.mts +24 -0
  135. package/dist/runtime/log.mjs +31 -0
  136. package/dist/runtime/migration-handler-pg.d.mts +6 -0
  137. package/dist/runtime/migration-handler-pg.mjs +85 -0
  138. package/dist/runtime/migration-handler.d.mts +19 -0
  139. package/dist/runtime/migration-handler.mjs +92 -0
  140. package/dist/runtime/queues.d.mts +7 -0
  141. package/dist/runtime/queues.mjs +8 -0
  142. package/dist/runtime/remote/binding-handler.d.mts +15 -0
  143. package/dist/runtime/remote/binding-handler.mjs +208 -0
  144. package/dist/runtime/remote/index.d.mts +8 -0
  145. package/dist/runtime/remote/index.mjs +461 -0
  146. package/dist/runtime/response.d.mts +14 -0
  147. package/dist/runtime/response.mjs +30 -0
  148. package/dist/runtime/sandbox.d.mts +17 -0
  149. package/dist/runtime/sandbox.mjs +19 -0
  150. package/dist/runtime/schema-d1.d.mts +1 -0
  151. package/dist/runtime/schema-d1.mjs +2 -0
  152. package/dist/runtime/schema-pg.d.mts +1 -0
  153. package/dist/runtime/schema-pg.mjs +2 -0
  154. package/dist/runtime/seed.d.mts +30 -0
  155. package/dist/runtime/seed.mjs +6 -0
  156. package/dist/runtime/storage.d.mts +7 -0
  157. package/dist/runtime/storage.mjs +14 -0
  158. package/dist/runtime/validator.d.mts +2 -0
  159. package/dist/runtime/validator.mjs +72 -0
  160. package/dist/runtime/ws-server.d.mts +26 -0
  161. package/dist/runtime/ws-server.mjs +296 -0
  162. package/dist/runtime/ws.d.mts +123 -0
  163. package/dist/runtime/ws.mjs +103 -0
  164. package/dist/scan-Ba4hFwlH.mjs +324 -0
  165. package/dist/scan-C6HMEIdW.mjs +318 -0
  166. package/dist/secret-CeRSukgM.mjs +109 -0
  167. package/dist/skills-ipldjlKE.mjs +62 -0
  168. package/dist/standard-schema-9CRjx-uR.d.mts +42 -0
  169. package/dist/subcommand-prompt-BKjuNAPb.mjs +349 -0
  170. package/dist/sveltekit.d.mts +20 -0
  171. package/dist/sveltekit.mjs +61 -0
  172. package/dist/types-mHOEwpW4.d.mts +57 -0
  173. package/dist/validate-CaMavMxu.mjs +146 -0
  174. package/dist/yarn-pnp-BFqMV_bl.mjs +196 -0
  175. package/getting-started-prompt.txt +26 -0
  176. package/package.json +322 -30
  177. package/schema.json +364 -0
  178. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
  179. package/skills/void/SKILL.md +75 -0
  180. package/skills/void/command/void.md +7 -0
  181. package/skills/void/docs/guide/ai.md +235 -0
  182. package/skills/void/docs/guide/app-types.md +103 -0
  183. package/skills/void/docs/guide/auth.md +257 -0
  184. package/skills/void/docs/guide/database/d1.md +106 -0
  185. package/skills/void/docs/guide/database/postgresql.md +106 -0
  186. package/skills/void/docs/guide/database.md +418 -0
  187. package/skills/void/docs/guide/deployment.md +98 -0
  188. package/skills/void/docs/guide/edge/headers.md +79 -0
  189. package/skills/void/docs/guide/edge/prerendering.md +83 -0
  190. package/skills/void/docs/guide/edge/redirects.md +116 -0
  191. package/skills/void/docs/guide/edge/revalidation.md +131 -0
  192. package/skills/void/docs/guide/edge/rewrites.md +354 -0
  193. package/skills/void/docs/guide/edge/static-assets.md +72 -0
  194. package/skills/void/docs/guide/env-vars.md +298 -0
  195. package/skills/void/docs/guide/index.md +80 -0
  196. package/skills/void/docs/guide/jobs.md +91 -0
  197. package/skills/void/docs/guide/kv.md +107 -0
  198. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +419 -0
  199. package/skills/void/docs/guide/pages-routing/head.md +130 -0
  200. package/skills/void/docs/guide/pages-routing/islands.md +405 -0
  201. package/skills/void/docs/guide/pages-routing/layouts.md +362 -0
  202. package/skills/void/docs/guide/pages-routing/loaders.md +267 -0
  203. package/skills/void/docs/guide/pages-routing/markdown.md +625 -0
  204. package/skills/void/docs/guide/pages-routing/overview.md +236 -0
  205. package/skills/void/docs/guide/pages-routing/view-transitions.md +140 -0
  206. package/skills/void/docs/guide/queues.md +140 -0
  207. package/skills/void/docs/guide/quickstart.md +233 -0
  208. package/skills/void/docs/guide/remote-dev.md +67 -0
  209. package/skills/void/docs/guide/sandboxes.md +82 -0
  210. package/skills/void/docs/guide/server-routing.md +246 -0
  211. package/skills/void/docs/guide/ssg.md +74 -0
  212. package/skills/void/docs/guide/ssr.md +105 -0
  213. package/skills/void/docs/guide/storage.md +67 -0
  214. package/skills/void/docs/guide/type-safety.md +179 -0
  215. package/skills/void/docs/guide/typed-fetch.md +113 -0
  216. package/skills/void/docs/guide/websockets.md +190 -0
  217. package/skills/void/docs/index.md +48 -0
  218. package/skills/void/docs/integrations/agents.md +84 -0
  219. package/skills/void/docs/integrations/cloudflare.md +284 -0
  220. package/skills/void/docs/integrations/frameworks/analog.md +182 -0
  221. package/skills/void/docs/integrations/frameworks/astro.md +197 -0
  222. package/skills/void/docs/integrations/frameworks/nuxt.md +164 -0
  223. package/skills/void/docs/integrations/frameworks/overview.md +136 -0
  224. package/skills/void/docs/integrations/frameworks/react-router.md +137 -0
  225. package/skills/void/docs/integrations/frameworks/sveltekit.md +191 -0
  226. package/skills/void/docs/integrations/frameworks/tanstack-start.md +140 -0
  227. package/skills/void/docs/integrations/hono.md +97 -0
  228. package/skills/void/docs/integrations/nodejs-bun-deno.md +210 -0
  229. package/skills/void/docs/node_modules/@iconify/vue/README.md +408 -0
  230. package/skills/void/docs/node_modules/@iconify/vue/offline/readme.md +5 -0
  231. package/skills/void/docs/node_modules/@voidzero-dev/vitepress-theme/README.md +103 -0
  232. package/skills/void/docs/node_modules/oxc-minify/README.md +78 -0
  233. package/skills/void/docs/node_modules/reka-ui/README.md +80 -0
  234. package/skills/void/docs/node_modules/vitepress/README.md +28 -0
  235. package/skills/void/docs/node_modules/vitepress/template/api-examples.md +49 -0
  236. package/skills/void/docs/node_modules/vitepress/template/index.md +28 -0
  237. package/skills/void/docs/node_modules/vitepress/template/markdown-examples.md +85 -0
  238. package/skills/void/docs/node_modules/vitepress-plugin-group-icons/README.md +101 -0
  239. package/skills/void/docs/node_modules/void/AGENTS.md +204 -0
  240. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +15 -0
  241. package/skills/void/docs/node_modules/void/README.md +89 -0
  242. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/CHANGELOG.md +591 -0
  243. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/README.md +375 -0
  244. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/sandbox/README.md +174 -0
  245. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/vite-plugin/README.md +37 -0
  246. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/workers-types/README.md +135 -0
  247. package/skills/void/docs/node_modules/void/node_modules/@electric-sql/pglite/README.md +189 -0
  248. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/CHANGELOG.md +143 -0
  249. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/README.md +1272 -0
  250. package/skills/void/docs/node_modules/void/node_modules/@napi-rs/keyring/README.md +19 -0
  251. package/skills/void/docs/node_modules/void/node_modules/@types/better-sqlite3/README.md +15 -0
  252. package/skills/void/docs/node_modules/void/node_modules/@types/node/README.md +15 -0
  253. package/skills/void/docs/node_modules/void/node_modules/@types/pg/README.md +15 -0
  254. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/README.md +22 -0
  255. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/vendor/vscode-jsonrpc/README.md +69 -0
  256. package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +152 -0
  257. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/engine-javascript/README.md +9 -0
  258. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/transformers/README.md +9 -0
  259. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@types/node/README.md +15 -0
  260. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/CHANGELOG.md +24 -0
  261. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/README.md +565 -0
  262. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-exit/README.md +124 -0
  263. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-anchor/README.md +600 -0
  264. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-attrs/README.md +386 -0
  265. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-container/README.md +95 -0
  266. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-emoji/README.md +101 -0
  267. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathe/README.md +73 -0
  268. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/shiki/README.md +15 -0
  269. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tinyglobby/README.md +25 -0
  270. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tsdown/README.md +55 -0
  271. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/LICENSE.md +2230 -0
  272. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/README.md +20 -0
  273. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vue/README.md +58 -0
  274. package/skills/void/docs/node_modules/void/node_modules/arktype/README.md +165 -0
  275. package/skills/void/docs/node_modules/void/node_modules/better-auth/LICENSE.md +20 -0
  276. package/skills/void/docs/node_modules/void/node_modules/better-auth/README.md +32 -0
  277. package/skills/void/docs/node_modules/void/node_modules/better-sqlite3/README.md +99 -0
  278. package/skills/void/docs/node_modules/void/node_modules/blake3-jit/README.md +108 -0
  279. package/skills/void/docs/node_modules/void/node_modules/drizzle-arktype/README.md +51 -0
  280. package/skills/void/docs/node_modules/void/node_modules/drizzle-kit/README.md +79 -0
  281. package/skills/void/docs/node_modules/void/node_modules/drizzle-orm/README.md +44 -0
  282. package/skills/void/docs/node_modules/void/node_modules/drizzle-valibot/README.md +51 -0
  283. package/skills/void/docs/node_modules/void/node_modules/drizzle-zod/README.md +65 -0
  284. package/skills/void/docs/node_modules/void/node_modules/es-module-lexer/README.md +390 -0
  285. package/skills/void/docs/node_modules/void/node_modules/estree-walker/README.md +48 -0
  286. package/skills/void/docs/node_modules/void/node_modules/hono/README.md +85 -0
  287. package/skills/void/docs/node_modules/void/node_modules/ignore/README.md +452 -0
  288. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/CHANGELOG.md +76 -0
  289. package/{LICENSE → skills/void/docs/node_modules/void/node_modules/jsonc-parser/LICENSE.md} +21 -21
  290. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/README.md +364 -0
  291. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/SECURITY.md +41 -0
  292. package/skills/void/docs/node_modules/void/node_modules/magic-string/README.md +325 -0
  293. package/skills/void/docs/node_modules/void/node_modules/ofetch/README.md +398 -0
  294. package/skills/void/docs/node_modules/void/node_modules/pathe/README.md +73 -0
  295. package/skills/void/docs/node_modules/void/node_modules/pg/README.md +95 -0
  296. package/skills/void/docs/node_modules/void/node_modules/pglite-server/LICENSE.md +21 -0
  297. package/skills/void/docs/node_modules/void/node_modules/pglite-server/README.md +135 -0
  298. package/skills/void/docs/node_modules/void/node_modules/picocolors/README.md +21 -0
  299. package/skills/void/docs/node_modules/void/node_modules/tinyglobby/README.md +25 -0
  300. package/skills/void/docs/node_modules/void/node_modules/tsdown/README.md +55 -0
  301. package/skills/void/docs/node_modules/void/node_modules/valibot/LICENSE.md +9 -0
  302. package/skills/void/docs/node_modules/void/node_modules/valibot/README.md +94 -0
  303. package/skills/void/docs/node_modules/void/node_modules/vite/LICENSE.md +2230 -0
  304. package/skills/void/docs/node_modules/void/node_modules/vite/README.md +20 -0
  305. package/skills/void/docs/node_modules/void/node_modules/wrangler/README.md +63 -0
  306. package/skills/void/docs/node_modules/void/node_modules/zod/README.md +191 -0
  307. package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
  308. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +75 -0
  309. package/skills/void/docs/node_modules/void/skills/void/command/void.md +7 -0
  310. package/skills/void/docs/reference/api.md +917 -0
  311. package/skills/void/docs/reference/cli.md +561 -0
  312. package/skills/void/docs/reference/config.md +408 -0
  313. package/skills/void/docs/reference/resource-inference.md +149 -0
  314. package/skills/void/docs/reference/structure.md +176 -0
  315. package/.npmignore +0 -29
  316. package/.travis.yml +0 -9
  317. package/favicon.ico +0 -0
  318. package/index.js +0 -14
  319. package/lib/Job.js +0 -150
  320. package/lib/Void.js +0 -99
  321. package/lib/scan.js +0 -19
  322. package/test/credentials.js +0 -20
  323. package/test/job.js +0 -64
  324. package/test/static/dir1/test6.html +0 -0
  325. package/test/static/dir2/test7.html +0 -0
  326. package/test/static/dir2/test8.html +0 -0
  327. package/test/static/dir2/test9.html +0 -0
  328. package/test/static/test1.html +0 -0
  329. package/test/static/test2.html +0 -0
  330. package/test/static/test3.html +0 -0
  331. package/test/void.js +0 -31
  332. /package/{test/static/dir1/test4.html → skills/void/docs/integrations/auth-providers.md} +0 -0
  333. /package/{test/static/dir1/test5.html → skills/void/docs/integrations/payment-processors.md} +0 -0
@@ -0,0 +1,980 @@
1
+ import { applyClientHead, initClientHead } from "./head-client.mjs";
2
+ import { PrefetchCache, parseCacheFor } from "./prefetch.mjs";
3
+ //#region src/pages/action-result.ts
4
+ var VoidActionError = class extends Error {
5
+ body;
6
+ status;
7
+ statusText;
8
+ url;
9
+ constructor({ body, status, statusText, url }) {
10
+ super(statusText ? `Action failed with ${status} ${statusText}` : `Action failed with ${status}`);
11
+ this.name = "VoidActionError";
12
+ this.body = body;
13
+ this.status = status;
14
+ this.statusText = statusText;
15
+ this.url = url;
16
+ }
17
+ };
18
+ function categorizeActionError(status) {
19
+ switch (status) {
20
+ case 400:
21
+ case 402:
22
+ case 404:
23
+ case 408:
24
+ case 409:
25
+ case 412:
26
+ case 413:
27
+ case 415:
28
+ case 422:
29
+ case 429:
30
+ case 499: return "callSite";
31
+ default: return "boundary";
32
+ }
33
+ }
34
+ function isCallSiteActionError(error) {
35
+ return typeof error === "object" && error !== null && "name" in error && error.name === "VoidActionError" && "status" in error && typeof error.status === "number" && categorizeActionError(error.status) === "callSite";
36
+ }
37
+ function isAbortError(error) {
38
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
39
+ }
40
+ async function readActionErrorBody(response) {
41
+ const contentType = response.headers.get("content-type") || "";
42
+ try {
43
+ if (contentType.includes("application/json")) return await response.json();
44
+ return await response.text() || null;
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+ async function createActionErrorFromResponse(response, url) {
50
+ return new VoidActionError({
51
+ body: await readActionErrorBody(response),
52
+ status: response.status,
53
+ statusText: response.statusText,
54
+ url
55
+ });
56
+ }
57
+ //#endregion
58
+ //#region src/pages/navigation-engine.ts
59
+ const PAGE_DATA_SCRIPT_ID = "__VOID_PAGE_DATA__";
60
+ const STATIC_PAGE_DATA_PREFIX = "/_void/pages";
61
+ function isFile$1(value) {
62
+ return typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
63
+ }
64
+ function hasFiles$1(data) {
65
+ return isFile$1(data) || typeof data === "object" && data !== null && Object.values(data).some(hasFiles$1);
66
+ }
67
+ function objectToFormData$1(source, form, parentKey) {
68
+ form = form || new FormData();
69
+ for (const key in source) {
70
+ if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
71
+ const composed = parentKey ? parentKey + "[" + key + "]" : key;
72
+ const value = source[key];
73
+ if (value instanceof File) form.append(composed, value, value.name);
74
+ else if (value instanceof Blob) form.append(composed, value);
75
+ else if (typeof FileList !== "undefined" && value instanceof FileList) for (let i = 0; i < value.length; i++) form.append(composed + "[]", value[i], value[i].name);
76
+ else if (Array.isArray(value)) for (let i = 0; i < value.length; i++) objectToFormData$1({ [i]: value[i] }, form, composed);
77
+ else if (value instanceof Date) form.append(composed, value.toISOString());
78
+ else if (typeof value === "boolean") form.append(composed, value ? "1" : "0");
79
+ else if (typeof value === "string") form.append(composed, value);
80
+ else if (typeof value === "number") form.append(composed, String(value));
81
+ else if (value === null || value === void 0) form.append(composed, "");
82
+ else objectToFormData$1(value, form, composed);
83
+ }
84
+ return form;
85
+ }
86
+ function clonePageData(pageData) {
87
+ return JSON.parse(JSON.stringify(pageData));
88
+ }
89
+ function readInitialPageData(appEl) {
90
+ const scriptEl = document.getElementById(PAGE_DATA_SCRIPT_ID);
91
+ if (scriptEl?.textContent) return JSON.parse(scriptEl.textContent);
92
+ const legacyData = appEl.getAttribute("data-page");
93
+ if (legacyData) return JSON.parse(legacyData);
94
+ throw new Error("pages: Missing initial page payload.");
95
+ }
96
+ function parsePageDataFromHtml(html) {
97
+ const scriptEl = new DOMParser().parseFromString(html, "text/html").getElementById(PAGE_DATA_SCRIPT_ID);
98
+ if (!scriptEl?.textContent) return null;
99
+ try {
100
+ return JSON.parse(scriptEl.textContent);
101
+ } catch {
102
+ return null;
103
+ }
104
+ }
105
+ function isAbortError$1(error) {
106
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
107
+ }
108
+ function abortError() {
109
+ return new DOMException("Navigation aborted", "AbortError");
110
+ }
111
+ function abortSignalPromise(signal) {
112
+ if (signal.aborted) return Promise.reject(abortError());
113
+ return new Promise((_resolve, reject) => {
114
+ signal.addEventListener("abort", () => reject(abortError()), { once: true });
115
+ });
116
+ }
117
+ async function fetchPageResponse(fetchUrl, init) {
118
+ try {
119
+ return await fetch(fetchUrl, init);
120
+ } catch (error) {
121
+ if (init.signal?.aborted || isAbortError$1(error)) throw abortError();
122
+ return null;
123
+ }
124
+ }
125
+ async function createPageNavigationEngine(config) {
126
+ const { adapter, components, layoutTree, routeMeta, matchRoute, staticPageData: STATIC_PAGE_DATA_ENABLED = false, staticPageDataFastPath: STATIC_PAGE_DATA_FAST_PATH = STATIC_PAGE_DATA_ENABLED, prefetchHoverDelay: PREFETCH_HOVER_DELAY, prefetchDefaultCacheFor: PREFETCH_DEFAULT_CACHE_FOR } = config;
127
+ const _prefetchCache = new PrefetchCache();
128
+ const _staticPageDataCacheKeys = /* @__PURE__ */ new Set();
129
+ let _nextNavigationId = 0;
130
+ let _pendingResource = null;
131
+ let _committedResource = null;
132
+ let _committedDeferredRegistry = null;
133
+ let _htmlDeferredRegistry = null;
134
+ let _currentFetchUrl = window.location.pathname + window.location.search;
135
+ let popStateHandler = null;
136
+ function getPageDataCacheKey(url, method = "GET") {
137
+ return `${method}:${url}`;
138
+ }
139
+ async function resolveComponent(id) {
140
+ const loader = components[id];
141
+ if (!loader) throw new Error(`pages: Unknown page component '${id}'.`);
142
+ return (await loader()).default;
143
+ }
144
+ async function resolveLayouts(componentId) {
145
+ const ids = layoutTree[componentId] || [];
146
+ return Promise.all(ids.map(async (id) => (await components[id]()).default));
147
+ }
148
+ function getStaticPageDataUrl(url) {
149
+ const { pathname } = new URL(url || "/", window.location.origin);
150
+ return `${STATIC_PAGE_DATA_PREFIX}/${pathname === "/" ? "index" : pathname.replace(/^\/+/, "")}.json`;
151
+ }
152
+ function isUsablePageData(pageData, matchedId) {
153
+ return typeof pageData === "object" && pageData !== null && "component" in pageData && typeof pageData.component === "string" && "props" in pageData && typeof pageData.props === "object" && pageData.props !== null && typeof pageData.component === "string" && pageData.component === matchedId && !routeMeta[pageData.component]?.island && Boolean(components[pageData.component]);
154
+ }
155
+ class DeferredRegistry {
156
+ active = true;
157
+ keyRefs = {};
158
+ props = {};
159
+ groups = {};
160
+ preservedSource = null;
161
+ preservedKeys = null;
162
+ setupPending(pageData) {
163
+ this.props = pageData.props;
164
+ this.keyRefs = {};
165
+ this.groups = {};
166
+ if (!pageData.deferredKeys) return;
167
+ for (const [key, group] of Object.entries(pageData.deferredKeys)) {
168
+ const ref = adapter.createDeferred();
169
+ this.keyRefs[key] = ref;
170
+ this.props[key] = ref;
171
+ (this.groups[group] ??= []).push(key);
172
+ }
173
+ }
174
+ setupResolved(pageData) {
175
+ this.props = pageData.props;
176
+ this.keyRefs = {};
177
+ this.groups = {};
178
+ if (!pageData.deferredKeys) return;
179
+ for (const [key, group] of Object.entries(pageData.deferredKeys)) {
180
+ const ref = adapter.createDeferred();
181
+ const updated = adapter.resolveDeferred(ref, pageData.props[key]);
182
+ this.keyRefs[key] = updated;
183
+ this.props[key] = updated;
184
+ (this.groups[group] ??= []).push(key);
185
+ }
186
+ }
187
+ preserveValuesFrom(source, pageData) {
188
+ if (!source) return;
189
+ const keys = source.applyPreservedValues(pageData);
190
+ if (keys) {
191
+ this.preservedSource = source;
192
+ this.preservedKeys = keys;
193
+ }
194
+ }
195
+ commitPreservedValues(source, pageData) {
196
+ if (!this.preservedSource || this.preservedSource !== source || !this.preservedKeys) return null;
197
+ this.preservedSource.retainOnly(this.preservedKeys, pageData.props);
198
+ return this.preservedSource;
199
+ }
200
+ applyPreservedValues(pageData) {
201
+ let keys = null;
202
+ for (const key of Object.keys(this.keyRefs)) if (pageData.props[key] === null && this.props[key] !== void 0) {
203
+ pageData.props[key] = this.props[key];
204
+ (keys ??= /* @__PURE__ */ new Set()).add(key);
205
+ }
206
+ return keys;
207
+ }
208
+ resolve(group, data, error) {
209
+ if (!this.active) return;
210
+ if (data !== void 0) if (typeof data === "object" && data !== null && !Array.isArray(data)) {
211
+ let resolvedAny = false;
212
+ for (const [key, value] of Object.entries(data)) if (this.keyRefs[key]) {
213
+ this.resolveKey(key, value);
214
+ resolvedAny = true;
215
+ }
216
+ if (!resolvedAny) this.resolveGroup(group, data);
217
+ } else this.resolveGroup(group, data);
218
+ else if (error !== void 0) this.rejectGroup(group, typeof error === "string" ? error : String(error));
219
+ adapter.onDeferredUpdate?.(this.props);
220
+ }
221
+ rejectPending(error, notify = true) {
222
+ if (!this.active) return;
223
+ for (const [key, ref] of Object.entries(this.keyRefs)) if (adapter.isLoading(ref)) {
224
+ const updated = adapter.rejectDeferred(ref, error);
225
+ this.keyRefs[key] = updated;
226
+ this.props[key] = updated;
227
+ }
228
+ if (notify) adapter.onDeferredUpdate?.(this.props);
229
+ }
230
+ dispose() {
231
+ if (!this.active) return;
232
+ this.rejectPending("Navigation disposed before deferred props resolved", false);
233
+ this.active = false;
234
+ }
235
+ retainOnly(keys, props) {
236
+ const keyRefs = {};
237
+ const groups = {};
238
+ for (const [key, ref] of Object.entries(this.keyRefs)) if (keys.has(key)) {
239
+ keyRefs[key] = ref;
240
+ props[key] = this.props[key];
241
+ } else if (adapter.isLoading(ref)) adapter.rejectDeferred(ref, "Navigation disposed before deferred props resolved");
242
+ for (const [group, groupKeys] of Object.entries(this.groups)) {
243
+ const preservedGroupKeys = groupKeys.filter((key) => keys.has(key));
244
+ if (preservedGroupKeys.length > 0) groups[group] = preservedGroupKeys;
245
+ }
246
+ this.props = props;
247
+ this.keyRefs = keyRefs;
248
+ this.groups = groups;
249
+ adapter.onDeferredUpdate?.(this.props);
250
+ }
251
+ resolveGroup(group, data) {
252
+ const keys = this.groups[group] ?? (this.keyRefs[group] ? [group] : []);
253
+ for (const key of keys) this.resolveKey(key, data);
254
+ }
255
+ resolveKey(key, value) {
256
+ const ref = this.keyRefs[key];
257
+ if (!ref || !adapter.isLoading(ref)) return;
258
+ const updated = adapter.resolveDeferred(ref, value);
259
+ this.keyRefs[key] = updated;
260
+ this.props[key] = updated;
261
+ }
262
+ rejectGroup(group, error) {
263
+ const keys = this.groups[group] ?? Object.keys(this.keyRefs);
264
+ for (const key of keys) {
265
+ const ref = this.keyRefs[key];
266
+ if (ref && adapter.isLoading(ref)) {
267
+ const updated = adapter.rejectDeferred(ref, error);
268
+ this.keyRefs[key] = updated;
269
+ this.props[key] = updated;
270
+ }
271
+ }
272
+ }
273
+ }
274
+ const _resourceDeferredRegistries = /* @__PURE__ */ new WeakMap();
275
+ const _preservedDeferredResources = /* @__PURE__ */ new WeakMap();
276
+ async function loadStaticPageDataFile(fetchUrl, signal) {
277
+ const matchedId = matchRoute(fetchUrl || window.location.pathname + window.location.search);
278
+ if (!matchedId || routeMeta[matchedId]?.island || !components[matchedId]) return null;
279
+ try {
280
+ const pageDataResponse = await fetch(getStaticPageDataUrl(fetchUrl), {
281
+ headers: { Accept: "application/json" },
282
+ signal
283
+ });
284
+ if (pageDataResponse.ok) {
285
+ const pageData = await pageDataResponse.json();
286
+ if (isUsablePageData(pageData, matchedId)) return {
287
+ pageData,
288
+ resolvedDeferred: true
289
+ };
290
+ }
291
+ } catch (error) {
292
+ if (signal?.aborted || isAbortError$1(error)) throw abortError();
293
+ }
294
+ return null;
295
+ }
296
+ async function loadStaticPageData(fetchUrl, response, signal, verifyPageResponse = false) {
297
+ if (!response.ok) return null;
298
+ const matchedId = matchRoute(fetchUrl || window.location.pathname + window.location.search);
299
+ if (!matchedId || routeMeta[matchedId]?.island || !components[matchedId]) return null;
300
+ const contentType = response.headers.get("content-type") || "";
301
+ if (contentType && !contentType.includes("text/html")) return null;
302
+ if (verifyPageResponse) {
303
+ const pageData = parsePageDataFromHtml(await response.text());
304
+ if (!isUsablePageData(pageData, matchedId)) return null;
305
+ if (!pageData.deferredKeys) return {
306
+ pageData,
307
+ resolvedDeferred: false
308
+ };
309
+ return loadStaticPageDataFile(fetchUrl, signal);
310
+ }
311
+ const filePageData = await loadStaticPageDataFile(fetchUrl, signal);
312
+ if (filePageData) return filePageData;
313
+ const pageData = parsePageDataFromHtml(await response.text());
314
+ if (!isUsablePageData(pageData, matchedId) || pageData.deferredKeys) return null;
315
+ return {
316
+ pageData,
317
+ resolvedDeferred: false
318
+ };
319
+ }
320
+ const deferredWindow = window;
321
+ deferredWindow.__resolveDeferred = (group, data) => _htmlDeferredRegistry?.resolve(group, data, void 0);
322
+ deferredWindow.__rejectDeferred = (group, error) => _htmlDeferredRegistry?.resolve(group, void 0, error);
323
+ function commitHashNavigation(effectiveFetchUrl, hash, options, writeHistory) {
324
+ _currentFetchUrl = effectiveFetchUrl;
325
+ if (writeHistory) if (options.replace) history.replaceState({}, "", effectiveFetchUrl + hash);
326
+ else {
327
+ history.replaceState({
328
+ scrollX: window.scrollX,
329
+ scrollY: window.scrollY
330
+ }, "");
331
+ history.pushState({}, "", effectiveFetchUrl + hash);
332
+ }
333
+ if (options._scrollPosition) {
334
+ window.scrollTo(options._scrollPosition.x, options._scrollPosition.y);
335
+ return;
336
+ }
337
+ if (hash) {
338
+ const el = document.getElementById(hash.slice(1));
339
+ if (el) {
340
+ el.scrollIntoView();
341
+ return;
342
+ }
343
+ }
344
+ window.scrollTo(0, 0);
345
+ }
346
+ async function loadNavigationShell(id, url, fetchUrl, method, hash, options, signal, commitTarget, deferredRegistry) {
347
+ if (method !== "GET") {
348
+ _prefetchCache.flushAll();
349
+ _staticPageDataCacheKeys.clear();
350
+ }
351
+ const headers = {
352
+ "X-VoidPages": "true",
353
+ Accept: "application/json"
354
+ };
355
+ const fetchOptions = {
356
+ method,
357
+ headers,
358
+ signal
359
+ };
360
+ if (options.data && method !== "GET") if (hasFiles$1(options.data)) fetchOptions.body = objectToFormData$1(options.data);
361
+ else {
362
+ headers["Content-Type"] = "application/json";
363
+ fetchOptions.body = JSON.stringify(options.data);
364
+ }
365
+ let pageData;
366
+ const cacheEntry = method === "GET" ? _prefetchCache.get(fetchUrl, method) : null;
367
+ if (cacheEntry) {
368
+ const cachedPageData = await cacheEntry.response;
369
+ _prefetchCache.consume(fetchUrl, method);
370
+ if (cachedPageData === null) {
371
+ window.location.href = url;
372
+ return;
373
+ }
374
+ pageData = _staticPageDataCacheKeys.has(getPageDataCacheKey(fetchUrl, method)) ? clonePageData(cachedPageData) : cachedPageData;
375
+ deferredRegistry.setupResolved(pageData);
376
+ if (!_prefetchCache.isFresh(cacheEntry)) {
377
+ const bgHeaders = {
378
+ "X-VoidPages": "true",
379
+ Accept: "application/json",
380
+ Purpose: "prefetch"
381
+ };
382
+ const bgFetch = (STATIC_PAGE_DATA_ENABLED && STATIC_PAGE_DATA_FAST_PATH && method === "GET" ? loadStaticPageDataFile(fetchUrl).then((result) => result?.pageData) : Promise.resolve(void 0)).then((pageData) => {
383
+ if (pageData !== void 0) return pageData;
384
+ return fetchPageResponse(fetchUrl, {
385
+ method,
386
+ headers: bgHeaders
387
+ }).then(async (r) => {
388
+ if (!r || r.redirected) return null;
389
+ if (!r.headers.get("X-VoidPages")) return (await loadStaticPageData(fetchUrl, r, void 0, !STATIC_PAGE_DATA_FAST_PATH))?.pageData ?? null;
390
+ return r.json();
391
+ });
392
+ });
393
+ _prefetchCache.set(fetchUrl, method, bgFetch, PREFETCH_DEFAULT_CACHE_FOR);
394
+ }
395
+ } else {
396
+ if (method === "GET" && STATIC_PAGE_DATA_ENABLED && STATIC_PAGE_DATA_FAST_PATH) {
397
+ const staticPageData = await loadStaticPageDataFile(fetchUrl, signal);
398
+ if (staticPageData) {
399
+ pageData = staticPageData.pageData;
400
+ _staticPageDataCacheKeys.add(getPageDataCacheKey(fetchUrl, method));
401
+ _prefetchCache.set(fetchUrl, method, Promise.resolve(clonePageData(pageData)), PREFETCH_DEFAULT_CACHE_FOR);
402
+ if (staticPageData.resolvedDeferred) deferredRegistry.setupResolved(pageData);
403
+ else deferredRegistry.setupPending(pageData);
404
+ }
405
+ }
406
+ const response = pageData === void 0 ? method === "GET" ? await fetchPageResponse(fetchUrl, fetchOptions) : await fetch(fetchUrl, fetchOptions) : null;
407
+ if (pageData === void 0 && !response) {
408
+ window.location.href = url;
409
+ return;
410
+ }
411
+ if (response?.redirected) {
412
+ const redirectUrl = new URL(response.url, window.location.origin);
413
+ if (redirectUrl.origin !== window.location.origin) {
414
+ window.location.href = method === "GET" ? url : response.url;
415
+ return;
416
+ }
417
+ commitTarget.fetchUrl = redirectUrl.pathname + redirectUrl.search;
418
+ commitTarget.hash = redirectUrl.hash;
419
+ return loadNavigationShell(id, redirectUrl.pathname + redirectUrl.search + redirectUrl.hash, redirectUrl.pathname + redirectUrl.search, "GET", redirectUrl.hash, {
420
+ preserveScroll: options.preserveScroll,
421
+ preserveState: options.preserveState,
422
+ replace: options.replace,
423
+ viewTransition: options.viewTransition
424
+ }, signal, commitTarget, deferredRegistry);
425
+ }
426
+ if (response && method !== "GET" && !response.ok) throw await createActionErrorFromResponse(response, fetchUrl);
427
+ if (response && !response.headers.get("X-VoidPages")) if (method === "GET") {
428
+ const staticPageData = await loadStaticPageData(fetchUrl, response, signal, !STATIC_PAGE_DATA_FAST_PATH);
429
+ if (staticPageData) {
430
+ pageData = staticPageData.pageData;
431
+ if (staticPageData.resolvedDeferred) deferredRegistry.setupResolved(pageData);
432
+ else deferredRegistry.setupPending(pageData);
433
+ } else {
434
+ window.location.href = url;
435
+ return;
436
+ }
437
+ } else {
438
+ window.location.href = url;
439
+ return;
440
+ }
441
+ const contentType = response?.headers.get("content-type") || "";
442
+ if (pageData !== void 0) {} else if (contentType.includes("application/x-ndjson")) {
443
+ const reader = response.body.getReader();
444
+ const decoder = new TextDecoder();
445
+ let buffer = "";
446
+ let firstLine = true;
447
+ const processLines = () => {
448
+ let newlineIdx;
449
+ while ((newlineIdx = buffer.indexOf("\n")) !== -1) {
450
+ const line = buffer.slice(0, newlineIdx);
451
+ buffer = buffer.slice(newlineIdx + 1);
452
+ if (!line) continue;
453
+ if (firstLine) {
454
+ pageData = JSON.parse(line);
455
+ deferredRegistry.setupPending(pageData);
456
+ firstLine = false;
457
+ } else {
458
+ const msg = JSON.parse(line);
459
+ if (msg.__deferred) deferredRegistry.resolve(msg.__deferred, msg.data, msg.error);
460
+ }
461
+ }
462
+ };
463
+ while (firstLine) {
464
+ const { done, value } = await reader.read();
465
+ if (done) break;
466
+ buffer += decoder.decode(value, { stream: true });
467
+ processLines();
468
+ }
469
+ (async () => {
470
+ try {
471
+ while (!signal.aborted) {
472
+ const { done, value } = await reader.read();
473
+ if (done) break;
474
+ buffer += decoder.decode(value, { stream: true });
475
+ processLines();
476
+ }
477
+ if (buffer.trim()) processLines();
478
+ } catch (e) {
479
+ if (!(e instanceof Error) || e.name !== "AbortError") deferredRegistry.rejectPending("Stream closed before resolution");
480
+ }
481
+ })();
482
+ } else {
483
+ pageData = await response.json();
484
+ deferredRegistry.setupPending(pageData);
485
+ }
486
+ }
487
+ if (!pageData) throw new Error("pages: Missing page payload.");
488
+ if (method !== "GET") deferredRegistry.preserveValuesFrom(_committedDeferredRegistry, pageData);
489
+ const [component, layouts] = await Promise.race([Promise.all([resolveComponent(pageData.component), resolveLayouts(pageData.component)]), abortSignalPromise(signal)]);
490
+ if (id !== _nextNavigationId && signal.aborted) throw abortError();
491
+ return {
492
+ pageData,
493
+ component,
494
+ layouts
495
+ };
496
+ }
497
+ function makeCommit(commitTarget, options, shell, deferredRegistry, resourceId, getResource) {
498
+ let committed = false;
499
+ return async () => {
500
+ if (committed) return;
501
+ committed = true;
502
+ const result = await shell;
503
+ if (!result) return;
504
+ if (_pendingResource?.id === resourceId) _pendingResource = null;
505
+ const previousResource = _committedResource;
506
+ const previousDeferredRegistry = _committedDeferredRegistry;
507
+ const preservedDeferredRegistry = deferredRegistry.commitPreservedValues(previousDeferredRegistry, result.pageData);
508
+ _committedResource = getResource();
509
+ const previousResourceOwnsPreservedRegistry = Boolean(previousResource && preservedDeferredRegistry && _resourceDeferredRegistries.get(previousResource) === preservedDeferredRegistry);
510
+ if (previousResource && previousResource !== _committedResource && !previousResourceOwnsPreservedRegistry) previousResource.dispose();
511
+ if (previousResource && preservedDeferredRegistry && previousResourceOwnsPreservedRegistry) _preservedDeferredResources.set(preservedDeferredRegistry, previousResource);
512
+ _committedDeferredRegistry = preservedDeferredRegistry ?? deferredRegistry;
513
+ const preservedDeferredResource = previousDeferredRegistry ? _preservedDeferredResources.get(previousDeferredRegistry) : void 0;
514
+ if (previousDeferredRegistry && previousDeferredRegistry !== _committedDeferredRegistry) {
515
+ previousDeferredRegistry.dispose();
516
+ if (preservedDeferredResource && preservedDeferredResource !== previousResource && preservedDeferredResource !== _committedResource) preservedDeferredResource.dispose();
517
+ _preservedDeferredResources.delete(previousDeferredRegistry);
518
+ }
519
+ if (preservedDeferredRegistry && preservedDeferredRegistry !== deferredRegistry) deferredRegistry.dispose();
520
+ applyClientHead(result.pageData.head);
521
+ _currentFetchUrl = commitTarget.fetchUrl;
522
+ if (!options.preserveState) {
523
+ const historyUrl = commitTarget.fetchUrl + commitTarget.hash;
524
+ if (options.replace) history.replaceState({}, "", historyUrl);
525
+ else {
526
+ history.replaceState({
527
+ scrollX: window.scrollX,
528
+ scrollY: window.scrollY
529
+ }, "");
530
+ history.pushState({}, "", historyUrl);
531
+ }
532
+ }
533
+ const doScroll = () => {
534
+ if (options.preserveScroll) return;
535
+ if (options._scrollPosition) window.scrollTo(options._scrollPosition.x, options._scrollPosition.y);
536
+ else if (commitTarget.hash) {
537
+ const el = document.getElementById(commitTarget.hash.slice(1));
538
+ if (el) el.scrollIntoView();
539
+ else window.scrollTo(0, 0);
540
+ } else window.scrollTo(0, 0);
541
+ };
542
+ requestAnimationFrame(doScroll);
543
+ };
544
+ }
545
+ const initialPageData = readInitialPageData(document.getElementById("app"));
546
+ const [initialComponent, initialLayouts] = await Promise.all([resolveComponent(initialPageData.component), resolveLayouts(initialPageData.component)]);
547
+ const initialDeferredRegistry = new DeferredRegistry();
548
+ initialDeferredRegistry.setupPending(initialPageData);
549
+ _committedDeferredRegistry = initialDeferredRegistry;
550
+ _htmlDeferredRegistry = initialDeferredRegistry;
551
+ return {
552
+ _hoverDelay: PREFETCH_HOVER_DELAY,
553
+ initialPageData,
554
+ initialComponent,
555
+ initialLayouts,
556
+ prepareVisit(url, options = {}) {
557
+ const hashIndex = url.indexOf("#");
558
+ const hash = hashIndex !== -1 ? url.slice(hashIndex) : "";
559
+ const fetchUrl = hashIndex !== -1 ? url.slice(0, hashIndex) : url;
560
+ const currentPath = window.location.pathname + window.location.search;
561
+ const effectiveFetchUrl = fetchUrl || currentPath;
562
+ const method = (options.method || "GET").toUpperCase();
563
+ const id = ++_nextNavigationId;
564
+ const hashNavigationBaseUrl = options._popstate ? _currentFetchUrl : currentPath;
565
+ _pendingResource?.abort();
566
+ _pendingResource = null;
567
+ if (effectiveFetchUrl === hashNavigationBaseUrl && method === "GET" && !options.data && Boolean(hash || options._popstate)) {
568
+ commitHashNavigation(effectiveFetchUrl, hash, options, !options._popstate && !options.preserveState);
569
+ return {
570
+ id,
571
+ url,
572
+ fetchUrl: effectiveFetchUrl,
573
+ hash,
574
+ method,
575
+ options,
576
+ immediate: true,
577
+ shell: Promise.resolve(void 0),
578
+ abort() {},
579
+ async commit() {},
580
+ dispose() {}
581
+ };
582
+ }
583
+ const controller = new AbortController();
584
+ const deferredRegistry = new DeferredRegistry();
585
+ const commitTarget = {
586
+ fetchUrl: effectiveFetchUrl,
587
+ hash
588
+ };
589
+ const shell = loadNavigationShell(id, url, effectiveFetchUrl, method, hash, options, controller.signal, commitTarget, deferredRegistry);
590
+ let commitResource = async () => {};
591
+ const resource = {
592
+ id,
593
+ url,
594
+ fetchUrl: effectiveFetchUrl,
595
+ hash,
596
+ method,
597
+ options,
598
+ immediate: false,
599
+ shell,
600
+ abort() {
601
+ controller.abort(abortError());
602
+ deferredRegistry.dispose();
603
+ },
604
+ commit() {
605
+ return commitResource();
606
+ },
607
+ dispose() {
608
+ controller.abort(abortError());
609
+ deferredRegistry.dispose();
610
+ }
611
+ };
612
+ _resourceDeferredRegistries.set(resource, deferredRegistry);
613
+ commitResource = makeCommit(commitTarget, options, shell, deferredRegistry, id, () => resource);
614
+ _pendingResource = resource;
615
+ return resource;
616
+ },
617
+ prefetch(url, options = {}) {
618
+ const method = (options.method || "GET").toUpperCase();
619
+ if (method !== "GET") throw new Error("Void Router: prefetch() only supports GET requests.");
620
+ const id = matchRoute(url);
621
+ if (!id) return Promise.resolve(void 0);
622
+ if (routeMeta[id]?.island) {
623
+ if (!document.querySelector("link[rel=\"prefetch\"][href=\"" + url + "\"]")) {
624
+ const link = document.createElement("link");
625
+ link.rel = "prefetch";
626
+ link.href = url;
627
+ link.as = "document";
628
+ document.head.appendChild(link);
629
+ }
630
+ return Promise.resolve(void 0);
631
+ }
632
+ if (components[id]) components[id]();
633
+ const layoutIds = layoutTree[id] || [];
634
+ for (const lid of layoutIds) if (components[lid]) components[lid]();
635
+ const hashIdx = url.indexOf("#");
636
+ const prefetchUrl = hashIdx !== -1 ? url.slice(0, hashIdx) : url;
637
+ const existing = _prefetchCache.get(prefetchUrl, method);
638
+ if (existing) return existing.response;
639
+ const ttl = options.cacheFor ? parseCacheFor(options.cacheFor) : PREFETCH_DEFAULT_CACHE_FOR;
640
+ const headers = {
641
+ "X-VoidPages": "true",
642
+ Accept: "application/json",
643
+ Purpose: "prefetch"
644
+ };
645
+ const fetchPromise = (STATIC_PAGE_DATA_ENABLED && STATIC_PAGE_DATA_FAST_PATH && method === "GET" ? loadStaticPageDataFile(prefetchUrl).then((result) => result?.pageData) : Promise.resolve(void 0)).then((pageData) => {
646
+ if (pageData !== void 0) return pageData;
647
+ return fetchPageResponse(prefetchUrl, {
648
+ method,
649
+ headers
650
+ }).then((r) => {
651
+ if (!r || r.redirected) return null;
652
+ if (!r.headers.get("X-VoidPages")) {
653
+ if (method !== "GET") return null;
654
+ return loadStaticPageData(prefetchUrl, r, void 0, !STATIC_PAGE_DATA_FAST_PATH).then((result) => result?.pageData ?? null);
655
+ }
656
+ return r.json();
657
+ });
658
+ });
659
+ _prefetchCache.set(prefetchUrl, method, fetchPromise, ttl);
660
+ return fetchPromise;
661
+ },
662
+ flush(url, method = "GET") {
663
+ _prefetchCache.flush(url, method);
664
+ _staticPageDataCacheKeys.delete(getPageDataCacheKey(url, method));
665
+ },
666
+ flushAll() {
667
+ _prefetchCache.flushAll();
668
+ _staticPageDataCacheKeys.clear();
669
+ },
670
+ setPopStateHandler(handler) {
671
+ popStateHandler = handler;
672
+ },
673
+ start() {
674
+ history.scrollRestoration = "manual";
675
+ history.replaceState({
676
+ scrollX: window.scrollX,
677
+ scrollY: window.scrollY
678
+ }, "");
679
+ initClientHead(initialPageData.head);
680
+ if (deferredWindow.__deferredQueue) {
681
+ for (const entry of deferredWindow.__deferredQueue) if (entry.length === 3) _htmlDeferredRegistry?.resolve(entry[0], void 0, entry[2]);
682
+ else _htmlDeferredRegistry?.resolve(entry[0], entry[1], void 0);
683
+ delete deferredWindow.__deferredQueue;
684
+ }
685
+ window.addEventListener("popstate", (e) => {
686
+ const saved = e.state;
687
+ const url = window.location.pathname + window.location.search + window.location.hash;
688
+ const options = {
689
+ preserveState: true,
690
+ _scrollPosition: saved ? {
691
+ x: saved.scrollX ?? 0,
692
+ y: saved.scrollY ?? 0
693
+ } : null,
694
+ _popstate: true
695
+ };
696
+ if (popStateHandler) popStateHandler(url, options);
697
+ });
698
+ }
699
+ };
700
+ }
701
+ //#endregion
702
+ //#region src/pages/form-value-equality.ts
703
+ function isPlainObject(value) {
704
+ if (value === null || typeof value !== "object") return false;
705
+ const prototype = Object.getPrototypeOf(value);
706
+ return prototype === Object.prototype || prototype === null;
707
+ }
708
+ function isEqualFormValue(a, b) {
709
+ if (Object.is(a, b)) return true;
710
+ if (Array.isArray(a) || Array.isArray(b)) {
711
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
712
+ return a.every((value, index) => isEqualFormValue(value, b[index]));
713
+ }
714
+ if (isPlainObject(a) || isPlainObject(b)) {
715
+ if (!isPlainObject(a) || !isPlainObject(b)) return false;
716
+ const aKeys = Object.keys(a);
717
+ const bKeys = Object.keys(b);
718
+ if (aKeys.length !== bKeys.length) return false;
719
+ return aKeys.every((key) => Object.hasOwn(b, key) && isEqualFormValue(a[key], b[key]));
720
+ }
721
+ return false;
722
+ }
723
+ //#endregion
724
+ //#region src/pages/client.ts
725
+ function currentUrl() {
726
+ return window.location.pathname + window.location.search + window.location.hash;
727
+ }
728
+ function getUrlOrigin() {
729
+ return typeof window === "undefined" ? "http://localhost" : window.location.origin;
730
+ }
731
+ function toUrl(value) {
732
+ return value instanceof URL ? new URL(value.href) : new URL(value || "/", getUrlOrigin());
733
+ }
734
+ function normalizeUrl(value) {
735
+ if (typeof value === "string" && value.startsWith("#")) return value;
736
+ const url = toUrl(value);
737
+ return url.origin === getUrlOrigin() ? url.pathname + url.search + url.hash : url.href;
738
+ }
739
+ function navigationMethod(method) {
740
+ const normalized = method.toUpperCase();
741
+ if (normalized === "POST" || normalized === "PUT" || normalized === "PATCH" || normalized === "DELETE") return normalized;
742
+ return "GET";
743
+ }
744
+ function navigationStateFor(url, method) {
745
+ const normalized = navigationMethod(method);
746
+ return {
747
+ state: normalized === "GET" ? "loading" : "submitting",
748
+ location: toUrl(url),
749
+ method: normalized
750
+ };
751
+ }
752
+ function idleNavigationState() {
753
+ return {
754
+ state: "idle",
755
+ location: null,
756
+ method: null
757
+ };
758
+ }
759
+ function createRouterFacade(router, getCurrentUrl) {
760
+ return {
761
+ get _hoverDelay() {
762
+ return router._hoverDelay;
763
+ },
764
+ get url() {
765
+ return toUrl(getCurrentUrl());
766
+ },
767
+ get path() {
768
+ return this.url.pathname;
769
+ },
770
+ get query() {
771
+ return this.url.searchParams;
772
+ },
773
+ visit(url, options = {}) {
774
+ return router.visit(url, options);
775
+ },
776
+ refresh(options = {}) {
777
+ return router.refresh(options);
778
+ },
779
+ prefetch(url, options = {}) {
780
+ return router.prefetch(url, options);
781
+ },
782
+ flush(url, method = "GET") {
783
+ router.flush(url, method);
784
+ },
785
+ flushAll() {
786
+ router.flushAll();
787
+ }
788
+ };
789
+ }
790
+ function createSsrRouter(url = "/") {
791
+ return {
792
+ _hoverDelay: 75,
793
+ get url() {
794
+ return toUrl(url);
795
+ },
796
+ get path() {
797
+ return this.url.pathname;
798
+ },
799
+ get query() {
800
+ return this.url.searchParams;
801
+ },
802
+ visit() {
803
+ throw new Error("Void Router: visit() is not available during SSR.");
804
+ },
805
+ refresh() {
806
+ throw new Error("Void Router: refresh() is not available during SSR.");
807
+ },
808
+ prefetch() {
809
+ throw new Error("Void Router: prefetch() is not available during SSR.");
810
+ },
811
+ flush() {
812
+ throw new Error("Void Router: flush() is not available during SSR.");
813
+ },
814
+ flushAll() {
815
+ throw new Error("Void Router: flushAll() is not available during SSR.");
816
+ }
817
+ };
818
+ }
819
+ function isFile(value) {
820
+ return typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
821
+ }
822
+ function hasFiles(data) {
823
+ return isFile(data) || typeof data === "object" && data !== null && Object.values(data).some(hasFiles);
824
+ }
825
+ function objectToFormData(source, form, parentKey) {
826
+ form = form || new FormData();
827
+ for (const key in source) {
828
+ if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
829
+ const composed = parentKey ? parentKey + "[" + key + "]" : key;
830
+ const value = source[key];
831
+ if (value instanceof File) form.append(composed, value, value.name);
832
+ else if (value instanceof Blob) form.append(composed, value);
833
+ else if (typeof FileList !== "undefined" && value instanceof FileList) for (let i = 0; i < value.length; i++) form.append(composed + "[]", value[i], value[i].name);
834
+ else if (Array.isArray(value)) for (let i = 0; i < value.length; i++) objectToFormData({ [i]: value[i] }, form, composed);
835
+ else if (value instanceof Date) form.append(composed, value.toISOString());
836
+ else if (typeof value === "boolean") form.append(composed, value ? "1" : "0");
837
+ else if (typeof value === "string") form.append(composed, value);
838
+ else if (typeof value === "number") form.append(composed, String(value));
839
+ else if (value === null || value === void 0) form.append(composed, "");
840
+ else objectToFormData(value, form, composed);
841
+ }
842
+ return form;
843
+ }
844
+ const ssrProxy = createSsrRouter();
845
+ async function submitAction(router, url, options) {
846
+ try {
847
+ const pageData = await router.visit(url, options);
848
+ if (typeof pageData === "object" && pageData !== null && "errors" in pageData && pageData.errors) return {
849
+ ok: false,
850
+ error: new VoidActionError({
851
+ body: { errors: pageData.errors },
852
+ status: 422,
853
+ statusText: "Unprocessable Content",
854
+ url
855
+ })
856
+ };
857
+ return {
858
+ ok: true,
859
+ pageData
860
+ };
861
+ } catch (error) {
862
+ if (isCallSiteActionError(error)) return {
863
+ ok: false,
864
+ error
865
+ };
866
+ throw error;
867
+ }
868
+ }
869
+ async function createVoidRouter(config) {
870
+ {
871
+ const engine = await createPageNavigationEngine(config);
872
+ let routeUrl = currentUrl();
873
+ let activeNavigationId = null;
874
+ const setRouteUrl = (url) => {
875
+ routeUrl = url;
876
+ config.onRouteChange?.(url);
877
+ };
878
+ const setNavigation = (navigation) => {
879
+ config.onNavigationChange?.(navigation);
880
+ };
881
+ async function applyNavigationResource(resource) {
882
+ activeNavigationId = resource.id;
883
+ setNavigation(navigationStateFor(resource.fetchUrl + resource.hash, resource.method));
884
+ try {
885
+ const result = await resource.shell;
886
+ if (!result) return;
887
+ const applyUpdate = () => config.adapter.applyUpdate(result.pageData, result.component, result.layouts);
888
+ if ((resource.options.viewTransition ?? config.viewTransitions) && document.startViewTransition) await document.startViewTransition(() => applyUpdate()).updateCallbackDone;
889
+ else await applyUpdate();
890
+ await resource.commit();
891
+ if (activeNavigationId === resource.id) setRouteUrl(currentUrl());
892
+ return result.pageData;
893
+ } finally {
894
+ if (activeNavigationId === resource.id) {
895
+ activeNavigationId = null;
896
+ setRouteUrl(currentUrl());
897
+ setNavigation(idleNavigationState());
898
+ }
899
+ }
900
+ }
901
+ const rawRouter = {
902
+ _hoverDelay: engine._hoverDelay,
903
+ get url() {
904
+ return toUrl(routeUrl);
905
+ },
906
+ get path() {
907
+ return this.url.pathname;
908
+ },
909
+ get query() {
910
+ return this.url.searchParams;
911
+ },
912
+ visit(url, options = {}) {
913
+ return applyNavigationResource(engine.prepareVisit(normalizeUrl(url), options));
914
+ },
915
+ refresh(options = {}) {
916
+ return rawRouter.visit(window.location.pathname + window.location.search, {
917
+ preserveState: true,
918
+ preserveScroll: true,
919
+ ...options
920
+ });
921
+ },
922
+ prefetch(url, options = {}) {
923
+ return engine.prefetch(normalizeUrl(url), options);
924
+ },
925
+ flush(url, method = "GET") {
926
+ engine.flush(normalizeUrl(url), method);
927
+ },
928
+ flushAll() {
929
+ engine.flushAll();
930
+ }
931
+ };
932
+ const router = createRouterFacade(rawRouter, () => routeUrl);
933
+ engine.setPopStateHandler((url, options) => {
934
+ router.visit(url, options);
935
+ });
936
+ return {
937
+ router,
938
+ initialPageData: engine.initialPageData,
939
+ initialComponent: engine.initialComponent,
940
+ initialLayouts: engine.initialLayouts,
941
+ start: engine.start
942
+ };
943
+ }
944
+ }
945
+ function scheduleHydration(el, loader, props, strategy, hydrateFn) {
946
+ const hydrate = () => loader().then((mod) => hydrateFn(el, mod, props));
947
+ if (strategy === "load") hydrate();
948
+ else if (strategy === "visible") {
949
+ const observer = new IntersectionObserver((entries) => {
950
+ if (entries[0].isIntersecting) {
951
+ observer.disconnect();
952
+ hydrate();
953
+ }
954
+ });
955
+ observer.observe(el);
956
+ } else if (strategy === "idle") (window.requestIdleCallback?.bind(window) ?? ((cb) => setTimeout(cb, 1)))(() => hydrate());
957
+ else if (strategy.startsWith("media:")) {
958
+ const query = strategy.slice(6);
959
+ const mql = matchMedia(query);
960
+ const check = () => {
961
+ if (mql.matches) {
962
+ mql.removeEventListener("change", check);
963
+ hydrate();
964
+ }
965
+ };
966
+ mql.addEventListener("change", check);
967
+ check();
968
+ }
969
+ }
970
+ function initIslands(islands, hydrateFn) {
971
+ document.querySelectorAll("[data-island]").forEach((el) => {
972
+ const id = el.getAttribute("data-island");
973
+ const props = JSON.parse(el.getAttribute("data-props") || "{}");
974
+ const strategy = el.getAttribute("data-hydrate") || "load";
975
+ const loader = islands[id];
976
+ if (loader) scheduleHydration(el, loader, props, strategy, hydrateFn);
977
+ });
978
+ }
979
+ //#endregion
980
+ export { VoidActionError, categorizeActionError, createPageNavigationEngine, createRouterFacade, createSsrRouter, createVoidRouter, hasFiles, idleNavigationState, initIslands, isAbortError, isCallSiteActionError, isEqualFormValue, isFile, objectToFormData, scheduleHydration, ssrProxy, submitAction };