@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
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KEYS[1] the stream, KEYS[2] the clock hash; ARGV[1] the event JSON, ARGV[2] the trim length.
|
|
3
|
+
* Lua numbers are doubles: a microsecond clock stays exact below 2^53 (the year 2255).
|
|
4
|
+
*/
|
|
5
|
+
export const APPEND_SCRIPT = `local t = redis.call('TIME')
|
|
6
|
+
local now = tonumber(t[1]) * 1000000 + tonumber(t[2])
|
|
7
|
+
local last = tonumber(redis.call('HGET', KEYS[2], 'seq') or '0')
|
|
8
|
+
local seq = math.max(last + 1, now)
|
|
9
|
+
local id = string.format('%.0f', seq)
|
|
10
|
+
local n = redis.call('HINCRBY', KEYS[2], 'n', 1)
|
|
11
|
+
redis.call('HSET', KEYS[2], 'seq', id)
|
|
12
|
+
redis.call('XADD', KEYS[1], 'MAXLEN', '~', ARGV[2], id .. '-0', 'n', n, 'e', ARGV[1])
|
|
13
|
+
return id`;
|
|
14
|
+
const RETRY_MS = [100, 500, 1_000, 2_000, 5_000];
|
|
15
|
+
const READ_GRACE_MS = 5_000;
|
|
16
|
+
export function redisLiveBus(options) {
|
|
17
|
+
const key = options.key ?? "nifra:live";
|
|
18
|
+
const clock = `${key}:clock`;
|
|
19
|
+
const maxLength = String(options.maxLength ?? 100_000);
|
|
20
|
+
const blockMs = String(options.blockMs ?? 5_000);
|
|
21
|
+
const readTimeoutMs = options.readTimeoutMs ?? (options.blockMs ?? 5_000) + READ_GRACE_MS;
|
|
22
|
+
/** The clock's seq and running count, as the last append left them. */
|
|
23
|
+
const position = async () => {
|
|
24
|
+
const reply = await options.send("HMGET", [clock, "seq", "n"]);
|
|
25
|
+
const [seq, n] = Array.isArray(reply) ? reply : [];
|
|
26
|
+
return { seq: countOf(seq), n: countOf(n) };
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
async append(input) {
|
|
30
|
+
const reply = await options.send("EVAL", [
|
|
31
|
+
APPEND_SCRIPT,
|
|
32
|
+
"2",
|
|
33
|
+
key,
|
|
34
|
+
clock,
|
|
35
|
+
JSON.stringify(input),
|
|
36
|
+
maxLength,
|
|
37
|
+
]);
|
|
38
|
+
const seq = countOf(reply);
|
|
39
|
+
if (seq === 0)
|
|
40
|
+
throw new Error("[nifra/web] live-redis: the append script returned no seq");
|
|
41
|
+
return seq;
|
|
42
|
+
},
|
|
43
|
+
async subscribe(listener) {
|
|
44
|
+
const read = options.read;
|
|
45
|
+
if (read === undefined) {
|
|
46
|
+
throw new TypeError("[nifra/web] live-redis: subscribing needs `read`, a connection of its own; a bus without one only appends");
|
|
47
|
+
}
|
|
48
|
+
const start = await position();
|
|
49
|
+
let closed = false;
|
|
50
|
+
void follow(read, start.seq, start.n, listener, () => closed);
|
|
51
|
+
return {
|
|
52
|
+
head: start.seq,
|
|
53
|
+
close: () => {
|
|
54
|
+
closed = true;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
async function follow(read, head, count, listener, isClosed) {
|
|
60
|
+
let last = head;
|
|
61
|
+
// The id the next read starts after, verbatim: an id this bus did not write still moves it on.
|
|
62
|
+
let cursor = `${head}-0`;
|
|
63
|
+
let expected = count + 1;
|
|
64
|
+
let failures = 0;
|
|
65
|
+
// Told `down`: only a read that answers again ends the outage, never the clock alone.
|
|
66
|
+
let down = false;
|
|
67
|
+
while (!isClosed()) {
|
|
68
|
+
let entries;
|
|
69
|
+
let error;
|
|
70
|
+
try {
|
|
71
|
+
const reply = await within(read("XREAD", ["BLOCK", blockMs, "COUNT", "1000", "STREAMS", key, cursor]), readTimeoutMs);
|
|
72
|
+
entries = reply === null || reply === undefined ? [] : entriesOf(reply);
|
|
73
|
+
if (entries === undefined)
|
|
74
|
+
error = new Error("[nifra/web] live-redis: XREAD replied in no known shape");
|
|
75
|
+
}
|
|
76
|
+
catch (failure) {
|
|
77
|
+
entries = undefined;
|
|
78
|
+
error = failure;
|
|
79
|
+
}
|
|
80
|
+
// Closed while the read was blocked: closing its connection next is the caller's shutdown.
|
|
81
|
+
if (isClosed())
|
|
82
|
+
return;
|
|
83
|
+
if (entries === undefined) {
|
|
84
|
+
// A reply of no known shape counts as a failed read, so it backs off instead of spinning.
|
|
85
|
+
failures++;
|
|
86
|
+
// One failed read may be a hiccup; a second in a row is an outage.
|
|
87
|
+
if (failures === 2) {
|
|
88
|
+
down = true;
|
|
89
|
+
listener.down(error);
|
|
90
|
+
}
|
|
91
|
+
await wait(RETRY_MS[Math.min(failures - 1, RETRY_MS.length - 1)] ?? 5_000);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
failures = 0;
|
|
95
|
+
if (down) {
|
|
96
|
+
try {
|
|
97
|
+
const now = await position();
|
|
98
|
+
if (isClosed())
|
|
99
|
+
return;
|
|
100
|
+
// Whatever happened while the bus was unreachable is unknown: resume after the clock.
|
|
101
|
+
listener.gap(now.seq);
|
|
102
|
+
last = now.seq;
|
|
103
|
+
cursor = `${now.seq}-0`;
|
|
104
|
+
expected = now.n + 1;
|
|
105
|
+
down = false;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// The clock is out of reach: still down, and the next read tries again.
|
|
109
|
+
}
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
if (isClosed())
|
|
114
|
+
return;
|
|
115
|
+
cursor = entry.id;
|
|
116
|
+
if (entry.seq === 0) {
|
|
117
|
+
listener.gap(last);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (entry.n !== expected) {
|
|
121
|
+
// Entries between were trimmed before this reader got to them.
|
|
122
|
+
listener.gap(entry.seq - 1);
|
|
123
|
+
}
|
|
124
|
+
expected = entry.n + 1;
|
|
125
|
+
last = entry.seq;
|
|
126
|
+
if (entry.event === undefined)
|
|
127
|
+
listener.gap(entry.seq);
|
|
128
|
+
else
|
|
129
|
+
listener.event(entry.event);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The entries of an `XREAD` reply for one stream - RESP2 `[[key, entries]]`, RESP3 `{ key: entries }`
|
|
136
|
+
* or a `Map` - each entry `[id, [field, value, ...]]`. Undefined when the reply has none of these shapes.
|
|
137
|
+
*/
|
|
138
|
+
function entriesOf(reply) {
|
|
139
|
+
let streams;
|
|
140
|
+
if (Array.isArray(reply))
|
|
141
|
+
streams = reply.map((stream) => (Array.isArray(stream) ? stream[1] : undefined));
|
|
142
|
+
else if (reply instanceof Map)
|
|
143
|
+
streams = [...reply.values()];
|
|
144
|
+
else if (isRecord(reply))
|
|
145
|
+
streams = Object.values(reply);
|
|
146
|
+
else
|
|
147
|
+
return undefined;
|
|
148
|
+
const out = [];
|
|
149
|
+
for (const entries of streams) {
|
|
150
|
+
if (!Array.isArray(entries))
|
|
151
|
+
return undefined;
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
if (!Array.isArray(entry))
|
|
154
|
+
return undefined;
|
|
155
|
+
const [id, fields] = entry;
|
|
156
|
+
if (typeof id !== "string" || !Array.isArray(fields))
|
|
157
|
+
return undefined;
|
|
158
|
+
const [time, part] = id.split("-");
|
|
159
|
+
const seq = part === "0" ? countOf(time) : 0;
|
|
160
|
+
let n = 0;
|
|
161
|
+
let body;
|
|
162
|
+
for (let i = 0; i + 1 < fields.length; i += 2) {
|
|
163
|
+
if (fields[i] === "n")
|
|
164
|
+
n = countOf(fields[i + 1]);
|
|
165
|
+
else if (fields[i] === "e")
|
|
166
|
+
body = fields[i + 1];
|
|
167
|
+
}
|
|
168
|
+
out.push({ id, seq, n, event: seq === 0 ? undefined : eventOf(body, seq) });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
function eventOf(body, seq) {
|
|
174
|
+
if (typeof body !== "string")
|
|
175
|
+
return undefined;
|
|
176
|
+
let value;
|
|
177
|
+
try {
|
|
178
|
+
value = JSON.parse(body);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
if (!isRecord(value))
|
|
184
|
+
return undefined;
|
|
185
|
+
if (value.type === "change" && Array.isArray(value.keys)) {
|
|
186
|
+
const keys = value.keys.filter((name) => typeof name === "string");
|
|
187
|
+
return { type: "change", keys, seq };
|
|
188
|
+
}
|
|
189
|
+
const { sub, key } = value;
|
|
190
|
+
if (value.type === "revoke" &&
|
|
191
|
+
(sub === null || typeof sub === "string") &&
|
|
192
|
+
(key === null || typeof key === "string")) {
|
|
193
|
+
return { type: "revoke", sub, key, seq };
|
|
194
|
+
}
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
198
|
+
/** A Redis integer reply or numeric string as a non-negative safe integer, else 0. */
|
|
199
|
+
function countOf(value) {
|
|
200
|
+
const n = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
|
|
201
|
+
return Number.isSafeInteger(n) && n > 0 ? n : 0;
|
|
202
|
+
}
|
|
203
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
204
|
+
/** `pending`, or a rejection once `ms` pass without it settling. */
|
|
205
|
+
function within(pending, ms) {
|
|
206
|
+
let timer;
|
|
207
|
+
const expiry = new Promise((_, reject) => {
|
|
208
|
+
timer = setTimeout(() => reject(new Error("[nifra/web] live-redis: the read timed out")), ms);
|
|
209
|
+
});
|
|
210
|
+
return Promise.race([pending, expiry]).finally(() => clearTimeout(timer));
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=live-redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-redis.js","sourceRoot":"","sources":["../src/live-redis.ts"],"names":[],"mappings":"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"}
|
package/dist/live.d.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live data refresh, server side. Loaders declare what their data depends on with `ctx.live(...keys)`;
|
|
3
|
+
* a live load returns an encrypted grant for those keys, and the client reloads through the same
|
|
4
|
+
* authorized path whenever one of them changes. Data never travels with a change notice.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { live } from "@nifrajs/web/live"
|
|
8
|
+
*
|
|
9
|
+
* const liveRuntime = live({ secret: process.env.LIVE_SECRET, subject: (ctx) => sessionUserId(ctx.request) })
|
|
10
|
+
* createWebApp({ ...options, live: liveRuntime })
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Every live load is a `POST` to the load endpoint that runs the target page as a `GET` through the
|
|
14
|
+
* whole app: every hook, middleware, gate and loader sees the target path, exactly as a navigation.
|
|
15
|
+
* Changes reach open pages over one WebSocket per tab, as opaque tags of the keys they watch.
|
|
16
|
+
*/
|
|
17
|
+
import { type Logger } from "@nifrajs/core/server";
|
|
18
|
+
import { type LiveRuntimeHandle } from "./internal/live-contract.js";
|
|
19
|
+
import { type LiveBus } from "./live/bus.js";
|
|
20
|
+
import { type LiveHubNamespace } from "./live/hub-protocol.js";
|
|
21
|
+
import type { LoaderContext } from "./manifest.js";
|
|
22
|
+
export type { LiveBus, LiveBusEvent, LiveBusInput, LiveBusListener, LiveBusSubscription, LiveChange, LiveRevocation, } from "./live/bus.js";
|
|
23
|
+
export { livePublisher, memoryBus, nextSeq } from "./live/bus.js";
|
|
24
|
+
export interface LiveOptions {
|
|
25
|
+
/**
|
|
26
|
+
* The grant secret, or a rotation list with the newest first (at most 3, each at least 32 bytes).
|
|
27
|
+
* Required in production; development falls back to a random per-process secret.
|
|
28
|
+
*/
|
|
29
|
+
readonly secret?: string | readonly string[] | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Who the viewer is: a stable id, or `null` for an anonymous viewer. Called once per live load,
|
|
32
|
+
* after middleware. A grant is only honored for the subject it was issued to.
|
|
33
|
+
*/
|
|
34
|
+
readonly subject: (ctx: LoaderContext) => string | null | Promise<string | null>;
|
|
35
|
+
/** Separates this app's tags from another app's that shares a secret. Default `"nifra"`. */
|
|
36
|
+
readonly appId?: string;
|
|
37
|
+
/** Grant lifetime in seconds, at most 3600. Default 600. */
|
|
38
|
+
readonly grantTtl?: number;
|
|
39
|
+
/** The live load endpoint. Default `/_nifra/live/load`. */
|
|
40
|
+
readonly loadPath?: string;
|
|
41
|
+
/** The live socket. Default `/_nifra/live`. */
|
|
42
|
+
readonly path?: string;
|
|
43
|
+
/** Origins besides the app's own that may call the load endpoint and open the socket. */
|
|
44
|
+
readonly trustedOrigins?: readonly string[];
|
|
45
|
+
/** Live loads running at once in this process; past it the endpoint answers 503. Default 64. */
|
|
46
|
+
readonly maxConcurrentLoads?: number;
|
|
47
|
+
/** Live sockets in this process; past it a socket is closed with 1013. Default 10,000. */
|
|
48
|
+
readonly maxSockets?: number;
|
|
49
|
+
/** Refuse new sockets while the process's resident memory is above this many bytes. */
|
|
50
|
+
readonly maxRssBytes?: number;
|
|
51
|
+
/**
|
|
52
|
+
* The ordered log every process serving the app shares. Default: an in-process bus, right for one
|
|
53
|
+
* process only.
|
|
54
|
+
*/
|
|
55
|
+
readonly bus?: LiveBus;
|
|
56
|
+
/**
|
|
57
|
+
* Cloudflare Workers: the Durable Object namespace of the app's live hub (`liveHub()` from
|
|
58
|
+
* `@nifrajs/web/live-hub`). The hub owns the log and holds the sockets; this isolate forwards the
|
|
59
|
+
* socket handshake to it, asks it for the seq and the revocations each load needs, and publishes
|
|
60
|
+
* through it. Exclusive with `bus`.
|
|
61
|
+
*/
|
|
62
|
+
readonly hub?: LiveHubNamespace;
|
|
63
|
+
/** Processes serving the app, for spreading reloads. Default 1. */
|
|
64
|
+
readonly instances?: number;
|
|
65
|
+
/** Live loads per second the deployment absorbs after one change, for spreading reloads. Default 500. */
|
|
66
|
+
readonly reloadRate?: number;
|
|
67
|
+
/** The least time, in ms, clients spread their reloads over. Default 0. */
|
|
68
|
+
readonly spreadFloor?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Re-check the keys of owners a load keeps without running their loaders. With it, `renew`
|
|
71
|
+
* re-signs a grant without loaders (every third renewal still runs them all, so a lost change is
|
|
72
|
+
* found within about 27 minutes); without it, `renew` runs a full load. `false` issues no grant.
|
|
73
|
+
*/
|
|
74
|
+
readonly authorize?: (keys: readonly string[], ctx: LoaderContext) => boolean | Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* Resolves once a committed write is readable by every loader, such as a read replica catching up.
|
|
77
|
+
* `publish` waits for it, so no client reloads before its data can show the change. Replica-backed
|
|
78
|
+
* reads need it; without it a publish goes out as soon as it is called.
|
|
79
|
+
*/
|
|
80
|
+
readonly visible?: () => void | Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Let query hooks refetch on the keys a page's loaders grant (`useQuery(key, fn, { live })`). Each
|
|
83
|
+
* live load then carries a salted digest of every key it grants: page code can confirm a guess at
|
|
84
|
+
* one of them, so leave it off when key names hold anything the viewer should not see.
|
|
85
|
+
*/
|
|
86
|
+
readonly queryKeys?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Where the runtime reports what it cannot fix by itself: the bus stopping to answer and answering
|
|
89
|
+
* again, events lost to a trim, an event it could not apply, a publish it did not read back.
|
|
90
|
+
* Default `jsonLogger()`; `false` reports nothing. {@link Live.status} has the same state to poll.
|
|
91
|
+
*/
|
|
92
|
+
readonly logger?: Logger | false;
|
|
93
|
+
}
|
|
94
|
+
/** What one process's live runtime is doing now; counters run from its start. */
|
|
95
|
+
export interface LiveStatus {
|
|
96
|
+
/** The keyring is derived and the bus read: grants can be issued. */
|
|
97
|
+
readonly ready: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* No grant is issued and no socket kept: the bus (or the Workers hub) is unreachable, or the
|
|
100
|
+
* runtime was closed. Open pages poll meanwhile.
|
|
101
|
+
*/
|
|
102
|
+
readonly down: boolean;
|
|
103
|
+
/** Since when `down` has held, in epoch ms. */
|
|
104
|
+
readonly downSince: number | undefined;
|
|
105
|
+
/** Live sockets open in this process. On Workers the hub holds them, so this is 0. */
|
|
106
|
+
readonly sockets: number;
|
|
107
|
+
/** Live loads running in this process. */
|
|
108
|
+
readonly loads: number;
|
|
109
|
+
/** Bus events this process applied. */
|
|
110
|
+
readonly events: number;
|
|
111
|
+
/** `changed` frames this process sent, one per watching socket: each makes a page reload. */
|
|
112
|
+
readonly notified: number;
|
|
113
|
+
/**
|
|
114
|
+
* How long after its append the last event was applied here, in ms. The append time comes from the
|
|
115
|
+
* bus's clock, so skew between hosts shows in it.
|
|
116
|
+
*/
|
|
117
|
+
readonly lagMs: number | undefined;
|
|
118
|
+
}
|
|
119
|
+
/** A live runtime: pass it to `createWebApp({ live })`. */
|
|
120
|
+
export interface Live extends LiveRuntimeHandle {
|
|
121
|
+
/** Resolves once the secrets are derived and the bus is read; rejects on a duplicate secret id. */
|
|
122
|
+
readonly ready: Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* `keys` changed: every open page watching one reloads it. Call it after the write is visible to
|
|
125
|
+
* loaders; resolves once this process has applied it, or 2 s after the bus took it if this process
|
|
126
|
+
* has not read it back by then.
|
|
127
|
+
*/
|
|
128
|
+
publish(...keys: string[]): Promise<void>;
|
|
129
|
+
/** Refuse every grant issued to `subject` before now, and close its sockets. */
|
|
130
|
+
revoke(subject: string): Promise<void>;
|
|
131
|
+
/** Refuse every grant issued before now, and close every socket. */
|
|
132
|
+
revokeAll(): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Access to `key` was removed (for everyone, or for one subject): every watcher gets one last change
|
|
135
|
+
* for it and stops watching it, and no grant issued before now keeps or re-signs it, so the next load
|
|
136
|
+
* runs that owner's loader, which decides again.
|
|
137
|
+
*/
|
|
138
|
+
revokeKey(key: string, subject?: string): Promise<void>;
|
|
139
|
+
/** What this process's runtime is doing now: for a readiness check or metrics. */
|
|
140
|
+
status(): LiveStatus;
|
|
141
|
+
/**
|
|
142
|
+
* Stop reading the bus and close every live socket (1001); open pages poll until they reach another
|
|
143
|
+
* process. Call it before closing the bus's connections, so the reader does not count that as an
|
|
144
|
+
* outage. A publish after it throws. Idempotent.
|
|
145
|
+
*/
|
|
146
|
+
close(): Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
/** Create the live runtime for one app. */
|
|
149
|
+
export declare function live(options: LiveOptions): Live;
|
|
150
|
+
//# sourceMappingURL=live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"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"}
|