@nifrajs/web 5.5.1 → 5.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 (481) hide show
  1. package/CHANGELOG.md +243 -0
  2. package/README.md +21 -11
  3. package/dist/boundary.d.ts +67 -7
  4. package/dist/boundary.d.ts.map +1 -1
  5. package/dist/boundary.js +6 -4
  6. package/dist/boundary.js.map +1 -1
  7. package/dist/build-plan.d.ts +3 -0
  8. package/dist/build-plan.d.ts.map +1 -1
  9. package/dist/build-plan.js.map +1 -1
  10. package/dist/build-vite.d.ts.map +1 -1
  11. package/dist/build-vite.js +2 -0
  12. package/dist/build-vite.js.map +1 -1
  13. package/dist/build.d.ts +9 -2
  14. package/dist/build.d.ts.map +1 -1
  15. package/dist/build.js +10 -0
  16. package/dist/build.js.map +1 -1
  17. package/dist/client.d.ts +3 -1
  18. package/dist/client.d.ts.map +1 -1
  19. package/dist/client.js +174 -23
  20. package/dist/client.js.map +1 -1
  21. package/dist/csp.d.ts +8 -0
  22. package/dist/csp.d.ts.map +1 -1
  23. package/dist/csp.js +11 -2
  24. package/dist/csp.js.map +1 -1
  25. package/dist/deferred.d.ts +6 -4
  26. package/dist/deferred.d.ts.map +1 -1
  27. package/dist/deferred.js +10 -6
  28. package/dist/deferred.js.map +1 -1
  29. package/dist/dev-feed.d.ts.map +1 -1
  30. package/dist/dev-feed.js +11 -2
  31. package/dist/dev-feed.js.map +1 -1
  32. package/dist/dev-session.d.ts.map +1 -1
  33. package/dist/dev-session.js +13 -6
  34. package/dist/dev-session.js.map +1 -1
  35. package/dist/dev.d.ts +4 -1
  36. package/dist/dev.d.ts.map +1 -1
  37. package/dist/dev.js +12 -5
  38. package/dist/dev.js.map +1 -1
  39. package/dist/diagnostic-catalog.d.ts +4 -0
  40. package/dist/diagnostic-catalog.d.ts.map +1 -1
  41. package/dist/diagnostic-catalog.js +48 -0
  42. package/dist/diagnostic-catalog.js.map +1 -1
  43. package/dist/diagnostic.d.ts +1 -1
  44. package/dist/diagnostic.d.ts.map +1 -1
  45. package/dist/diagnostic.js +1 -1
  46. package/dist/diagnostic.js.map +1 -1
  47. package/dist/fn.d.ts +5 -3
  48. package/dist/fn.d.ts.map +1 -1
  49. package/dist/fn.js +20 -5
  50. package/dist/fn.js.map +1 -1
  51. package/dist/fs.d.ts.map +1 -1
  52. package/dist/fs.js +13 -3
  53. package/dist/fs.js.map +1 -1
  54. package/dist/identity.d.ts +22 -0
  55. package/dist/identity.d.ts.map +1 -0
  56. package/dist/identity.js +60 -0
  57. package/dist/identity.js.map +1 -0
  58. package/dist/index.d.ts +8 -6
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +6 -3
  61. package/dist/index.js.map +1 -1
  62. package/dist/internal/cdn/cloudflare.d.ts +2 -1
  63. package/dist/internal/cdn/cloudflare.d.ts.map +1 -1
  64. package/dist/internal/cdn/cloudflare.js +2 -1
  65. package/dist/internal/cdn/cloudflare.js.map +1 -1
  66. package/dist/internal/certified-components.d.ts +1 -1
  67. package/dist/internal/certified-components.js +1 -1
  68. package/dist/internal/codegen.d.ts +11 -10
  69. package/dist/internal/codegen.d.ts.map +1 -1
  70. package/dist/internal/codegen.js +73 -10
  71. package/dist/internal/codegen.js.map +1 -1
  72. package/dist/internal/dev-websocket.d.ts +73 -0
  73. package/dist/internal/dev-websocket.d.ts.map +1 -0
  74. package/dist/internal/dev-websocket.js +145 -0
  75. package/dist/internal/dev-websocket.js.map +1 -0
  76. package/dist/internal/hole-runtime.d.ts +66 -0
  77. package/dist/internal/hole-runtime.d.ts.map +1 -0
  78. package/dist/internal/hole-runtime.js +211 -0
  79. package/dist/internal/hole-runtime.js.map +1 -0
  80. package/dist/internal/identity-epoch.d.ts +50 -0
  81. package/dist/internal/identity-epoch.d.ts.map +1 -0
  82. package/dist/internal/identity-epoch.js +180 -0
  83. package/dist/internal/identity-epoch.js.map +1 -0
  84. package/dist/internal/invalidation-contract.d.ts +23 -0
  85. package/dist/internal/invalidation-contract.d.ts.map +1 -0
  86. package/dist/internal/invalidation-contract.js +11 -0
  87. package/dist/internal/invalidation-contract.js.map +1 -0
  88. package/dist/internal/invalidation.d.ts +62 -0
  89. package/dist/internal/invalidation.d.ts.map +1 -0
  90. package/dist/internal/invalidation.js +149 -0
  91. package/dist/internal/invalidation.js.map +1 -0
  92. package/dist/internal/island-bindings.d.ts +51 -0
  93. package/dist/internal/island-bindings.d.ts.map +1 -0
  94. package/dist/internal/island-bindings.js +147 -0
  95. package/dist/internal/island-bindings.js.map +1 -0
  96. package/dist/internal/island-list.d.ts +26 -0
  97. package/dist/internal/island-list.d.ts.map +1 -0
  98. package/dist/internal/island-list.js +78 -0
  99. package/dist/internal/island-list.js.map +1 -0
  100. package/dist/internal/island-mount.d.ts +4 -0
  101. package/dist/internal/island-mount.d.ts.map +1 -0
  102. package/dist/internal/island-mount.js +66 -0
  103. package/dist/internal/island-mount.js.map +1 -0
  104. package/dist/internal/island-owner.d.ts +5 -0
  105. package/dist/internal/island-owner.d.ts.map +1 -0
  106. package/dist/internal/island-owner.js +20 -0
  107. package/dist/internal/island-owner.js.map +1 -0
  108. package/dist/internal/island-resource.d.ts +30 -0
  109. package/dist/internal/island-resource.d.ts.map +1 -0
  110. package/dist/internal/island-resource.js +57 -0
  111. package/dist/internal/island-resource.js.map +1 -0
  112. package/dist/internal/island-signals.d.ts +51 -0
  113. package/dist/internal/island-signals.d.ts.map +1 -0
  114. package/dist/internal/island-signals.js +220 -0
  115. package/dist/internal/island-signals.js.map +1 -0
  116. package/dist/internal/keep-alive-table.d.ts +23 -0
  117. package/dist/internal/keep-alive-table.d.ts.map +1 -0
  118. package/dist/internal/keep-alive-table.js +53 -0
  119. package/dist/internal/keep-alive-table.js.map +1 -0
  120. package/dist/internal/live-contract.d.ts +101 -0
  121. package/dist/internal/live-contract.d.ts.map +1 -0
  122. package/dist/internal/live-contract.js +5 -0
  123. package/dist/internal/live-contract.js.map +1 -0
  124. package/dist/internal/live-queries.d.ts +22 -0
  125. package/dist/internal/live-queries.d.ts.map +1 -0
  126. package/dist/internal/live-queries.js +54 -0
  127. package/dist/internal/live-queries.js.map +1 -0
  128. package/dist/internal/page-events.d.ts +10 -0
  129. package/dist/internal/page-events.d.ts.map +1 -0
  130. package/dist/internal/page-events.js +26 -0
  131. package/dist/internal/page-events.js.map +1 -0
  132. package/dist/internal/page-execution.d.ts +16 -1
  133. package/dist/internal/page-execution.d.ts.map +1 -1
  134. package/dist/internal/page-execution.js +432 -31
  135. package/dist/internal/page-execution.js.map +1 -1
  136. package/dist/internal/parity.d.ts +3 -0
  137. package/dist/internal/parity.d.ts.map +1 -1
  138. package/dist/internal/parity.js +28 -5
  139. package/dist/internal/parity.js.map +1 -1
  140. package/dist/internal/ppr/admission.d.ts +83 -0
  141. package/dist/internal/ppr/admission.d.ts.map +1 -0
  142. package/dist/internal/ppr/admission.js +221 -0
  143. package/dist/internal/ppr/admission.js.map +1 -0
  144. package/dist/internal/ppr/canary.d.ts +24 -0
  145. package/dist/internal/ppr/canary.d.ts.map +1 -0
  146. package/dist/internal/ppr/canary.js +102 -0
  147. package/dist/internal/ppr/canary.js.map +1 -0
  148. package/dist/internal/ppr/compile-shell.d.ts +39 -0
  149. package/dist/internal/ppr/compile-shell.d.ts.map +1 -0
  150. package/dist/internal/ppr/compile-shell.js +298 -0
  151. package/dist/internal/ppr/compile-shell.js.map +1 -0
  152. package/dist/internal/ppr/contract.d.ts +177 -0
  153. package/dist/internal/ppr/contract.d.ts.map +1 -0
  154. package/dist/internal/ppr/contract.js +80 -0
  155. package/dist/internal/ppr/contract.js.map +1 -0
  156. package/dist/internal/ppr/frames.d.ts +71 -0
  157. package/dist/internal/ppr/frames.d.ts.map +1 -0
  158. package/dist/internal/ppr/frames.js +119 -0
  159. package/dist/internal/ppr/frames.js.map +1 -0
  160. package/dist/internal/ppr/integration.d.ts +19 -0
  161. package/dist/internal/ppr/integration.d.ts.map +1 -0
  162. package/dist/internal/ppr/integration.js +106 -0
  163. package/dist/internal/ppr/integration.js.map +1 -0
  164. package/dist/internal/ppr/options.d.ts +96 -0
  165. package/dist/internal/ppr/options.d.ts.map +1 -0
  166. package/dist/internal/ppr/options.js +125 -0
  167. package/dist/internal/ppr/options.js.map +1 -0
  168. package/dist/internal/ppr/route-rules.d.ts +12 -0
  169. package/dist/internal/ppr/route-rules.d.ts.map +1 -0
  170. package/dist/internal/ppr/route-rules.js +53 -0
  171. package/dist/internal/ppr/route-rules.js.map +1 -0
  172. package/dist/internal/ppr/runtime.d.ts +29 -0
  173. package/dist/internal/ppr/runtime.d.ts.map +1 -0
  174. package/dist/internal/ppr/runtime.js +35 -0
  175. package/dist/internal/ppr/runtime.js.map +1 -0
  176. package/dist/internal/ppr/server.d.ts +29 -0
  177. package/dist/internal/ppr/server.d.ts.map +1 -0
  178. package/dist/internal/ppr/server.js +1409 -0
  179. package/dist/internal/ppr/server.js.map +1 -0
  180. package/dist/internal/ppr/shell-store.d.ts +39 -0
  181. package/dist/internal/ppr/shell-store.d.ts.map +1 -0
  182. package/dist/internal/ppr/shell-store.js +106 -0
  183. package/dist/internal/ppr/shell-store.js.map +1 -0
  184. package/dist/internal/prerendered-pages.d.ts +1 -1
  185. package/dist/internal/prerendered-pages.d.ts.map +1 -1
  186. package/dist/internal/prerendered-pages.js +7 -4
  187. package/dist/internal/prerendered-pages.js.map +1 -1
  188. package/dist/internal/present.d.ts +11 -0
  189. package/dist/internal/present.d.ts.map +1 -0
  190. package/dist/internal/present.js +13 -0
  191. package/dist/internal/present.js.map +1 -0
  192. package/dist/internal/query-digest.d.ts +9 -0
  193. package/dist/internal/query-digest.d.ts.map +1 -0
  194. package/dist/internal/query-digest.js +23 -0
  195. package/dist/internal/query-digest.js.map +1 -0
  196. package/dist/internal/query-runtime.d.ts +6 -1
  197. package/dist/internal/query-runtime.d.ts.map +1 -1
  198. package/dist/internal/query-runtime.js +9 -0
  199. package/dist/internal/query-runtime.js.map +1 -1
  200. package/dist/internal/query-seam.d.ts +29 -0
  201. package/dist/internal/query-seam.d.ts.map +1 -0
  202. package/dist/internal/query-seam.js +23 -0
  203. package/dist/internal/query-seam.js.map +1 -0
  204. package/dist/internal/render-document.d.ts +34 -64
  205. package/dist/internal/render-document.d.ts.map +1 -1
  206. package/dist/internal/render-document.js +82 -64
  207. package/dist/internal/render-document.js.map +1 -1
  208. package/dist/internal/request-abort.d.ts +8 -0
  209. package/dist/internal/request-abort.d.ts.map +1 -0
  210. package/dist/internal/request-abort.js +22 -0
  211. package/dist/internal/request-abort.js.map +1 -0
  212. package/dist/internal/server-boundary.d.ts +2 -0
  213. package/dist/internal/server-boundary.d.ts.map +1 -1
  214. package/dist/internal/server-boundary.js +8 -1
  215. package/dist/internal/server-boundary.js.map +1 -1
  216. package/dist/internal/share-data.d.ts +10 -0
  217. package/dist/internal/share-data.d.ts.map +1 -0
  218. package/dist/internal/share-data.js +135 -0
  219. package/dist/internal/share-data.js.map +1 -0
  220. package/dist/internal/status-page.d.ts +68 -0
  221. package/dist/internal/status-page.d.ts.map +1 -0
  222. package/dist/internal/status-page.js +66 -0
  223. package/dist/internal/status-page.js.map +1 -0
  224. package/dist/internal/store-signature.d.ts +15 -0
  225. package/dist/internal/store-signature.d.ts.map +1 -0
  226. package/dist/internal/store-signature.js +114 -0
  227. package/dist/internal/store-signature.js.map +1 -0
  228. package/dist/internal/vite-plugin-compat.d.ts +2 -2
  229. package/dist/internal/vite-plugin-compat.js +2 -2
  230. package/dist/internal/web-app.d.ts +26 -0
  231. package/dist/internal/web-app.d.ts.map +1 -1
  232. package/dist/internal/web-app.js +79 -3
  233. package/dist/internal/web-app.js.map +1 -1
  234. package/dist/islands-swap.d.ts +41 -0
  235. package/dist/islands-swap.d.ts.map +1 -0
  236. package/dist/islands-swap.js +270 -0
  237. package/dist/islands-swap.js.map +1 -0
  238. package/dist/islands.d.ts +86 -24
  239. package/dist/islands.d.ts.map +1 -1
  240. package/dist/islands.js +138 -78
  241. package/dist/islands.js.map +1 -1
  242. package/dist/isr.d.ts +67 -13
  243. package/dist/isr.d.ts.map +1 -1
  244. package/dist/isr.js +247 -99
  245. package/dist/isr.js.map +1 -1
  246. package/dist/keep-alive.d.ts +147 -0
  247. package/dist/keep-alive.d.ts.map +1 -0
  248. package/dist/keep-alive.js +1102 -0
  249. package/dist/keep-alive.js.map +1 -0
  250. package/dist/live/bus.d.ts +70 -0
  251. package/dist/live/bus.d.ts.map +1 -0
  252. package/dist/live/bus.js +55 -0
  253. package/dist/live/bus.js.map +1 -0
  254. package/dist/live/core.d.ts +25 -0
  255. package/dist/live/core.d.ts.map +1 -0
  256. package/dist/live/core.js +29 -0
  257. package/dist/live/core.js.map +1 -0
  258. package/dist/live/history.d.ts +38 -0
  259. package/dist/live/history.d.ts.map +1 -0
  260. package/dist/live/history.js +104 -0
  261. package/dist/live/history.js.map +1 -0
  262. package/dist/live/hub-protocol.d.ts +46 -0
  263. package/dist/live/hub-protocol.d.ts.map +1 -0
  264. package/dist/live/hub-protocol.js +108 -0
  265. package/dist/live/hub-protocol.js.map +1 -0
  266. package/dist/live/hub.d.ts +185 -0
  267. package/dist/live/hub.d.ts.map +1 -0
  268. package/dist/live/hub.js +544 -0
  269. package/dist/live/hub.js.map +1 -0
  270. package/dist/live/keyring.d.ts +92 -0
  271. package/dist/live/keyring.d.ts.map +1 -0
  272. package/dist/live/keyring.js +265 -0
  273. package/dist/live/keyring.js.map +1 -0
  274. package/dist/live/read-capped.d.ts +6 -0
  275. package/dist/live/read-capped.d.ts.map +1 -0
  276. package/dist/live/read-capped.js +42 -0
  277. package/dist/live/read-capped.js.map +1 -0
  278. package/dist/live/revocations.d.ts +52 -0
  279. package/dist/live/revocations.d.ts.map +1 -0
  280. package/dist/live/revocations.js +116 -0
  281. package/dist/live/revocations.js.map +1 -0
  282. package/dist/live/settings.d.ts +14 -0
  283. package/dist/live/settings.d.ts.map +1 -0
  284. package/dist/live/settings.js +38 -0
  285. package/dist/live/settings.js.map +1 -0
  286. package/dist/live-client.d.ts +34 -0
  287. package/dist/live-client.d.ts.map +1 -0
  288. package/dist/live-client.js +878 -0
  289. package/dist/live-client.js.map +1 -0
  290. package/dist/live-hub.d.ts +130 -0
  291. package/dist/live-hub.d.ts.map +1 -0
  292. package/dist/live-hub.js +507 -0
  293. package/dist/live-hub.js.map +1 -0
  294. package/dist/live-redis.d.ts +60 -0
  295. package/dist/live-redis.d.ts.map +1 -0
  296. package/dist/live-redis.js +212 -0
  297. package/dist/live-redis.js.map +1 -0
  298. package/dist/live.d.ts +150 -0
  299. package/dist/live.d.ts.map +1 -0
  300. package/dist/live.js +972 -0
  301. package/dist/live.js.map +1 -0
  302. package/dist/manifest.d.ts +113 -2
  303. package/dist/manifest.d.ts.map +1 -1
  304. package/dist/manifest.js +109 -5
  305. package/dist/manifest.js.map +1 -1
  306. package/dist/navigation.d.ts +9 -3
  307. package/dist/navigation.d.ts.map +1 -1
  308. package/dist/navigation.js +13 -3
  309. package/dist/navigation.js.map +1 -1
  310. package/dist/plugins/vite-zone-guard.d.ts +6 -0
  311. package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
  312. package/dist/plugins/vite-zone-guard.js +8 -2
  313. package/dist/plugins/vite-zone-guard.js.map +1 -1
  314. package/dist/ppr.d.ts +73 -0
  315. package/dist/ppr.d.ts.map +1 -0
  316. package/dist/ppr.js +76 -0
  317. package/dist/ppr.js.map +1 -0
  318. package/dist/query.d.ts +8 -13
  319. package/dist/query.d.ts.map +1 -1
  320. package/dist/query.js +112 -18
  321. package/dist/query.js.map +1 -1
  322. package/dist/render-seam.d.ts +32 -0
  323. package/dist/render-seam.d.ts.map +1 -1
  324. package/dist/render-seam.js +7 -0
  325. package/dist/render-seam.js.map +1 -1
  326. package/dist/route-types.d.ts.map +1 -1
  327. package/dist/route-types.js +2 -2
  328. package/dist/route-types.js.map +1 -1
  329. package/dist/router.d.ts +72 -4
  330. package/dist/router.d.ts.map +1 -1
  331. package/dist/router.js +416 -129
  332. package/dist/router.js.map +1 -1
  333. package/dist/server-components/build.d.ts.map +1 -1
  334. package/dist/server-components/build.js +3 -3
  335. package/dist/server-components/build.js.map +1 -1
  336. package/dist/server-components/client.d.ts +23 -1
  337. package/dist/server-components/client.d.ts.map +1 -1
  338. package/dist/server-components/client.js +92 -5
  339. package/dist/server-components/client.js.map +1 -1
  340. package/dist/server-components/definition.d.ts.map +1 -1
  341. package/dist/server-components/definition.js +2 -1
  342. package/dist/server-components/definition.js.map +1 -1
  343. package/dist/server-components/hole.d.ts +8 -0
  344. package/dist/server-components/hole.d.ts.map +1 -0
  345. package/dist/server-components/hole.js +20 -0
  346. package/dist/server-components/hole.js.map +1 -0
  347. package/dist/server-components/html-policy.d.ts.map +1 -1
  348. package/dist/server-components/html-policy.js +62 -4
  349. package/dist/server-components/html-policy.js.map +1 -1
  350. package/dist/server-components/html-scan.d.ts +17 -0
  351. package/dist/server-components/html-scan.d.ts.map +1 -0
  352. package/dist/server-components/html-scan.js +180 -0
  353. package/dist/server-components/html-scan.js.map +1 -0
  354. package/dist/server-components/html.d.ts.map +1 -1
  355. package/dist/server-components/html.js +19 -4
  356. package/dist/server-components/html.js.map +1 -1
  357. package/dist/server-components/router-integration.d.ts +4 -1
  358. package/dist/server-components/router-integration.d.ts.map +1 -1
  359. package/dist/server-components/router-integration.js +23 -2
  360. package/dist/server-components/router-integration.js.map +1 -1
  361. package/dist/server-components/runtime.d.ts +6 -1
  362. package/dist/server-components/runtime.d.ts.map +1 -1
  363. package/dist/server-components/runtime.js +88 -29
  364. package/dist/server-components/runtime.js.map +1 -1
  365. package/dist/server-components/state.d.ts +3 -1
  366. package/dist/server-components/state.d.ts.map +1 -1
  367. package/dist/server-components/state.js +50 -38
  368. package/dist/server-components/state.js.map +1 -1
  369. package/dist/server-components/types.d.ts +9 -0
  370. package/dist/server-components/types.d.ts.map +1 -1
  371. package/dist/server-components/vite.d.ts.map +1 -1
  372. package/dist/server-components/vite.js +26 -9
  373. package/dist/server-components/vite.js.map +1 -1
  374. package/dist/vite.d.ts +5 -1
  375. package/dist/vite.d.ts.map +1 -1
  376. package/dist/vite.js +58 -4
  377. package/dist/vite.js.map +1 -1
  378. package/package.json +48 -8
  379. package/src/boundary.ts +77 -5
  380. package/src/build-plan.ts +3 -0
  381. package/src/build-vite.ts +2 -0
  382. package/src/build.ts +20 -1
  383. package/src/client.ts +183 -23
  384. package/src/csp.ts +16 -2
  385. package/src/deferred.ts +11 -5
  386. package/src/dev-feed.ts +11 -2
  387. package/src/dev-session.ts +22 -11
  388. package/src/dev.ts +29 -8
  389. package/src/diagnostic-catalog.ts +53 -0
  390. package/src/diagnostic.ts +1 -0
  391. package/src/fn.ts +24 -7
  392. package/src/fs.ts +22 -8
  393. package/src/identity.ts +61 -0
  394. package/src/index.ts +20 -4
  395. package/src/internal/cdn/cloudflare.ts +2 -1
  396. package/src/internal/certified-components.ts +1 -1
  397. package/src/internal/codegen.ts +95 -9
  398. package/src/internal/dev-websocket.ts +230 -0
  399. package/src/internal/hole-runtime.ts +286 -0
  400. package/src/internal/identity-epoch.ts +239 -0
  401. package/src/internal/invalidation-contract.ts +35 -0
  402. package/src/internal/invalidation.ts +213 -0
  403. package/src/internal/island-bindings.ts +191 -0
  404. package/src/internal/island-list.ts +92 -0
  405. package/src/internal/island-mount.ts +68 -0
  406. package/src/internal/island-owner.ts +20 -0
  407. package/src/internal/island-resource.ts +76 -0
  408. package/src/internal/island-signals.ts +249 -0
  409. package/src/internal/keep-alive-table.ts +72 -0
  410. package/src/internal/live-contract.ts +111 -0
  411. package/src/internal/live-queries.ts +60 -0
  412. package/src/internal/page-events.ts +27 -0
  413. package/src/internal/page-execution.ts +605 -45
  414. package/src/internal/parity.ts +35 -6
  415. package/src/internal/ppr/admission.ts +300 -0
  416. package/src/internal/ppr/canary.ts +122 -0
  417. package/src/internal/ppr/compile-shell.ts +379 -0
  418. package/src/internal/ppr/contract.ts +265 -0
  419. package/src/internal/ppr/frames.ts +170 -0
  420. package/src/internal/ppr/integration.ts +137 -0
  421. package/src/internal/ppr/options.ts +221 -0
  422. package/src/internal/ppr/route-rules.ts +77 -0
  423. package/src/internal/ppr/runtime.ts +39 -0
  424. package/src/internal/ppr/server.ts +1766 -0
  425. package/src/internal/ppr/shell-store.ts +152 -0
  426. package/src/internal/prerendered-pages.ts +7 -4
  427. package/src/internal/present.ts +20 -0
  428. package/src/internal/query-digest.ts +34 -0
  429. package/src/internal/query-runtime.ts +14 -1
  430. package/src/internal/query-seam.ts +48 -0
  431. package/src/internal/render-document.ts +158 -113
  432. package/src/internal/request-abort.ts +26 -0
  433. package/src/internal/server-boundary.ts +10 -1
  434. package/src/internal/share-data.ts +136 -0
  435. package/src/internal/status-page.ts +95 -0
  436. package/src/internal/store-signature.ts +149 -0
  437. package/src/internal/vite-plugin-compat.ts +2 -2
  438. package/src/internal/web-app.ts +123 -3
  439. package/src/islands-swap.ts +283 -0
  440. package/src/islands.ts +169 -72
  441. package/src/isr.ts +348 -106
  442. package/src/keep-alive.ts +1354 -0
  443. package/src/live/bus.ts +104 -0
  444. package/src/live/core.ts +52 -0
  445. package/src/live/history.ts +109 -0
  446. package/src/live/hub-protocol.ts +133 -0
  447. package/src/live/hub.ts +620 -0
  448. package/src/live/keyring.ts +384 -0
  449. package/src/live/read-capped.ts +36 -0
  450. package/src/live/revocations.ts +155 -0
  451. package/src/live/settings.ts +46 -0
  452. package/src/live-client.ts +1011 -0
  453. package/src/live-hub.ts +658 -0
  454. package/src/live-redis.ts +284 -0
  455. package/src/live.ts +1257 -0
  456. package/src/manifest.ts +274 -6
  457. package/src/navigation.ts +14 -2
  458. package/src/plugins/vite-zone-guard.ts +15 -2
  459. package/src/ppr.ts +153 -0
  460. package/src/query.ts +147 -20
  461. package/src/render-seam.ts +37 -0
  462. package/src/route-types.ts +3 -1
  463. package/src/router.ts +534 -132
  464. package/src/server-components/build.ts +9 -3
  465. package/src/server-components/client.ts +89 -5
  466. package/src/server-components/definition.ts +2 -1
  467. package/src/server-components/hole.ts +23 -0
  468. package/src/server-components/html-policy.ts +63 -4
  469. package/src/server-components/html-scan.ts +159 -0
  470. package/src/server-components/html.ts +18 -4
  471. package/src/server-components/router-integration.ts +21 -2
  472. package/src/server-components/runtime.ts +114 -31
  473. package/src/server-components/state.ts +66 -44
  474. package/src/server-components/types.ts +16 -0
  475. package/src/server-components/vite.ts +33 -14
  476. package/src/vite.ts +75 -6
  477. package/dist/nano.d.ts +0 -125
  478. package/dist/nano.d.ts.map +0 -1
  479. package/dist/nano.js +0 -190
  480. package/dist/nano.js.map +0 -1
  481. package/src/nano.ts +0 -246
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Shells and shared hole frames in a store shared by processes (Workers KV, Redis): a second level
3
+ * behind the in-process map. Whoever can write the store could put script into every visitor's page,
4
+ * so each entry is signed with the app's secret over its key, deployment and contents; anything that
5
+ * fails the check is a miss.
6
+ */
7
+ import type { CachedResponse, CacheStore } from "../../isr.ts"
8
+ import { DATE_TAG } from "../revive-dates.ts"
9
+ import { storeSigner } from "../store-signature.ts"
10
+ import { wireDate } from "../wire-date.ts"
11
+
12
+ /** A shell or a shared hole's frame as the shared store holds it: everything a process needs to
13
+ * serve it. */
14
+ export interface StoredEntry {
15
+ readonly routeId: string
16
+ /** A shell's document up to the request script's end, with room for the token at `tokenAt`
17
+ * (bytes); or a hole's frame. */
18
+ readonly html: string
19
+ readonly tokenAt: number
20
+ readonly data: unknown
21
+ readonly builtAt: number
22
+ readonly tags: readonly string[]
23
+ /** A shared hole's live keys. */
24
+ readonly keys?: readonly string[]
25
+ /** The shell loader's `notFound()`. */
26
+ readonly notFound: boolean
27
+ }
28
+
29
+ export interface SharedShellStore {
30
+ get(key: string): Promise<StoredEntry | undefined>
31
+ /** Skipped by the store when the key or one of its tags was purged after `fence`. */
32
+ set(
33
+ key: string,
34
+ entry: StoredEntry,
35
+ keepSeconds: number,
36
+ fence: number | undefined,
37
+ ): Promise<void>
38
+ fence(): Promise<number | undefined>
39
+ /** Absent when the store cannot drop entries by tag. */
40
+ readonly invalidateTag: ((tag: string) => Promise<void>) | undefined
41
+ }
42
+
43
+ const MAC_HEADER = "x-nifra-ppr-mac"
44
+
45
+ const isStrings = (value: unknown): value is readonly string[] =>
46
+ Array.isArray(value) && value.every((item) => typeof item === "string")
47
+
48
+ const field = (value: object, name: string): unknown => Reflect.get(value, name)
49
+
50
+ const isStoredEntry = (value: unknown): value is StoredEntry => {
51
+ if (typeof value !== "object" || value === null) return false
52
+ const tokenAt = field(value, "tokenAt")
53
+ const keys = field(value, "keys")
54
+ return (
55
+ typeof field(value, "routeId") === "string" &&
56
+ typeof field(value, "html") === "string" &&
57
+ typeof tokenAt === "number" &&
58
+ Number.isSafeInteger(tokenAt) &&
59
+ typeof field(value, "builtAt") === "number" &&
60
+ isStrings(field(value, "tags")) &&
61
+ (keys === undefined || isStrings(keys)) &&
62
+ typeof field(value, "notFound") === "boolean"
63
+ )
64
+ }
65
+
66
+ /** Read and write signed deployment-scoped PPR entries, treating malformed data as cache misses. */
67
+ export function sharedShellStore(
68
+ store: CacheStore,
69
+ secret: string,
70
+ deployment: string,
71
+ ): SharedShellStore {
72
+ const signer = storeSigner(secret)
73
+ const invalidateTag = store.invalidateTag
74
+ return {
75
+ async get(entryKey) {
76
+ const cached = await store.get(entryKey)
77
+ if (cached === undefined) return undefined
78
+ // One part, where ISR signs two: under a shared secret neither entry verifies as the other.
79
+ if (!(await signer.verify([cached.body], cached.headers[MAC_HEADER]))) {
80
+ console.error("[nifra/web] ppr: a shared store entry failed its signature check", {
81
+ key: entryKey,
82
+ })
83
+ return undefined
84
+ }
85
+ let payload: unknown
86
+ try {
87
+ // Match page-data revival, but keep the server's tagged toJSON for subsequent responses.
88
+ // JSON.parse defines own properties (including __proto__) without invoking setters.
89
+ payload = JSON.parse(cached.body, (_key, value: unknown) => {
90
+ if (typeof value !== "object" || value === null) return value
91
+ const tagged: unknown = Reflect.get(value, DATE_TAG)
92
+ if (typeof tagged !== "string" || Object.keys(value).length !== 1) return value
93
+ const time = Date.parse(tagged)
94
+ // An invalid wireDate would throw later from toJSON, outside this cache-miss boundary.
95
+ if (!Number.isFinite(time)) throw new RangeError("invalid cached date tag")
96
+ return wireDate(time)
97
+ })
98
+ } catch {
99
+ return undefined
100
+ }
101
+ if (typeof payload !== "object" || payload === null) return undefined
102
+ // The key and deployment are signed too, so an entry copied to another key or kept from
103
+ // another deployment never verifies as this one.
104
+ if (
105
+ field(payload, "v") !== 1 ||
106
+ field(payload, "key") !== entryKey ||
107
+ field(payload, "deployment") !== deployment
108
+ ) {
109
+ return undefined
110
+ }
111
+ const entry = field(payload, "entry")
112
+ return isStoredEntry(entry) ? entry : undefined
113
+ },
114
+ async set(entryKey, entry, keepSeconds, fence) {
115
+ const body = JSON.stringify({ v: 1, key: entryKey, deployment, entry })
116
+ const mac = await signer.sign([body])
117
+ const value: CachedResponse = {
118
+ body,
119
+ status: entry.notFound ? 404 : 200,
120
+ headers: { [MAC_HEADER]: mac },
121
+ storedAt: entry.builtAt,
122
+ revalidate: keepSeconds * 1000,
123
+ tags: entry.tags,
124
+ fence,
125
+ }
126
+ await store.set(entryKey, value)
127
+ },
128
+ async fence() {
129
+ return store.fence === undefined ? undefined : await store.fence()
130
+ },
131
+ invalidateTag:
132
+ invalidateTag === undefined ? undefined : (tag) => invalidateTag.call(store, tag),
133
+ }
134
+ }
135
+
136
+ /**
137
+ * A short, stable digest of `text` (FNV-1a, 64 bits as hex). It names a deployment inside cache keys;
138
+ * nothing an attacker controls goes into it, so it needs no collision resistance.
139
+ */
140
+ export function digest(text: string): string {
141
+ let high = 0xcbf29ce4
142
+ let low = 0x84222325
143
+ for (let at = 0; at < text.length; at++) {
144
+ low = (low ^ text.charCodeAt(at)) >>> 0
145
+ // Multiply the 64-bit value by the FNV prime 0x100000001b3 in two 32-bit halves.
146
+ const lowProduct = low * 0x1b3
147
+ const carry = Math.floor(lowProduct / 0x100000000)
148
+ high = (high * 0x1b3 + low * 0x100 + carry) >>> 0
149
+ low = lowProduct >>> 0
150
+ }
151
+ return high.toString(16).padStart(8, "0") + low.toString(16).padStart(8, "0")
152
+ }
@@ -1,5 +1,6 @@
1
1
  import { pathnameOf } from "@nifrajs/core/server"
2
2
  import { isDraftEnabled } from "../draft.ts"
3
+ import { SWAP_HEADER } from "../render-seam.ts"
3
4
  import { DATA_HEADER } from "../router.ts"
4
5
 
5
6
  /**
@@ -21,10 +22,11 @@ const REPLAYED = [
21
22
  "content-language",
22
23
  "content-security-policy",
23
24
  "content-security-policy-report-only",
25
+ "vary",
24
26
  ]
25
- // Vary values a file still answers correctly: compression is negotiated by the host, and a data request
26
- // never reaches the file.
27
- const STATIC_VARY = new Set(["accept-encoding", DATA_HEADER])
27
+ // Vary values a file still answers correctly: compression is negotiated by the host, and a data or
28
+ // slot-swap request never reaches the file.
29
+ const STATIC_VARY = new Set(["accept-encoding", DATA_HEADER, SWAP_HEADER])
28
30
 
29
31
  /**
30
32
  * The headers a self-hosted server replays with a prerendered page, or `undefined` when its build-time
@@ -84,7 +86,7 @@ export function servablePrerenderedPages(
84
86
  /**
85
87
  * Wrap a page route's GET handler so a plain document request for a prerendered path is answered from
86
88
  * its file. Anything a file cannot answer the way a render would renders on demand: a query string, a
87
- * navigation data or component request, a draft-mode visitor, or a file the reader cannot return.
89
+ * navigation data, component or slot-swap request, a draft-mode visitor, or a file the reader cannot return.
88
90
  */
89
91
  export function servePrerenderedPages(
90
92
  prerendered: PrerenderedPages,
@@ -102,6 +104,7 @@ export function servePrerenderedPages(
102
104
  req.url.includes("?") ||
103
105
  req.headers.has(DATA_HEADER) ||
104
106
  req.headers.has("x-nifra-component") ||
107
+ req.headers.has(SWAP_HEADER) ||
105
108
  (draftSecret !== undefined && (await isDraftEnabled(req, draftSecret)))
106
109
  ) {
107
110
  return render(c)
@@ -0,0 +1,20 @@
1
+ /**
2
+ * How a client navigation's page swap reaches the screen. The router loads a page first and hands only
3
+ * the swap here, so the history layer can wrap the swap alone in a view transition rather than the
4
+ * whole load. Module-scoped: one app per page; unset on the server and without `installHistory`.
5
+ */
6
+ export type Presenter = (swap: () => void) => Promise<void>
7
+
8
+ let presenter: Presenter | undefined
9
+
10
+ /** Set (or clear, with `undefined`) the presenter - called by `installHistory`. */
11
+ export function setPresenter(next: Presenter | undefined): void {
12
+ presenter = next
13
+ }
14
+
15
+ /** Run `swap` through the presenter, or at once when none is set. */
16
+ export function present(swap: () => void): Promise<void> | undefined {
17
+ if (presenter !== undefined) return presenter(swap)
18
+ swap()
19
+ return undefined
20
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The digest a live load gives each granted key for query hooks: HMAC-SHA-256 under a salt fresh per
3
+ * load, the first 16 bytes in base64url. A page's queries name the keys they read and find the load's
4
+ * tag for each one without the load ever sending key text. Shared by the server and the browser.
5
+ */
6
+
7
+ const TEXT = new TextEncoder()
8
+ const DIGEST_BYTES = 16
9
+ const SALT_BYTES = 16
10
+
11
+ export function querySalt(): string {
12
+ return base64url(crypto.getRandomValues(new Uint8Array(SALT_BYTES)))
13
+ }
14
+
15
+ /** Digests keys under one salt, importing the salt once. */
16
+ export async function queryDigester(salt: string): Promise<(key: string) => Promise<string>> {
17
+ const secret = await crypto.subtle.importKey(
18
+ "raw",
19
+ TEXT.encode(salt),
20
+ { name: "HMAC", hash: "SHA-256" },
21
+ false,
22
+ ["sign"],
23
+ )
24
+ return async (key) =>
25
+ base64url(
26
+ new Uint8Array(await crypto.subtle.sign("HMAC", secret, TEXT.encode(key)), 0, DIGEST_BYTES),
27
+ )
28
+ }
29
+
30
+ function base64url(bytes: Uint8Array): string {
31
+ let binary = ""
32
+ for (const byte of bytes) binary += String.fromCharCode(byte)
33
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")
34
+ }
@@ -1,4 +1,4 @@
1
- import type { QueryClient, QueryState } from "../query.ts"
1
+ import type { QueryClient, QueryHandle, QueryState } from "../query.ts"
2
2
  import { createQueryClient } from "../query.ts"
3
3
 
4
4
  /** Stable idle state shared by every framework query binding. */
@@ -23,6 +23,19 @@ export function getQueryClientSingleton(): QueryClient | undefined {
23
23
  return singleton
24
24
  }
25
25
 
26
+ export const noop = (): void => {}
27
+
28
+ /** Stable no-op subscription for a binding with no client (server, pre-hydration). */
29
+ export const noopSubscribe = (): (() => void) => noop
30
+
31
+ /** A binding's fetch on mount. A failed fetch shows as the query's `error`, so its promise is let go. */
32
+ export const fetchOnMount = (handle: QueryHandle<unknown> | undefined): (() => void) =>
33
+ handle === undefined
34
+ ? noop
35
+ : () => {
36
+ handle.fetch().catch(noop)
37
+ }
38
+
26
39
  /** Create the refetch fallback used when a binding has no client-side query cache. */
27
40
  export function createNoClientRefetch<T>(tag: string, operation: string): () => Promise<T> {
28
41
  return async () => {
@@ -0,0 +1,48 @@
1
+ /**
2
+ * What a query client tells the live client. `@nifrajs/web/live-client` installs the seam; a page
3
+ * without live refresh never does, so its queries keep no live state and ship none of it.
4
+ */
5
+ import type { QueryClient } from "../query.ts"
6
+
7
+ export interface LiveQuery {
8
+ /** The live keys its data depends on, as the page's loaders declare them. */
9
+ keys(): readonly string[]
10
+ /** The {@link QuerySeam.tick} its data was asked for at: the start of the fetch in flight, else of
11
+ * the fetch that produced it. */
12
+ tick(): number
13
+ /** Drop its data's freshness and refetch, superseding a fetch in flight. */
14
+ refresh(): void
15
+ }
16
+
17
+ export interface QuerySeam {
18
+ /** The live tick now, read as each fetch starts. */
19
+ tick(): number
20
+ /** A query was mounted or unmounted; only a mounted one with live keys is watched. */
21
+ track(query: LiveQuery, mounted: boolean): void
22
+ }
23
+
24
+ // On the global, so a query engine and a live client from two copies of the package still meet.
25
+ const SEAM = Symbol.for("nifra.web.querySeam")
26
+ const CLIENTS = Symbol.for("nifra.web.queryClients")
27
+
28
+ export const querySeam = (): QuerySeam | undefined => Reflect.get(globalThis, SEAM)
29
+
30
+ export function installQuerySeam(seam: QuerySeam): void {
31
+ if (querySeam() === undefined) Reflect.set(globalThis, SEAM, seam)
32
+ }
33
+
34
+ /**
35
+ * The browser query clients the page made, held weakly: a viewer switch clears each one still alive,
36
+ * whether it was made before or after the live client loaded.
37
+ */
38
+ export const queryClients = (): readonly WeakRef<QueryClient>[] =>
39
+ Reflect.get(globalThis, CLIENTS) ?? []
40
+
41
+ export function adoptClient(client: QueryClient): void {
42
+ // A server builds a client per request; none of them outlives it or sees a viewer switch.
43
+ if (typeof Reflect.get(globalThis, "window") === "undefined") return
44
+ // Each new client sheds the ones the page let go, so the list never outgrows the live clients.
45
+ const clients = queryClients().filter((ref) => ref.deref() !== undefined)
46
+ clients.push(new WeakRef(client))
47
+ Reflect.set(globalThis, CLIENTS, clients)
48
+ }