@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.
- package/CHANGELOG.md +243 -0
- package/README.md +21 -11
- package/dist/boundary.d.ts +67 -7
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +6 -4
- package/dist/boundary.js.map +1 -1
- package/dist/build-plan.d.ts +3 -0
- package/dist/build-plan.d.ts.map +1 -1
- package/dist/build-plan.js.map +1 -1
- package/dist/build-vite.d.ts.map +1 -1
- package/dist/build-vite.js +2 -0
- package/dist/build-vite.js.map +1 -1
- package/dist/build.d.ts +9 -2
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +10 -0
- package/dist/build.js.map +1 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +174 -23
- package/dist/client.js.map +1 -1
- package/dist/csp.d.ts +8 -0
- package/dist/csp.d.ts.map +1 -1
- package/dist/csp.js +11 -2
- package/dist/csp.js.map +1 -1
- package/dist/deferred.d.ts +6 -4
- package/dist/deferred.d.ts.map +1 -1
- package/dist/deferred.js +10 -6
- package/dist/deferred.js.map +1 -1
- package/dist/dev-feed.d.ts.map +1 -1
- package/dist/dev-feed.js +11 -2
- package/dist/dev-feed.js.map +1 -1
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +13 -6
- package/dist/dev-session.js.map +1 -1
- package/dist/dev.d.ts +4 -1
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +12 -5
- package/dist/dev.js.map +1 -1
- package/dist/diagnostic-catalog.d.ts +4 -0
- package/dist/diagnostic-catalog.d.ts.map +1 -1
- package/dist/diagnostic-catalog.js +48 -0
- package/dist/diagnostic-catalog.js.map +1 -1
- package/dist/diagnostic.d.ts +1 -1
- package/dist/diagnostic.d.ts.map +1 -1
- package/dist/diagnostic.js +1 -1
- package/dist/diagnostic.js.map +1 -1
- package/dist/fn.d.ts +5 -3
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +20 -5
- package/dist/fn.js.map +1 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +13 -3
- package/dist/fs.js.map +1 -1
- package/dist/identity.d.ts +22 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +60 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/internal/cdn/cloudflare.d.ts +2 -1
- package/dist/internal/cdn/cloudflare.d.ts.map +1 -1
- package/dist/internal/cdn/cloudflare.js +2 -1
- package/dist/internal/cdn/cloudflare.js.map +1 -1
- package/dist/internal/certified-components.d.ts +1 -1
- package/dist/internal/certified-components.js +1 -1
- package/dist/internal/codegen.d.ts +11 -10
- package/dist/internal/codegen.d.ts.map +1 -1
- package/dist/internal/codegen.js +73 -10
- package/dist/internal/codegen.js.map +1 -1
- package/dist/internal/dev-websocket.d.ts +73 -0
- package/dist/internal/dev-websocket.d.ts.map +1 -0
- package/dist/internal/dev-websocket.js +145 -0
- package/dist/internal/dev-websocket.js.map +1 -0
- package/dist/internal/hole-runtime.d.ts +66 -0
- package/dist/internal/hole-runtime.d.ts.map +1 -0
- package/dist/internal/hole-runtime.js +211 -0
- package/dist/internal/hole-runtime.js.map +1 -0
- package/dist/internal/identity-epoch.d.ts +50 -0
- package/dist/internal/identity-epoch.d.ts.map +1 -0
- package/dist/internal/identity-epoch.js +180 -0
- package/dist/internal/identity-epoch.js.map +1 -0
- package/dist/internal/invalidation-contract.d.ts +23 -0
- package/dist/internal/invalidation-contract.d.ts.map +1 -0
- package/dist/internal/invalidation-contract.js +11 -0
- package/dist/internal/invalidation-contract.js.map +1 -0
- package/dist/internal/invalidation.d.ts +62 -0
- package/dist/internal/invalidation.d.ts.map +1 -0
- package/dist/internal/invalidation.js +149 -0
- package/dist/internal/invalidation.js.map +1 -0
- package/dist/internal/island-bindings.d.ts +51 -0
- package/dist/internal/island-bindings.d.ts.map +1 -0
- package/dist/internal/island-bindings.js +147 -0
- package/dist/internal/island-bindings.js.map +1 -0
- package/dist/internal/island-list.d.ts +26 -0
- package/dist/internal/island-list.d.ts.map +1 -0
- package/dist/internal/island-list.js +78 -0
- package/dist/internal/island-list.js.map +1 -0
- package/dist/internal/island-mount.d.ts +4 -0
- package/dist/internal/island-mount.d.ts.map +1 -0
- package/dist/internal/island-mount.js +66 -0
- package/dist/internal/island-mount.js.map +1 -0
- package/dist/internal/island-owner.d.ts +5 -0
- package/dist/internal/island-owner.d.ts.map +1 -0
- package/dist/internal/island-owner.js +20 -0
- package/dist/internal/island-owner.js.map +1 -0
- package/dist/internal/island-resource.d.ts +30 -0
- package/dist/internal/island-resource.d.ts.map +1 -0
- package/dist/internal/island-resource.js +57 -0
- package/dist/internal/island-resource.js.map +1 -0
- package/dist/internal/island-signals.d.ts +51 -0
- package/dist/internal/island-signals.d.ts.map +1 -0
- package/dist/internal/island-signals.js +220 -0
- package/dist/internal/island-signals.js.map +1 -0
- package/dist/internal/keep-alive-table.d.ts +23 -0
- package/dist/internal/keep-alive-table.d.ts.map +1 -0
- package/dist/internal/keep-alive-table.js +53 -0
- package/dist/internal/keep-alive-table.js.map +1 -0
- package/dist/internal/live-contract.d.ts +101 -0
- package/dist/internal/live-contract.d.ts.map +1 -0
- package/dist/internal/live-contract.js +5 -0
- package/dist/internal/live-contract.js.map +1 -0
- package/dist/internal/live-queries.d.ts +22 -0
- package/dist/internal/live-queries.d.ts.map +1 -0
- package/dist/internal/live-queries.js +54 -0
- package/dist/internal/live-queries.js.map +1 -0
- package/dist/internal/page-events.d.ts +10 -0
- package/dist/internal/page-events.d.ts.map +1 -0
- package/dist/internal/page-events.js +26 -0
- package/dist/internal/page-events.js.map +1 -0
- package/dist/internal/page-execution.d.ts +16 -1
- package/dist/internal/page-execution.d.ts.map +1 -1
- package/dist/internal/page-execution.js +432 -31
- package/dist/internal/page-execution.js.map +1 -1
- package/dist/internal/parity.d.ts +3 -0
- package/dist/internal/parity.d.ts.map +1 -1
- package/dist/internal/parity.js +28 -5
- package/dist/internal/parity.js.map +1 -1
- package/dist/internal/ppr/admission.d.ts +83 -0
- package/dist/internal/ppr/admission.d.ts.map +1 -0
- package/dist/internal/ppr/admission.js +221 -0
- package/dist/internal/ppr/admission.js.map +1 -0
- package/dist/internal/ppr/canary.d.ts +24 -0
- package/dist/internal/ppr/canary.d.ts.map +1 -0
- package/dist/internal/ppr/canary.js +102 -0
- package/dist/internal/ppr/canary.js.map +1 -0
- package/dist/internal/ppr/compile-shell.d.ts +39 -0
- package/dist/internal/ppr/compile-shell.d.ts.map +1 -0
- package/dist/internal/ppr/compile-shell.js +298 -0
- package/dist/internal/ppr/compile-shell.js.map +1 -0
- package/dist/internal/ppr/contract.d.ts +177 -0
- package/dist/internal/ppr/contract.d.ts.map +1 -0
- package/dist/internal/ppr/contract.js +80 -0
- package/dist/internal/ppr/contract.js.map +1 -0
- package/dist/internal/ppr/frames.d.ts +71 -0
- package/dist/internal/ppr/frames.d.ts.map +1 -0
- package/dist/internal/ppr/frames.js +119 -0
- package/dist/internal/ppr/frames.js.map +1 -0
- package/dist/internal/ppr/integration.d.ts +19 -0
- package/dist/internal/ppr/integration.d.ts.map +1 -0
- package/dist/internal/ppr/integration.js +106 -0
- package/dist/internal/ppr/integration.js.map +1 -0
- package/dist/internal/ppr/options.d.ts +96 -0
- package/dist/internal/ppr/options.d.ts.map +1 -0
- package/dist/internal/ppr/options.js +125 -0
- package/dist/internal/ppr/options.js.map +1 -0
- package/dist/internal/ppr/route-rules.d.ts +12 -0
- package/dist/internal/ppr/route-rules.d.ts.map +1 -0
- package/dist/internal/ppr/route-rules.js +53 -0
- package/dist/internal/ppr/route-rules.js.map +1 -0
- package/dist/internal/ppr/runtime.d.ts +29 -0
- package/dist/internal/ppr/runtime.d.ts.map +1 -0
- package/dist/internal/ppr/runtime.js +35 -0
- package/dist/internal/ppr/runtime.js.map +1 -0
- package/dist/internal/ppr/server.d.ts +29 -0
- package/dist/internal/ppr/server.d.ts.map +1 -0
- package/dist/internal/ppr/server.js +1409 -0
- package/dist/internal/ppr/server.js.map +1 -0
- package/dist/internal/ppr/shell-store.d.ts +39 -0
- package/dist/internal/ppr/shell-store.d.ts.map +1 -0
- package/dist/internal/ppr/shell-store.js +106 -0
- package/dist/internal/ppr/shell-store.js.map +1 -0
- package/dist/internal/prerendered-pages.d.ts +1 -1
- package/dist/internal/prerendered-pages.d.ts.map +1 -1
- package/dist/internal/prerendered-pages.js +7 -4
- package/dist/internal/prerendered-pages.js.map +1 -1
- package/dist/internal/present.d.ts +11 -0
- package/dist/internal/present.d.ts.map +1 -0
- package/dist/internal/present.js +13 -0
- package/dist/internal/present.js.map +1 -0
- package/dist/internal/query-digest.d.ts +9 -0
- package/dist/internal/query-digest.d.ts.map +1 -0
- package/dist/internal/query-digest.js +23 -0
- package/dist/internal/query-digest.js.map +1 -0
- package/dist/internal/query-runtime.d.ts +6 -1
- package/dist/internal/query-runtime.d.ts.map +1 -1
- package/dist/internal/query-runtime.js +9 -0
- package/dist/internal/query-runtime.js.map +1 -1
- package/dist/internal/query-seam.d.ts +29 -0
- package/dist/internal/query-seam.d.ts.map +1 -0
- package/dist/internal/query-seam.js +23 -0
- package/dist/internal/query-seam.js.map +1 -0
- package/dist/internal/render-document.d.ts +34 -64
- package/dist/internal/render-document.d.ts.map +1 -1
- package/dist/internal/render-document.js +82 -64
- package/dist/internal/render-document.js.map +1 -1
- package/dist/internal/request-abort.d.ts +8 -0
- package/dist/internal/request-abort.d.ts.map +1 -0
- package/dist/internal/request-abort.js +22 -0
- package/dist/internal/request-abort.js.map +1 -0
- package/dist/internal/server-boundary.d.ts +2 -0
- package/dist/internal/server-boundary.d.ts.map +1 -1
- package/dist/internal/server-boundary.js +8 -1
- package/dist/internal/server-boundary.js.map +1 -1
- package/dist/internal/share-data.d.ts +10 -0
- package/dist/internal/share-data.d.ts.map +1 -0
- package/dist/internal/share-data.js +135 -0
- package/dist/internal/share-data.js.map +1 -0
- package/dist/internal/status-page.d.ts +68 -0
- package/dist/internal/status-page.d.ts.map +1 -0
- package/dist/internal/status-page.js +66 -0
- package/dist/internal/status-page.js.map +1 -0
- package/dist/internal/store-signature.d.ts +15 -0
- package/dist/internal/store-signature.d.ts.map +1 -0
- package/dist/internal/store-signature.js +114 -0
- package/dist/internal/store-signature.js.map +1 -0
- package/dist/internal/vite-plugin-compat.d.ts +2 -2
- package/dist/internal/vite-plugin-compat.js +2 -2
- package/dist/internal/web-app.d.ts +26 -0
- package/dist/internal/web-app.d.ts.map +1 -1
- package/dist/internal/web-app.js +79 -3
- package/dist/internal/web-app.js.map +1 -1
- package/dist/islands-swap.d.ts +41 -0
- package/dist/islands-swap.d.ts.map +1 -0
- package/dist/islands-swap.js +270 -0
- package/dist/islands-swap.js.map +1 -0
- package/dist/islands.d.ts +86 -24
- package/dist/islands.d.ts.map +1 -1
- package/dist/islands.js +138 -78
- package/dist/islands.js.map +1 -1
- package/dist/isr.d.ts +67 -13
- package/dist/isr.d.ts.map +1 -1
- package/dist/isr.js +247 -99
- package/dist/isr.js.map +1 -1
- package/dist/keep-alive.d.ts +147 -0
- package/dist/keep-alive.d.ts.map +1 -0
- package/dist/keep-alive.js +1102 -0
- package/dist/keep-alive.js.map +1 -0
- package/dist/live/bus.d.ts +70 -0
- package/dist/live/bus.d.ts.map +1 -0
- package/dist/live/bus.js +55 -0
- package/dist/live/bus.js.map +1 -0
- package/dist/live/core.d.ts +25 -0
- package/dist/live/core.d.ts.map +1 -0
- package/dist/live/core.js +29 -0
- package/dist/live/core.js.map +1 -0
- package/dist/live/history.d.ts +38 -0
- package/dist/live/history.d.ts.map +1 -0
- package/dist/live/history.js +104 -0
- package/dist/live/history.js.map +1 -0
- package/dist/live/hub-protocol.d.ts +46 -0
- package/dist/live/hub-protocol.d.ts.map +1 -0
- package/dist/live/hub-protocol.js +108 -0
- package/dist/live/hub-protocol.js.map +1 -0
- package/dist/live/hub.d.ts +185 -0
- package/dist/live/hub.d.ts.map +1 -0
- package/dist/live/hub.js +544 -0
- package/dist/live/hub.js.map +1 -0
- package/dist/live/keyring.d.ts +92 -0
- package/dist/live/keyring.d.ts.map +1 -0
- package/dist/live/keyring.js +265 -0
- package/dist/live/keyring.js.map +1 -0
- package/dist/live/read-capped.d.ts +6 -0
- package/dist/live/read-capped.d.ts.map +1 -0
- package/dist/live/read-capped.js +42 -0
- package/dist/live/read-capped.js.map +1 -0
- package/dist/live/revocations.d.ts +52 -0
- package/dist/live/revocations.d.ts.map +1 -0
- package/dist/live/revocations.js +116 -0
- package/dist/live/revocations.js.map +1 -0
- package/dist/live/settings.d.ts +14 -0
- package/dist/live/settings.d.ts.map +1 -0
- package/dist/live/settings.js +38 -0
- package/dist/live/settings.js.map +1 -0
- package/dist/live-client.d.ts +34 -0
- package/dist/live-client.d.ts.map +1 -0
- package/dist/live-client.js +878 -0
- package/dist/live-client.js.map +1 -0
- package/dist/live-hub.d.ts +130 -0
- package/dist/live-hub.d.ts.map +1 -0
- package/dist/live-hub.js +507 -0
- package/dist/live-hub.js.map +1 -0
- package/dist/live-redis.d.ts +60 -0
- package/dist/live-redis.d.ts.map +1 -0
- package/dist/live-redis.js +212 -0
- package/dist/live-redis.js.map +1 -0
- package/dist/live.d.ts +150 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +972 -0
- package/dist/live.js.map +1 -0
- package/dist/manifest.d.ts +113 -2
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +109 -5
- package/dist/manifest.js.map +1 -1
- package/dist/navigation.d.ts +9 -3
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +13 -3
- package/dist/navigation.js.map +1 -1
- package/dist/plugins/vite-zone-guard.d.ts +6 -0
- package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
- package/dist/plugins/vite-zone-guard.js +8 -2
- package/dist/plugins/vite-zone-guard.js.map +1 -1
- package/dist/ppr.d.ts +73 -0
- package/dist/ppr.d.ts.map +1 -0
- package/dist/ppr.js +76 -0
- package/dist/ppr.js.map +1 -0
- package/dist/query.d.ts +8 -13
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +112 -18
- package/dist/query.js.map +1 -1
- package/dist/render-seam.d.ts +32 -0
- package/dist/render-seam.d.ts.map +1 -1
- package/dist/render-seam.js +7 -0
- package/dist/render-seam.js.map +1 -1
- package/dist/route-types.d.ts.map +1 -1
- package/dist/route-types.js +2 -2
- package/dist/route-types.js.map +1 -1
- package/dist/router.d.ts +72 -4
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +416 -129
- package/dist/router.js.map +1 -1
- package/dist/server-components/build.d.ts.map +1 -1
- package/dist/server-components/build.js +3 -3
- package/dist/server-components/build.js.map +1 -1
- package/dist/server-components/client.d.ts +23 -1
- package/dist/server-components/client.d.ts.map +1 -1
- package/dist/server-components/client.js +92 -5
- package/dist/server-components/client.js.map +1 -1
- package/dist/server-components/definition.d.ts.map +1 -1
- package/dist/server-components/definition.js +2 -1
- package/dist/server-components/definition.js.map +1 -1
- package/dist/server-components/hole.d.ts +8 -0
- package/dist/server-components/hole.d.ts.map +1 -0
- package/dist/server-components/hole.js +20 -0
- package/dist/server-components/hole.js.map +1 -0
- package/dist/server-components/html-policy.d.ts.map +1 -1
- package/dist/server-components/html-policy.js +62 -4
- package/dist/server-components/html-policy.js.map +1 -1
- package/dist/server-components/html-scan.d.ts +17 -0
- package/dist/server-components/html-scan.d.ts.map +1 -0
- package/dist/server-components/html-scan.js +180 -0
- package/dist/server-components/html-scan.js.map +1 -0
- package/dist/server-components/html.d.ts.map +1 -1
- package/dist/server-components/html.js +19 -4
- package/dist/server-components/html.js.map +1 -1
- package/dist/server-components/router-integration.d.ts +4 -1
- package/dist/server-components/router-integration.d.ts.map +1 -1
- package/dist/server-components/router-integration.js +23 -2
- package/dist/server-components/router-integration.js.map +1 -1
- package/dist/server-components/runtime.d.ts +6 -1
- package/dist/server-components/runtime.d.ts.map +1 -1
- package/dist/server-components/runtime.js +88 -29
- package/dist/server-components/runtime.js.map +1 -1
- package/dist/server-components/state.d.ts +3 -1
- package/dist/server-components/state.d.ts.map +1 -1
- package/dist/server-components/state.js +50 -38
- package/dist/server-components/state.js.map +1 -1
- package/dist/server-components/types.d.ts +9 -0
- package/dist/server-components/types.d.ts.map +1 -1
- package/dist/server-components/vite.d.ts.map +1 -1
- package/dist/server-components/vite.js +26 -9
- package/dist/server-components/vite.js.map +1 -1
- package/dist/vite.d.ts +5 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +58 -4
- package/dist/vite.js.map +1 -1
- package/package.json +48 -8
- package/src/boundary.ts +77 -5
- package/src/build-plan.ts +3 -0
- package/src/build-vite.ts +2 -0
- package/src/build.ts +20 -1
- package/src/client.ts +183 -23
- package/src/csp.ts +16 -2
- package/src/deferred.ts +11 -5
- package/src/dev-feed.ts +11 -2
- package/src/dev-session.ts +22 -11
- package/src/dev.ts +29 -8
- package/src/diagnostic-catalog.ts +53 -0
- package/src/diagnostic.ts +1 -0
- package/src/fn.ts +24 -7
- package/src/fs.ts +22 -8
- package/src/identity.ts +61 -0
- package/src/index.ts +20 -4
- package/src/internal/cdn/cloudflare.ts +2 -1
- package/src/internal/certified-components.ts +1 -1
- package/src/internal/codegen.ts +95 -9
- package/src/internal/dev-websocket.ts +230 -0
- package/src/internal/hole-runtime.ts +286 -0
- package/src/internal/identity-epoch.ts +239 -0
- package/src/internal/invalidation-contract.ts +35 -0
- package/src/internal/invalidation.ts +213 -0
- package/src/internal/island-bindings.ts +191 -0
- package/src/internal/island-list.ts +92 -0
- package/src/internal/island-mount.ts +68 -0
- package/src/internal/island-owner.ts +20 -0
- package/src/internal/island-resource.ts +76 -0
- package/src/internal/island-signals.ts +249 -0
- package/src/internal/keep-alive-table.ts +72 -0
- package/src/internal/live-contract.ts +111 -0
- package/src/internal/live-queries.ts +60 -0
- package/src/internal/page-events.ts +27 -0
- package/src/internal/page-execution.ts +605 -45
- package/src/internal/parity.ts +35 -6
- package/src/internal/ppr/admission.ts +300 -0
- package/src/internal/ppr/canary.ts +122 -0
- package/src/internal/ppr/compile-shell.ts +379 -0
- package/src/internal/ppr/contract.ts +265 -0
- package/src/internal/ppr/frames.ts +170 -0
- package/src/internal/ppr/integration.ts +137 -0
- package/src/internal/ppr/options.ts +221 -0
- package/src/internal/ppr/route-rules.ts +77 -0
- package/src/internal/ppr/runtime.ts +39 -0
- package/src/internal/ppr/server.ts +1766 -0
- package/src/internal/ppr/shell-store.ts +152 -0
- package/src/internal/prerendered-pages.ts +7 -4
- package/src/internal/present.ts +20 -0
- package/src/internal/query-digest.ts +34 -0
- package/src/internal/query-runtime.ts +14 -1
- package/src/internal/query-seam.ts +48 -0
- package/src/internal/render-document.ts +158 -113
- package/src/internal/request-abort.ts +26 -0
- package/src/internal/server-boundary.ts +10 -1
- package/src/internal/share-data.ts +136 -0
- package/src/internal/status-page.ts +95 -0
- package/src/internal/store-signature.ts +149 -0
- package/src/internal/vite-plugin-compat.ts +2 -2
- package/src/internal/web-app.ts +123 -3
- package/src/islands-swap.ts +283 -0
- package/src/islands.ts +169 -72
- package/src/isr.ts +348 -106
- package/src/keep-alive.ts +1354 -0
- package/src/live/bus.ts +104 -0
- package/src/live/core.ts +52 -0
- package/src/live/history.ts +109 -0
- package/src/live/hub-protocol.ts +133 -0
- package/src/live/hub.ts +620 -0
- package/src/live/keyring.ts +384 -0
- package/src/live/read-capped.ts +36 -0
- package/src/live/revocations.ts +155 -0
- package/src/live/settings.ts +46 -0
- package/src/live-client.ts +1011 -0
- package/src/live-hub.ts +658 -0
- package/src/live-redis.ts +284 -0
- package/src/live.ts +1257 -0
- package/src/manifest.ts +274 -6
- package/src/navigation.ts +14 -2
- package/src/plugins/vite-zone-guard.ts +15 -2
- package/src/ppr.ts +153 -0
- package/src/query.ts +147 -20
- package/src/render-seam.ts +37 -0
- package/src/route-types.ts +3 -1
- package/src/router.ts +534 -132
- package/src/server-components/build.ts +9 -3
- package/src/server-components/client.ts +89 -5
- package/src/server-components/definition.ts +2 -1
- package/src/server-components/hole.ts +23 -0
- package/src/server-components/html-policy.ts +63 -4
- package/src/server-components/html-scan.ts +159 -0
- package/src/server-components/html.ts +18 -4
- package/src/server-components/router-integration.ts +21 -2
- package/src/server-components/runtime.ts +114 -31
- package/src/server-components/state.ts +66 -44
- package/src/server-components/types.ts +16 -0
- package/src/server-components/vite.ts +33 -14
- package/src/vite.ts +75 -6
- package/dist/nano.d.ts +0 -125
- package/dist/nano.d.ts.map +0 -1
- package/dist/nano.js +0 -190
- package/dist/nano.js.map +0 -1
- package/src/nano.ts +0 -246
package/src/query.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* + navigation use the path cache; component-level interactive data (search, infinite scroll, polling)
|
|
12
12
|
* uses this arbitrary-keyed query cache. The two coexist.
|
|
13
13
|
*/
|
|
14
|
+
import { adoptClient, type LiveQuery, querySeam } from "./internal/query-seam.ts"
|
|
14
15
|
|
|
15
16
|
/** A query's lifecycle status. `pending` = no data yet; `success`/`error` once it has settled once. */
|
|
16
17
|
export type QueryStatus = "pending" | "success" | "error"
|
|
@@ -43,6 +44,11 @@ export interface QueryOptions {
|
|
|
43
44
|
/** Data stays fresh this long (ms) after a fetch; older ⇒ refetch on the next `fetch()`. Overrides
|
|
44
45
|
* the client default for this key. */
|
|
45
46
|
readonly staleTime?: number
|
|
47
|
+
/**
|
|
48
|
+
* Live keys the data depends on, as the page's loaders declare them with `ctx.live()`. While the
|
|
49
|
+
* query is mounted, a change to one refetches it. Needs `live({ queryKeys: true })`.
|
|
50
|
+
*/
|
|
51
|
+
readonly live?: readonly string[]
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export interface QueryClientOptions {
|
|
@@ -147,6 +153,9 @@ export interface QueryClient {
|
|
|
147
153
|
dehydrate: () => DehydratedState
|
|
148
154
|
/** Seed the cache from a {@link dehydrate} snapshot (client boot). Existing fresher entries win. */
|
|
149
155
|
hydrate: (state: DehydratedState) => void
|
|
156
|
+
/** Drop every cached query: mounted ones go back to pending and refetch, the rest are removed. A
|
|
157
|
+
* live app calls it on every query client in the page when the viewer changes. */
|
|
158
|
+
clear: () => void
|
|
150
159
|
}
|
|
151
160
|
|
|
152
161
|
/**
|
|
@@ -180,10 +189,33 @@ function keyMatchesPrefix(key: unknown, prefix: unknown): boolean {
|
|
|
180
189
|
)
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
|
|
192
|
+
/** What both kinds of entry carry for a page with live refresh. */
|
|
193
|
+
interface LiveFields {
|
|
194
|
+
live: readonly string[]
|
|
195
|
+
subscribers: number
|
|
196
|
+
readonly lq: LiveQuery
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** The live tick now; 0 on a page without live refresh. */
|
|
200
|
+
const liveTick = (): number => querySeam()?.tick() ?? 0
|
|
201
|
+
|
|
202
|
+
/** New keys while mounted are tracked again: a change to a new key before now never reached it. */
|
|
203
|
+
function relive(entry: LiveFields, live: readonly string[] | undefined): void {
|
|
204
|
+
if (live === undefined) return
|
|
205
|
+
if (live.length === entry.live.length && live.every((key, i) => key === entry.live[i])) return
|
|
206
|
+
entry.live = [...live]
|
|
207
|
+
if (entry.subscribers === 0) return
|
|
208
|
+
querySeam()?.track(entry.lq, false)
|
|
209
|
+
querySeam()?.track(entry.lq, true)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
interface Entry extends LiveFields {
|
|
184
213
|
readonly key: unknown
|
|
185
214
|
fn: () => Promise<unknown>
|
|
186
215
|
staleTime: number
|
|
216
|
+
/** The {@link liveTick} at the start of the latest fetch, and of the fetch that produced `state`. */
|
|
217
|
+
startTick: number
|
|
218
|
+
dataTick: number
|
|
187
219
|
state: QueryState
|
|
188
220
|
promise: Promise<unknown> | undefined
|
|
189
221
|
/** The {@link generation} the in-flight {@link promise} started at - so a fetch begun *before* an
|
|
@@ -192,7 +224,6 @@ interface Entry {
|
|
|
192
224
|
/** Bumped by `invalidateQueries`/`refetch` to supersede any in-flight fetch begun before it. */
|
|
193
225
|
generation: number
|
|
194
226
|
invalidated: boolean
|
|
195
|
-
subscribers: number
|
|
196
227
|
/** Scheduled eviction time (set when subscribers hit 0; cleared on resubscribe). */
|
|
197
228
|
gcAt: number | undefined
|
|
198
229
|
readonly listeners: Set<() => void>
|
|
@@ -248,10 +279,22 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
248
279
|
// between renders). All the fetch/dedup/generation machinery lives here so query(), prefetchQuery(),
|
|
249
280
|
// setQueryData(), and invalidateQueries() share exactly one implementation.
|
|
250
281
|
const makeEntry = (key: unknown, fn: () => Promise<unknown>, staleTime: number): Entry => {
|
|
282
|
+
const lq: LiveQuery = {
|
|
283
|
+
keys: () => entry.live,
|
|
284
|
+
tick: () =>
|
|
285
|
+
entry.promise !== undefined && entry.promiseGen === entry.generation
|
|
286
|
+
? entry.startTick
|
|
287
|
+
: entry.dataTick,
|
|
288
|
+
refresh: () => invalidateEntry(entry),
|
|
289
|
+
}
|
|
251
290
|
const entry: Entry = {
|
|
252
291
|
key,
|
|
253
292
|
fn,
|
|
254
293
|
staleTime,
|
|
294
|
+
live: [],
|
|
295
|
+
lq,
|
|
296
|
+
startTick: 0,
|
|
297
|
+
dataTick: 0,
|
|
255
298
|
state: PENDING,
|
|
256
299
|
promise: undefined,
|
|
257
300
|
promiseGen: 0,
|
|
@@ -287,6 +330,8 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
287
330
|
if (!force && entry.state.status === "success" && !isStale())
|
|
288
331
|
return Promise.resolve(entry.state.data) // fresh cache hit - no fn call
|
|
289
332
|
const gen = entry.generation
|
|
333
|
+
const started = liveTick()
|
|
334
|
+
entry.startTick = started
|
|
290
335
|
entry.setState({ ...entry.state, isFetching: true }) // show the background/initial fetch
|
|
291
336
|
const promise = (async () => {
|
|
292
337
|
try {
|
|
@@ -296,6 +341,7 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
296
341
|
// that superseded this one publishes the post-mutation data.
|
|
297
342
|
if (gen !== entry.generation) return data
|
|
298
343
|
entry.invalidated = false
|
|
344
|
+
entry.dataTick = started
|
|
299
345
|
entry.setState(successState(data, now()))
|
|
300
346
|
return data
|
|
301
347
|
} catch (error) {
|
|
@@ -320,10 +366,14 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
320
366
|
entry.subscribers++
|
|
321
367
|
entry.gcAt = undefined // in use again - cancel any pending eviction
|
|
322
368
|
entry.listeners.add(listener)
|
|
369
|
+
if (entry.subscribers === 1) querySeam()?.track(lq, true)
|
|
323
370
|
return () => {
|
|
324
371
|
entry.listeners.delete(listener)
|
|
325
372
|
entry.subscribers--
|
|
326
|
-
if (entry.subscribers === 0)
|
|
373
|
+
if (entry.subscribers === 0) {
|
|
374
|
+
entry.gcAt = now() + gcTime
|
|
375
|
+
querySeam()?.track(lq, false)
|
|
376
|
+
}
|
|
327
377
|
}
|
|
328
378
|
},
|
|
329
379
|
fetch: () => entry.run(false),
|
|
@@ -332,35 +382,50 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
332
382
|
return entry
|
|
333
383
|
}
|
|
334
384
|
|
|
335
|
-
|
|
336
|
-
|
|
385
|
+
const invalidateEntry = (entry: Entry): void => {
|
|
386
|
+
entry.invalidated = true // next fetch refetches even within staleTime
|
|
387
|
+
// Supersede any in-flight fetch begun before this point - its result is pre-mutation and must
|
|
388
|
+
// not resolve as "fresh" or clear `invalidated`. The refetch below (or the next `fetch()`)
|
|
389
|
+
// starts a new generation that publishes the post-mutation data.
|
|
390
|
+
entry.generation++
|
|
391
|
+
if (entry.subscribers > 0) void entry.handle.refetch().catch(() => {}) // refresh mounted now (best-effort)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Get an entry by key, or create + insert a fresh one. `fn`/`staleTime`/`live` re-bind on an
|
|
395
|
+
// existing entry; `live` stays as it is when the call names none (a write, a hydration).
|
|
396
|
+
const upsert = (
|
|
397
|
+
key: unknown,
|
|
398
|
+
fn: () => Promise<unknown>,
|
|
399
|
+
staleTime: number,
|
|
400
|
+
live?: readonly string[],
|
|
401
|
+
): Entry => {
|
|
337
402
|
const h = hashQueryKey(key)
|
|
338
403
|
const existing = cache.get(h)
|
|
339
404
|
if (existing !== undefined) {
|
|
340
405
|
existing.fn = fn
|
|
341
406
|
existing.staleTime = staleTime
|
|
407
|
+
relive(existing, live)
|
|
342
408
|
return existing
|
|
343
409
|
}
|
|
344
410
|
const entry = makeEntry(key, fn, staleTime)
|
|
411
|
+
relive(entry, live)
|
|
345
412
|
cache.set(h, entry)
|
|
346
413
|
return entry
|
|
347
414
|
}
|
|
348
415
|
|
|
349
416
|
const query = <T>(key: unknown, fn: () => Promise<T>, opts?: QueryOptions): QueryHandle<T> => {
|
|
350
417
|
sweep()
|
|
351
|
-
return upsert(
|
|
352
|
-
|
|
418
|
+
return upsert(
|
|
419
|
+
key,
|
|
420
|
+
fn as () => Promise<unknown>,
|
|
421
|
+
opts?.staleTime ?? defaultStaleTime,
|
|
422
|
+
opts?.live ?? [],
|
|
423
|
+
).handle as QueryHandle<T>
|
|
353
424
|
}
|
|
354
425
|
|
|
355
426
|
const invalidateQueries = (keyOrPrefix: unknown): void => {
|
|
356
427
|
for (const entry of cache.values()) {
|
|
357
|
-
if (
|
|
358
|
-
entry.invalidated = true // next fetch refetches even within staleTime
|
|
359
|
-
// Supersede any in-flight fetch begun before this point - its result is pre-mutation and must
|
|
360
|
-
// not resolve as "fresh" or clear `invalidated`. The refetch below (or the next `fetch()`)
|
|
361
|
-
// starts a new generation that publishes the post-mutation data.
|
|
362
|
-
entry.generation++
|
|
363
|
-
if (entry.subscribers > 0) void entry.handle.refetch().catch(() => {}) // refresh mounted now (best-effort)
|
|
428
|
+
if (keyMatchesPrefix(entry.key, keyOrPrefix)) invalidateEntry(entry)
|
|
364
429
|
}
|
|
365
430
|
for (const entry of infinite.values()) {
|
|
366
431
|
if (keyMatchesPrefix(entry.key, keyOrPrefix)) entry.invalidate()
|
|
@@ -391,6 +456,7 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
391
456
|
// and clear the invalidated flag (the caller just supplied fresh data).
|
|
392
457
|
entry.generation++
|
|
393
458
|
entry.invalidated = false
|
|
459
|
+
entry.dataTick = liveTick()
|
|
394
460
|
entry.setState(successState(data, now()))
|
|
395
461
|
}
|
|
396
462
|
|
|
@@ -400,7 +466,12 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
400
466
|
opts?: QueryOptions,
|
|
401
467
|
): Promise<void> => {
|
|
402
468
|
sweep()
|
|
403
|
-
await upsert(
|
|
469
|
+
await upsert(
|
|
470
|
+
key,
|
|
471
|
+
fn as () => Promise<unknown>,
|
|
472
|
+
opts?.staleTime ?? defaultStaleTime,
|
|
473
|
+
opts?.live,
|
|
474
|
+
).run(false)
|
|
404
475
|
}
|
|
405
476
|
|
|
406
477
|
const dehydrate = (): DehydratedState => {
|
|
@@ -433,8 +504,11 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
433
504
|
// Don't clobber a client entry that's already fresher than the server snapshot (the client may
|
|
434
505
|
// have refetched between SSR and hydration). Seed only when we have no successful data or the
|
|
435
506
|
// incoming snapshot is newer.
|
|
436
|
-
if (entry.state.status !== "success" || q.updatedAt > entry.state.updatedAt)
|
|
507
|
+
if (entry.state.status !== "success" || q.updatedAt > entry.state.updatedAt) {
|
|
508
|
+
// Read before any live load took a watermark: the first grant of its keys refetches it.
|
|
509
|
+
entry.dataTick = 0
|
|
437
510
|
entry.setState(successState(q.data, q.updatedAt))
|
|
511
|
+
}
|
|
438
512
|
}
|
|
439
513
|
// An infinite entry needs its page options before it can exist, so a snapshot for a key not yet
|
|
440
514
|
// queried waits here until `infiniteQuery` creates it.
|
|
@@ -473,15 +547,16 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
473
547
|
}
|
|
474
548
|
|
|
475
549
|
// Infinite entries live in their own map (their data shape + fetch model differ from plain queries).
|
|
476
|
-
interface InfiniteEntry<T, P> {
|
|
550
|
+
interface InfiniteEntry<T, P> extends LiveFields {
|
|
477
551
|
readonly key: unknown
|
|
478
552
|
handle: InfiniteQueryHandle<T, P>
|
|
479
553
|
rebind: (fn: (p: P) => Promise<T>, opts: InfiniteQueryOptions<T, P>) => void
|
|
480
554
|
/** Mark stale, drop an in-flight fetch's result, and refetch when mounted. */
|
|
481
555
|
invalidate: () => void
|
|
556
|
+
/** Back to pending, dropping an in-flight fetch's result; refetch the first page when mounted. */
|
|
557
|
+
reset: () => void
|
|
482
558
|
/** Take a dehydrated snapshot unless the entry already holds fresher data. */
|
|
483
559
|
seed: (data: InfiniteData<unknown, unknown>, updatedAt: number) => void
|
|
484
|
-
subscribers: number
|
|
485
560
|
gcAt: number | undefined
|
|
486
561
|
}
|
|
487
562
|
const infinite = new Map<string, InfiniteEntry<unknown, unknown>>()
|
|
@@ -495,9 +570,12 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
495
570
|
let fn = fetchPage
|
|
496
571
|
let opts = initialOpts
|
|
497
572
|
let state: QueryState<InfiniteData<T, P>> = PENDING as QueryState<InfiniteData<T, P>>
|
|
573
|
+
const pending = state
|
|
498
574
|
let generation = 0
|
|
499
575
|
let invalidated = false
|
|
500
576
|
let promise: Promise<InfiniteData<T, P>> | undefined
|
|
577
|
+
let startTick = 0
|
|
578
|
+
let dataTick = 0
|
|
501
579
|
const listeners = new Set<() => void>()
|
|
502
580
|
const emit = (): void => {
|
|
503
581
|
for (const l of listeners) l()
|
|
@@ -532,12 +610,15 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
532
610
|
const runPaged = (build: () => Promise<InfiniteData<T, P>>): Promise<InfiniteData<T, P>> => {
|
|
533
611
|
if (promise !== undefined) return promise
|
|
534
612
|
const gen = ++generation
|
|
613
|
+
const started = liveTick()
|
|
614
|
+
startTick = started
|
|
535
615
|
setState({ ...state, isFetching: true })
|
|
536
616
|
const p = (async () => {
|
|
537
617
|
try {
|
|
538
618
|
const data = await build()
|
|
539
619
|
if (gen !== generation) return data
|
|
540
620
|
invalidated = false
|
|
621
|
+
dataTick = started
|
|
541
622
|
setState(successState(data, now()))
|
|
542
623
|
return data
|
|
543
624
|
} catch (error) {
|
|
@@ -566,10 +647,14 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
566
647
|
entry.subscribers++
|
|
567
648
|
entry.gcAt = undefined
|
|
568
649
|
listeners.add(listener)
|
|
650
|
+
if (entry.subscribers === 1) querySeam()?.track(lq, true)
|
|
569
651
|
return () => {
|
|
570
652
|
listeners.delete(listener)
|
|
571
653
|
entry.subscribers--
|
|
572
|
-
if (entry.subscribers === 0)
|
|
654
|
+
if (entry.subscribers === 0) {
|
|
655
|
+
entry.gcAt = now() + gcTime
|
|
656
|
+
querySeam()?.track(lq, false)
|
|
657
|
+
}
|
|
573
658
|
}
|
|
574
659
|
},
|
|
575
660
|
fetch: () => fetchFirst(false),
|
|
@@ -614,12 +699,18 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
614
699
|
return p !== undefined && p !== null
|
|
615
700
|
},
|
|
616
701
|
}
|
|
702
|
+
const lq: LiveQuery = {
|
|
703
|
+
keys: () => entry.live,
|
|
704
|
+
tick: () => (promise !== undefined ? startTick : dataTick),
|
|
705
|
+
refresh: () => entry.invalidate(),
|
|
706
|
+
}
|
|
617
707
|
const entry: InfiniteEntry<T, P> = {
|
|
618
708
|
key,
|
|
619
709
|
handle,
|
|
620
710
|
rebind: (nextFn, nextOpts) => {
|
|
621
711
|
fn = nextFn
|
|
622
712
|
opts = nextOpts
|
|
713
|
+
relive(entry, nextOpts.live ?? [])
|
|
623
714
|
},
|
|
624
715
|
invalidate: () => {
|
|
625
716
|
invalidated = true
|
|
@@ -629,18 +720,50 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
629
720
|
promise = undefined
|
|
630
721
|
if (entry.subscribers > 0) void handle.refetch().catch(() => {})
|
|
631
722
|
},
|
|
723
|
+
reset: () => {
|
|
724
|
+
invalidated = true
|
|
725
|
+
generation++
|
|
726
|
+
promise = undefined
|
|
727
|
+
dataTick = 0
|
|
728
|
+
setState(pending)
|
|
729
|
+
if (entry.subscribers > 0) void handle.refetch().catch(() => {})
|
|
730
|
+
},
|
|
632
731
|
seed: (data, updatedAt) => {
|
|
633
732
|
if (state.status === "success" && state.updatedAt >= updatedAt) return
|
|
733
|
+
dataTick = 0
|
|
634
734
|
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: the snapshot was dehydrated from an entry under this key, whose pages and params are T and P
|
|
635
735
|
setState(successState(data as InfiniteData<T, P>, updatedAt))
|
|
636
736
|
},
|
|
637
737
|
subscribers: 0,
|
|
638
738
|
gcAt: undefined,
|
|
739
|
+
live: [],
|
|
740
|
+
lq,
|
|
639
741
|
}
|
|
742
|
+
relive(entry, initialOpts.live)
|
|
640
743
|
return entry
|
|
641
744
|
}
|
|
642
745
|
|
|
643
|
-
|
|
746
|
+
const clear = (): void => {
|
|
747
|
+
seeded.clear()
|
|
748
|
+
for (const [h, entry] of cache) {
|
|
749
|
+
// An in-flight fetch carried the last viewer's credentials: its result may not publish.
|
|
750
|
+
entry.generation++
|
|
751
|
+
entry.invalidated = true
|
|
752
|
+
entry.dataTick = 0
|
|
753
|
+
if (entry.subscribers === 0) {
|
|
754
|
+
cache.delete(h)
|
|
755
|
+
continue
|
|
756
|
+
}
|
|
757
|
+
entry.setState(PENDING)
|
|
758
|
+
void entry.handle.refetch().catch(() => {})
|
|
759
|
+
}
|
|
760
|
+
for (const [h, entry] of infinite) {
|
|
761
|
+
if (entry.subscribers === 0) infinite.delete(h)
|
|
762
|
+
entry.reset()
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const client: QueryClient = {
|
|
644
767
|
query,
|
|
645
768
|
infiniteQuery,
|
|
646
769
|
invalidateQueries,
|
|
@@ -649,7 +772,11 @@ export function createQueryClient(options: QueryClientOptions): QueryClient {
|
|
|
649
772
|
prefetchQuery,
|
|
650
773
|
dehydrate,
|
|
651
774
|
hydrate,
|
|
775
|
+
clear,
|
|
652
776
|
}
|
|
777
|
+
// A page with live refresh clears every client it made when the viewer changes.
|
|
778
|
+
adoptClient(client)
|
|
779
|
+
return client
|
|
653
780
|
}
|
|
654
781
|
|
|
655
782
|
// --- Standalone mutations -----------------------------------------------------------------------
|
package/src/render-seam.ts
CHANGED
|
@@ -135,6 +135,13 @@ export interface RenderStreamOptions {
|
|
|
135
135
|
readonly nonce?: string
|
|
136
136
|
/** Present only for an adapter that sets {@link RenderAdapter.documentParts}. */
|
|
137
137
|
readonly parts?: DocumentParts
|
|
138
|
+
/**
|
|
139
|
+
* Chain indices to render inside the two slot wrappers a kept page needs (`keepAlive`), each
|
|
140
|
+
* `<slot data-nifra-entry><slot data-nifra-page>` around that chain entry (a `<slot>` lays out as
|
|
141
|
+
* `display: contents`), so the browser's keep-alive view hydrates the same markup. Present only
|
|
142
|
+
* in an app with a `keepAlive` route; an adapter without keep-alive support ignores it.
|
|
143
|
+
*/
|
|
144
|
+
readonly slots?: readonly number[]
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
/**
|
|
@@ -167,13 +174,41 @@ export interface RenderAdapter {
|
|
|
167
174
|
): string | undefined | Promise<string | undefined>
|
|
168
175
|
/** Per-document bootstrap markup injected into `<head>` for client hydration. */
|
|
169
176
|
hydrationHead(nonce?: string): string
|
|
177
|
+
/**
|
|
178
|
+
* Render one piece of UI (a boundary's `render` result or `fallback`) to an HTML string on its own,
|
|
179
|
+
* outside the route chain. `ui` produces it: call it inside the render, since a framework whose
|
|
180
|
+
* markup is made as it is evaluated (Solid) needs its render context there. `idPrefix` namespaces
|
|
181
|
+
* any ids the framework generates, so two fragments rendered separately never collide. `hydrates`
|
|
182
|
+
* is set when the client hydrates the fragment as a root of its own (an interactive hole). Required
|
|
183
|
+
* for partial prerendering; optional otherwise.
|
|
184
|
+
*/
|
|
185
|
+
renderFragment?(
|
|
186
|
+
ui: () => unknown,
|
|
187
|
+
options: { readonly idPrefix?: string; readonly hydrates?: boolean },
|
|
188
|
+
): string | Promise<string>
|
|
170
189
|
/**
|
|
171
190
|
* Set when a render can produce markup that belongs outside the app root. Every render is then
|
|
172
191
|
* passed `options.parts` to fill; an adapter without it never is, and pays nothing for the seam.
|
|
173
192
|
*/
|
|
174
193
|
readonly documentParts?: boolean
|
|
194
|
+
/**
|
|
195
|
+
* Render the chain and return only the HTML of the slot named `name`, or `undefined` when the
|
|
196
|
+
* render has no such slot. Called for an {@link SWAP_HEADER} request; an adapter without it, or a
|
|
197
|
+
* render without the slot, answers with the whole document, which the client loads normally.
|
|
198
|
+
*/
|
|
199
|
+
renderSlot?(
|
|
200
|
+
chain: readonly unknown[],
|
|
201
|
+
props: RenderProps,
|
|
202
|
+
name: string,
|
|
203
|
+
): string | undefined | Promise<string | undefined>
|
|
175
204
|
}
|
|
176
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Request header of a `data-swap` link or form: the name of the slot it refreshes. A response that
|
|
208
|
+
* carries only that slot echoes it; any other response is a whole document.
|
|
209
|
+
*/
|
|
210
|
+
export const SWAP_HEADER = "x-nifra-swap"
|
|
211
|
+
|
|
177
212
|
/** Loads a module through the dev server's module graph rather than the runtime's resolver. */
|
|
178
213
|
export type SsrModuleLoader = (id: string) => Promise<unknown>
|
|
179
214
|
|
|
@@ -209,6 +244,8 @@ export const ACTION_GLOBAL = "__NIFRA_ACTION__"
|
|
|
209
244
|
/** Dynamic-boundary states for hydration; absent when a route declares no boundaries. */
|
|
210
245
|
export const BOUNDARY_GLOBAL = "__NIFRA_BOUNDARIES__"
|
|
211
246
|
export const COMPONENT_GLOBAL = "__NIFRA_COMPONENTS__"
|
|
247
|
+
/** A live app's seed for the page: the client exchanges it for a grant once its socket opens. */
|
|
248
|
+
export const LIVE_GLOBAL = "__NIFRA_LIVE__"
|
|
212
249
|
/** Locale key -> copy chunk URL, in a production build that split copy tables by locale. The name
|
|
213
250
|
* `@nifrajs/i18n/copy` reads. */
|
|
214
251
|
export const COPY_CHUNKS_GLOBAL = "__NIFRA_COPY__"
|
package/src/route-types.ts
CHANGED
|
@@ -144,7 +144,7 @@ function routeTypesModule(
|
|
|
144
144
|
)
|
|
145
145
|
lines.push(
|
|
146
146
|
route.kind === "page"
|
|
147
|
-
? 'import type { MetaArgs as WebMetaArgs, RenderProps } from "@nifrajs/web"'
|
|
147
|
+
? 'import type { BoundaryLoadersOf, MetaArgs as WebMetaArgs, RenderProps } from "@nifrajs/web"'
|
|
148
148
|
: 'import type { MetaArgs as WebMetaArgs } from "@nifrajs/web"',
|
|
149
149
|
)
|
|
150
150
|
lines.push("")
|
|
@@ -181,6 +181,8 @@ function routeTypesModule(
|
|
|
181
181
|
" readonly actionData?: ActionData",
|
|
182
182
|
" readonly params: Params",
|
|
183
183
|
" }",
|
|
184
|
+
" /** The backend half's `boundaryLoaders`. Check it, `export const boundaryLoaders = { ... } satisfies Route.BoundaryLoaders`, and a key must name a boundary the page declares; with a `shellLoader`, every hole needs one. */",
|
|
185
|
+
` export type BoundaryLoaders = BoundaryLoadersOf<${frontend === undefined ? "unknown" : "Frontend"}, ${backend === undefined ? "unknown" : "Backend"}>`,
|
|
184
186
|
)
|
|
185
187
|
} else {
|
|
186
188
|
lines.push(
|