@nifrajs/web 5.5.1 → 5.6.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 +154 -0
- 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 +9 -0
- package/dist/build.js.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +140 -12
- 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 +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- 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 +65 -8
- 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 +179 -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 +96 -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 +14 -1
- package/dist/internal/page-execution.d.ts.map +1 -1
- package/dist/internal/page-execution.js +415 -31
- package/dist/internal/page-execution.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 +32 -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 +1407 -0
- package/dist/internal/ppr/server.js.map +1 -0
- package/dist/internal/ppr/shell-store.d.ts +38 -0
- package/dist/internal/ppr/shell-store.d.ts.map +1 -0
- package/dist/internal/ppr/shell-store.js +90 -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/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 +28 -1
- package/dist/internal/render-document.d.ts.map +1 -1
- package/dist/internal/render-document.js +83 -18
- 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/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 +25 -0
- package/dist/internal/web-app.d.ts.map +1 -1
- package/dist/internal/web-app.js +78 -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 +1069 -0
- package/dist/keep-alive.js.map +1 -0
- package/dist/live/bus.d.ts +56 -0
- package/dist/live/bus.d.ts.map +1 -0
- package/dist/live/bus.js +32 -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 +181 -0
- package/dist/live/hub.d.ts.map +1 -0
- package/dist/live/hub.js +539 -0
- package/dist/live/hub.js.map +1 -0
- package/dist/live/keyring.d.ts +87 -0
- package/dist/live/keyring.d.ts.map +1 -0
- package/dist/live/keyring.js +260 -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 +840 -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 +48 -0
- package/dist/live-redis.d.ts.map +1 -0
- package/dist/live-redis.js +201 -0
- package/dist/live-redis.js.map +1 -0
- package/dist/live.d.ts +94 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +869 -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 +30 -0
- package/dist/render-seam.d.ts.map +1 -1
- package/dist/render-seam.js +5 -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 +374 -99
- 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/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 +86 -28
- 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/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 +19 -1
- package/src/client.ts +147 -10
- 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 +19 -0
- package/src/internal/cdn/cloudflare.ts +2 -1
- package/src/internal/certified-components.ts +1 -1
- package/src/internal/codegen.ts +87 -8
- package/src/internal/dev-websocket.ts +230 -0
- package/src/internal/hole-runtime.ts +286 -0
- package/src/internal/identity-epoch.ts +235 -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 +106 -0
- package/src/internal/live-queries.ts +60 -0
- package/src/internal/page-events.ts +27 -0
- package/src/internal/page-execution.ts +579 -40
- 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 +36 -0
- package/src/internal/ppr/server.ts +1764 -0
- package/src/internal/ppr/shell-store.ts +139 -0
- package/src/internal/prerendered-pages.ts +7 -4
- 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 +149 -22
- 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/store-signature.ts +149 -0
- package/src/internal/vite-plugin-compat.ts +2 -2
- package/src/internal/web-app.ts +121 -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 +1315 -0
- package/src/live/bus.ts +77 -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 +615 -0
- package/src/live/keyring.ts +379 -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 +973 -0
- package/src/live-hub.ts +658 -0
- package/src/live-redis.ts +259 -0
- package/src/live.ts +1096 -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 +35 -0
- package/src/route-types.ts +3 -1
- package/src/router.ts +494 -101
- package/src/server-components/build.ts +9 -3
- package/src/server-components/client.ts +89 -5
- 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 +112 -30
- package/src/server-components/state.ts +66 -44
- package/src/server-components/types.ts +16 -0
- 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,149 @@
|
|
|
1
|
+
const ORDER = ["data", "pages", "publish", "cdn"];
|
|
2
|
+
/** Retry delays after a retryable failure; inline retries stop at {@link INLINE_DEADLINE_MS}. */
|
|
3
|
+
const RETRY_MS = [200, 600, 1800];
|
|
4
|
+
export const INLINE_DEADLINE_MS = 2000;
|
|
5
|
+
/** Run the stages from `from` once. */
|
|
6
|
+
export async function runInvalidation(op, targets, req, platform, from = "data") {
|
|
7
|
+
const stages = [];
|
|
8
|
+
for (const stage of ORDER.slice(ORDER.indexOf(from))) {
|
|
9
|
+
// Decided before any await: a stage with nothing to do costs no turn of the event loop.
|
|
10
|
+
const running = startStage(stage, op, targets, req, platform);
|
|
11
|
+
if (running === undefined)
|
|
12
|
+
continue;
|
|
13
|
+
const report = await running;
|
|
14
|
+
stages.push(report);
|
|
15
|
+
// A cache stage that failed leaves data a reload would read: nothing after it may run.
|
|
16
|
+
if (!report.ok && (stage === "data" || stage === "pages"))
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
return { id: op.id, ok: stages.every((report) => report.ok), stages };
|
|
20
|
+
}
|
|
21
|
+
/** Start a stage's work for this operation; `undefined` when it has none. Never rejects. */
|
|
22
|
+
function startStage(stage, op, targets, req, platform) {
|
|
23
|
+
const done = { stage, ok: true, retryable: false };
|
|
24
|
+
let work;
|
|
25
|
+
switch (stage) {
|
|
26
|
+
case "data": {
|
|
27
|
+
const caches = targets.dataCaches;
|
|
28
|
+
if (op.tags.length === 0 || caches === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
work = (async () => {
|
|
31
|
+
for (const cache of caches) {
|
|
32
|
+
for (const tag of op.tags)
|
|
33
|
+
await cache.invalidateTag(tag);
|
|
34
|
+
}
|
|
35
|
+
return done;
|
|
36
|
+
})();
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "pages": {
|
|
40
|
+
const store = targets.store;
|
|
41
|
+
if (store === undefined || op.paths.length + op.tags.length === 0)
|
|
42
|
+
return undefined;
|
|
43
|
+
work = (async () => {
|
|
44
|
+
if (op.tags.length > 0 && store.invalidateTag === undefined) {
|
|
45
|
+
return { stage, ok: false, retryable: false, error: "tag_invalidation_not_supported" };
|
|
46
|
+
}
|
|
47
|
+
for (const path of op.paths) {
|
|
48
|
+
const key = targets.keyOf?.(path, req) ?? null;
|
|
49
|
+
if (key !== null)
|
|
50
|
+
await store.delete(key);
|
|
51
|
+
}
|
|
52
|
+
for (const tag of op.tags)
|
|
53
|
+
await store.invalidateTag?.(tag);
|
|
54
|
+
return done;
|
|
55
|
+
})();
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case "publish": {
|
|
59
|
+
const publish = targets.publish;
|
|
60
|
+
if (publish === undefined || op.keys.length + op.tags.length === 0)
|
|
61
|
+
return undefined;
|
|
62
|
+
work = (async () => {
|
|
63
|
+
await publish([...new Set([...op.keys, ...op.tags])]);
|
|
64
|
+
return done;
|
|
65
|
+
})();
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case "cdn": {
|
|
69
|
+
const cdn = targets.cdn;
|
|
70
|
+
if (cdn === undefined || op.paths.length + op.tags.length === 0)
|
|
71
|
+
return undefined;
|
|
72
|
+
work = (async () => {
|
|
73
|
+
const outcome = await cdn.purge({ tags: op.tags, paths: op.paths }, platform);
|
|
74
|
+
return outcome.cdn === "failed"
|
|
75
|
+
? {
|
|
76
|
+
stage,
|
|
77
|
+
ok: false,
|
|
78
|
+
retryable: outcome.retryable,
|
|
79
|
+
error: outcome.error ?? "cdn_purge_failed",
|
|
80
|
+
}
|
|
81
|
+
: outcome.cdn === "queued"
|
|
82
|
+
? { stage, ok: true, retryable: false, queued: true }
|
|
83
|
+
: done;
|
|
84
|
+
})();
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return work.catch(() => ({ stage, ok: false, retryable: true, error: `${stage}_failed` }));
|
|
89
|
+
}
|
|
90
|
+
const realClock = {
|
|
91
|
+
now: () => Date.now(),
|
|
92
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Run the pipeline for a write; never throws and never changes the response. A retryable failure
|
|
96
|
+
* retries from the failed stage, under `waitUntil` when the platform has it, else inline until
|
|
97
|
+
* {@link INLINE_DEADLINE_MS}. A failure that remains is reported once.
|
|
98
|
+
*/
|
|
99
|
+
export async function settleInvalidation(op, targets, req, platform, options = {}) {
|
|
100
|
+
const onError = options.onError ?? logInvalidation;
|
|
101
|
+
const clock = options.clock ?? realClock;
|
|
102
|
+
const started = clock.now();
|
|
103
|
+
const first = await runInvalidation(op, targets, req, platform);
|
|
104
|
+
if (first.ok)
|
|
105
|
+
return first;
|
|
106
|
+
const failed = first.stages.find((report) => !report.ok);
|
|
107
|
+
if (failed === undefined || !failed.retryable) {
|
|
108
|
+
report(onError, first);
|
|
109
|
+
return first;
|
|
110
|
+
}
|
|
111
|
+
const background = typeof platform?.waitUntil === "function";
|
|
112
|
+
const retry = async () => {
|
|
113
|
+
let last = first;
|
|
114
|
+
let stage = failed.stage;
|
|
115
|
+
for (const delay of RETRY_MS) {
|
|
116
|
+
if (!background && clock.now() - started + delay >= INLINE_DEADLINE_MS)
|
|
117
|
+
break;
|
|
118
|
+
await clock.sleep(delay);
|
|
119
|
+
last = await runInvalidation(op, targets, req, platform, stage);
|
|
120
|
+
const next = last.stages.find((report) => !report.ok);
|
|
121
|
+
if (next === undefined)
|
|
122
|
+
return last;
|
|
123
|
+
if (!next.retryable)
|
|
124
|
+
break;
|
|
125
|
+
stage = next.stage;
|
|
126
|
+
}
|
|
127
|
+
report(onError, last);
|
|
128
|
+
return last;
|
|
129
|
+
};
|
|
130
|
+
if (background) {
|
|
131
|
+
platform?.waitUntil?.(retry());
|
|
132
|
+
return first;
|
|
133
|
+
}
|
|
134
|
+
return retry();
|
|
135
|
+
}
|
|
136
|
+
function report(onError, value) {
|
|
137
|
+
try {
|
|
138
|
+
onError(value);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// A failing reporter must not reach the response.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** The default report: the operation id and the stage, never a path, tag or key. */
|
|
145
|
+
export function logInvalidation(report) {
|
|
146
|
+
const failed = report.stages.find((stage) => !stage.ok);
|
|
147
|
+
console.error(`[nifra/web] invalidation ${report.id} gave up at the ${failed?.stage ?? "unknown"} stage (${failed?.error ?? "failed"})`);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=invalidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidation.js","sourceRoot":"","sources":["../../src/internal/invalidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declarative binding walker - attaches signal-driven behavior to SERVER-RENDERED markup.
|
|
3
|
+
* No VDOM, no hydration re-render: the HTML the server sent (e.g. via `@nifrajs/web-vanilla`) is
|
|
4
|
+
* already the initial state; bindings update it surgically when signals change. `bindIsland` runs it.
|
|
5
|
+
*
|
|
6
|
+
* The attribute set is CLOSED and documented - six bindings, no expression language. Values are
|
|
7
|
+
* signal/handler NAMES looked up in the island's scope, never evaluated code, so markup can't
|
|
8
|
+
* inject behavior:
|
|
9
|
+
*
|
|
10
|
+
* data-bind-text="count" textContent ← String(signal())
|
|
11
|
+
* data-bind-show="isOpen" hidden ← !signal()
|
|
12
|
+
* data-bind-class="active:isOpen,b:sigB" classList.toggle per pair
|
|
13
|
+
* data-bind-attr="aria-expanded:isOpen" setAttribute / removeAttribute (false/null remove);
|
|
14
|
+
* never an `on*` handler or `srcdoc`, and a URL attribute
|
|
15
|
+
* takes only an http(s)/mailto/tel or relative URL
|
|
16
|
+
* data-bind-value="query" two-way <input>/<select>/<textarea> (input and change)
|
|
17
|
+
* data-bind-on="click:inc,submit:save" addEventListener per pair
|
|
18
|
+
*
|
|
19
|
+
* Nothing inside a `data-island-ignore` element binds or mounts: render user HTML there, so its
|
|
20
|
+
* markup cannot reach the island's handlers or signals.
|
|
21
|
+
*
|
|
22
|
+
* A binding belongs to its nearest island: an island never binds inside a nested island's host. The
|
|
23
|
+
* nested host element itself is still the outer island's markup, so the outer island may bind it.
|
|
24
|
+
*/
|
|
25
|
+
import { type Signal } from "./island-signals.js";
|
|
26
|
+
export type IslandScope = {
|
|
27
|
+
readonly signals: Readonly<Record<string, Signal<unknown>>>;
|
|
28
|
+
readonly handlers: Readonly<Record<string, (event: Event) => void>>;
|
|
29
|
+
};
|
|
30
|
+
/** The element surface the walker needs - structural, so tests can drive it without a real DOM. */
|
|
31
|
+
export interface BindableElement {
|
|
32
|
+
getAttribute(name: string): string | null;
|
|
33
|
+
setAttribute(name: string, value: string): void;
|
|
34
|
+
removeAttribute(name: string): void;
|
|
35
|
+
textContent: string | null;
|
|
36
|
+
hidden: boolean;
|
|
37
|
+
value?: string;
|
|
38
|
+
readonly classList: {
|
|
39
|
+
toggle(name: string, force?: boolean): unknown;
|
|
40
|
+
};
|
|
41
|
+
addEventListener(type: string, listener: (event: Event) => void): void;
|
|
42
|
+
removeEventListener(type: string, listener: (event: Event) => void): void;
|
|
43
|
+
}
|
|
44
|
+
export interface BindableRoot {
|
|
45
|
+
querySelectorAll(selector: string): Iterable<BindableElement>;
|
|
46
|
+
}
|
|
47
|
+
/** Walk `root` and attach every `data-bind-*` binding against `scope`. Each binding's disposer
|
|
48
|
+
* (reactive effect or event listener) goes onto `stops` as it attaches, so a binding that throws
|
|
49
|
+
* midway leaves the earlier ones disposable; `stops` is returned. */
|
|
50
|
+
export declare function bindScope(root: BindableRoot, scope: IslandScope, stops?: Array<() => void>): Array<() => void>;
|
|
51
|
+
//# sourceMappingURL=island-bindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-bindings.d.ts","sourceRoot":"","sources":["../../src/internal/island-bindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAS,MAAM,qBAAqB,CAAA;AAExD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAA;CACpE,CAAA;AAuCD,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACzC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,SAAS,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;KAAE,CAAA;IACtE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAA;IACtE,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAA;CAC1E;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAA;CAC9D;AAED;;qEAEqE;AACrE,wBAAgB,SAAS,CACvB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE,KAAK,CAAC,MAAM,IAAI,CAAM,GAC5B,KAAK,CAAC,MAAM,IAAI,CAAC,CAiGnB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declarative binding walker - attaches signal-driven behavior to SERVER-RENDERED markup.
|
|
3
|
+
* No VDOM, no hydration re-render: the HTML the server sent (e.g. via `@nifrajs/web-vanilla`) is
|
|
4
|
+
* already the initial state; bindings update it surgically when signals change. `bindIsland` runs it.
|
|
5
|
+
*
|
|
6
|
+
* The attribute set is CLOSED and documented - six bindings, no expression language. Values are
|
|
7
|
+
* signal/handler NAMES looked up in the island's scope, never evaluated code, so markup can't
|
|
8
|
+
* inject behavior:
|
|
9
|
+
*
|
|
10
|
+
* data-bind-text="count" textContent ← String(signal())
|
|
11
|
+
* data-bind-show="isOpen" hidden ← !signal()
|
|
12
|
+
* data-bind-class="active:isOpen,b:sigB" classList.toggle per pair
|
|
13
|
+
* data-bind-attr="aria-expanded:isOpen" setAttribute / removeAttribute (false/null remove);
|
|
14
|
+
* never an `on*` handler or `srcdoc`, and a URL attribute
|
|
15
|
+
* takes only an http(s)/mailto/tel or relative URL
|
|
16
|
+
* data-bind-value="query" two-way <input>/<select>/<textarea> (input and change)
|
|
17
|
+
* data-bind-on="click:inc,submit:save" addEventListener per pair
|
|
18
|
+
*
|
|
19
|
+
* Nothing inside a `data-island-ignore` element binds or mounts: render user HTML there, so its
|
|
20
|
+
* markup cannot reach the island's handlers or signals.
|
|
21
|
+
*
|
|
22
|
+
* A binding belongs to its nearest island: an island never binds inside a nested island's host. The
|
|
23
|
+
* nested host element itself is still the outer island's markup, so the outer island may bind it.
|
|
24
|
+
*/
|
|
25
|
+
import { watch } from "./island-signals.js";
|
|
26
|
+
const warned = new Set();
|
|
27
|
+
/** Unknown names warn once (loud in dev, resilient in prod - progressive enhancement must not
|
|
28
|
+
* throw over a typo'd attribute) and the binding is skipped. */
|
|
29
|
+
function warnOnce(kind, name) {
|
|
30
|
+
const key = `${kind}:${name}`;
|
|
31
|
+
if (warned.has(key))
|
|
32
|
+
return;
|
|
33
|
+
warned.add(key);
|
|
34
|
+
console.warn(`[nifra/islands] unknown ${kind} ${JSON.stringify(name)} - binding skipped`);
|
|
35
|
+
}
|
|
36
|
+
// Own keys only: a name such as `constructor` must not resolve to what a plain object inherits.
|
|
37
|
+
function named(kind, record, name) {
|
|
38
|
+
if (Object.hasOwn(record, name))
|
|
39
|
+
return record[name];
|
|
40
|
+
warnOnce(kind, name);
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Parse a `"key:name,key2:name2"` pair list (whitespace-tolerant). Malformed entries skip. */
|
|
44
|
+
function pairs(spec) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const part of spec.split(",")) {
|
|
47
|
+
const sep = part.indexOf(":");
|
|
48
|
+
if (sep <= 0)
|
|
49
|
+
continue;
|
|
50
|
+
const key = part.slice(0, sep).trim();
|
|
51
|
+
const name = part.slice(sep + 1).trim();
|
|
52
|
+
if (key && name)
|
|
53
|
+
out.push([key, name]);
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
// A bound value is data (often from island state the markup carries), so an attribute that would run
|
|
58
|
+
// it as code, or navigate to it as a script URL, is refused.
|
|
59
|
+
const CODE_ATTRIBUTE = /^(?:on|srcdoc$)/i;
|
|
60
|
+
const URL_ATTRIBUTE = /^(?:href|src|action|formaction|xlink:href|poster|data|background|cite|ping)$/i;
|
|
61
|
+
const SAFE_URL = /^(?:(?:https?|mailto|tel):|[^:/?#]*(?:[/?#]|$))/i;
|
|
62
|
+
/** Walk `root` and attach every `data-bind-*` binding against `scope`. Each binding's disposer
|
|
63
|
+
* (reactive effect or event listener) goes onto `stops` as it attaches, so a binding that throws
|
|
64
|
+
* midway leaves the earlier ones disposable; `stops` is returned. */
|
|
65
|
+
export function bindScope(root, scope, stops = []) {
|
|
66
|
+
// Each element carrying `data-bind-<kind>` outside any ignored subtree and any nested island, with
|
|
67
|
+
// that attribute's value.
|
|
68
|
+
const each = (kind) => {
|
|
69
|
+
const attribute = `data-bind-${kind}`;
|
|
70
|
+
return [
|
|
71
|
+
...root.querySelectorAll(`[${attribute}]:not([data-island-ignore],[data-island-ignore] *,:scope [data-island] *)`),
|
|
72
|
+
].map((el) => [el, el.getAttribute(attribute) ?? ""]);
|
|
73
|
+
};
|
|
74
|
+
for (const [el, name] of each("text")) {
|
|
75
|
+
const s = named("signal", scope.signals, name);
|
|
76
|
+
if (s) {
|
|
77
|
+
stops.push(watch(s, (v) => {
|
|
78
|
+
el.textContent = String(v);
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const [el, name] of each("show")) {
|
|
83
|
+
const s = named("signal", scope.signals, name);
|
|
84
|
+
if (s) {
|
|
85
|
+
stops.push(watch(s, (v) => {
|
|
86
|
+
el.hidden = !v;
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [el, spec] of each("class")) {
|
|
91
|
+
for (const [className, name] of pairs(spec)) {
|
|
92
|
+
const s = named("signal", scope.signals, name);
|
|
93
|
+
if (s) {
|
|
94
|
+
stops.push(watch(s, (v) => {
|
|
95
|
+
el.classList.toggle(className, !!v);
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const [el, spec] of each("attr")) {
|
|
101
|
+
for (const [attr, name] of pairs(spec)) {
|
|
102
|
+
if (CODE_ATTRIBUTE.test(attr)) {
|
|
103
|
+
warnOnce("attribute", attr);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const s = named("signal", scope.signals, name);
|
|
107
|
+
if (s) {
|
|
108
|
+
const isUrl = URL_ATTRIBUTE.test(attr);
|
|
109
|
+
stops.push(watch(s, (v) => {
|
|
110
|
+
if (v === false || v == null || (isUrl && !SAFE_URL.test(String(v).trim())))
|
|
111
|
+
el.removeAttribute(attr);
|
|
112
|
+
else
|
|
113
|
+
el.setAttribute(attr, String(v));
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (const [el, name] of each("value")) {
|
|
119
|
+
const s = named("signal", scope.signals, name);
|
|
120
|
+
if (s) {
|
|
121
|
+
stops.push(watch(s, (v) => {
|
|
122
|
+
const next = String(v);
|
|
123
|
+
// Skip same-value writes: resetting an input's value mid-typing moves the caret.
|
|
124
|
+
if (el.value !== next)
|
|
125
|
+
el.value = next;
|
|
126
|
+
}));
|
|
127
|
+
const input = () => s.set(el.value ?? "");
|
|
128
|
+
// A <select> commits on `change`, and browsers disagree on whether `input` comes first. The
|
|
129
|
+
// second event of a pair writes the same value, which the signal skips.
|
|
130
|
+
for (const type of ["input", "change"]) {
|
|
131
|
+
el.addEventListener(type, input);
|
|
132
|
+
stops.push(() => el.removeEventListener(type, input));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const [el, spec] of each("on")) {
|
|
137
|
+
for (const [event, name] of pairs(spec)) {
|
|
138
|
+
const handler = named("handler", scope.handlers, name);
|
|
139
|
+
if (handler === undefined)
|
|
140
|
+
continue;
|
|
141
|
+
el.addEventListener(event, handler);
|
|
142
|
+
stops.push(() => el.removeEventListener(event, handler));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return stops;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=island-bindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-bindings.js","sourceRoot":"","sources":["../../src/internal/island-bindings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The node surface `bindList` uses; an `Element` has it. */
|
|
2
|
+
export interface ListNode {
|
|
3
|
+
remove(): void;
|
|
4
|
+
}
|
|
5
|
+
/** The container surface `bindList` uses; an `Element` has it. */
|
|
6
|
+
export interface ListContainer<E extends ListNode> {
|
|
7
|
+
replaceChildren(...nodes: E[]): void;
|
|
8
|
+
insertBefore(node: E, before: E | null): unknown;
|
|
9
|
+
}
|
|
10
|
+
/** How `bindList` turns items into keyed DOM. */
|
|
11
|
+
export interface BindListOptions<T, E extends ListNode = HTMLElement> {
|
|
12
|
+
/** Stable and unique per item - never the array index, or a removal reuses the wrong node. */
|
|
13
|
+
key(item: T): string | number;
|
|
14
|
+
create(item: T): E;
|
|
15
|
+
/** Brings a node in line with its item: runs after `create` and on every later change. */
|
|
16
|
+
update?(el: E, item: T): void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Render a list signal (or any getter) into `container` with keyed reconciliation. A surviving item
|
|
20
|
+
* keeps its node, so focus, selection and input state survive a reorder. A render with no earlier
|
|
21
|
+
* nodes replaces the container's children; later renders move only the nodes outside the longest
|
|
22
|
+
* run already in order. `key`, `create` and `update` run untracked: a signal they read does not
|
|
23
|
+
* re-render the list. Returns the disposer; inside an island the binding also stops on unmount.
|
|
24
|
+
*/
|
|
25
|
+
export declare function bindList<T, E extends ListNode = HTMLElement>(source: () => readonly T[], container: ListContainer<NoInfer<E>>, options: BindListOptions<T, E>): () => void;
|
|
26
|
+
//# sourceMappingURL=island-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-list.d.ts","sourceRoot":"","sources":["../../src/internal/island-list.ts"],"names":[],"mappings":"AAEA,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,MAAM,IAAI,IAAI,CAAA;CACf;AAED,kEAAkE;AAClE,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ;IAC/C,eAAe,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAA;IACpC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,OAAO,CAAA;CACjD;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,GAAG,WAAW;IAClE,8FAA8F;IAC9F,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,CAAA;IAC7B,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;IAClB,0FAA0F;IAC1F,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,GAAG,WAAW,EAC1D,MAAM,EAAE,MAAM,SAAS,CAAC,EAAE,EAE1B,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EACpC,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,MAAM,IAAI,CAkCZ"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { effect, untrack } from "./island-signals.js";
|
|
2
|
+
/**
|
|
3
|
+
* Render a list signal (or any getter) into `container` with keyed reconciliation. A surviving item
|
|
4
|
+
* keeps its node, so focus, selection and input state survive a reorder. A render with no earlier
|
|
5
|
+
* nodes replaces the container's children; later renders move only the nodes outside the longest
|
|
6
|
+
* run already in order. `key`, `create` and `update` run untracked: a signal they read does not
|
|
7
|
+
* re-render the list. Returns the disposer; inside an island the binding also stops on unmount.
|
|
8
|
+
*/
|
|
9
|
+
export function bindList(source,
|
|
10
|
+
// A DOM container's generic methods would drive E to `ListNode`; the row type comes from `create`.
|
|
11
|
+
container, options) {
|
|
12
|
+
let nodes = new Map();
|
|
13
|
+
// Each node's position in the last render; empty until a render leaves nodes to keep.
|
|
14
|
+
let at = new Map();
|
|
15
|
+
return effect(() => {
|
|
16
|
+
const items = source();
|
|
17
|
+
untrack(() => {
|
|
18
|
+
const next = new Map();
|
|
19
|
+
for (const item of items) {
|
|
20
|
+
const key = options.key(item);
|
|
21
|
+
if (next.has(key))
|
|
22
|
+
console.warn("[nifra/islands] bindList: duplicate key skipped", key);
|
|
23
|
+
else {
|
|
24
|
+
const el = nodes.get(key) ?? options.create(item);
|
|
25
|
+
options.update?.(el, item);
|
|
26
|
+
next.set(key, el);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const els = [...next.values()];
|
|
30
|
+
if (at.size === 0)
|
|
31
|
+
container.replaceChildren(...els);
|
|
32
|
+
else {
|
|
33
|
+
for (const [key, el] of nodes)
|
|
34
|
+
if (!next.has(key))
|
|
35
|
+
el.remove();
|
|
36
|
+
const stays = inOrder(els.map((el) => at.get(el) ?? -1));
|
|
37
|
+
let anchor = null;
|
|
38
|
+
for (let i = els.length - 1; i >= 0; i--) {
|
|
39
|
+
const el = els[i];
|
|
40
|
+
if (el === undefined)
|
|
41
|
+
continue;
|
|
42
|
+
if (!stays.has(i))
|
|
43
|
+
container.insertBefore(el, anchor);
|
|
44
|
+
anchor = el;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
at = new Map(els.map((el, i) => [el, i]));
|
|
48
|
+
nodes = next;
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// The indexes of `old` (each node's previous position, -1 for a new node) on a longest increasing
|
|
53
|
+
// run: those nodes already sit in order, and every other node is moved.
|
|
54
|
+
function inOrder(old) {
|
|
55
|
+
// tails[n] is the index ending the best run of length n + 1; back links each run.
|
|
56
|
+
const tails = [];
|
|
57
|
+
const back = [];
|
|
58
|
+
old.forEach((o, i) => {
|
|
59
|
+
if (o < 0)
|
|
60
|
+
return;
|
|
61
|
+
let lo = 0;
|
|
62
|
+
let hi = tails.length;
|
|
63
|
+
while (lo < hi) {
|
|
64
|
+
const mid = (lo + hi) >> 1;
|
|
65
|
+
if ((old[tails[mid] ?? 0] ?? 0) < o)
|
|
66
|
+
lo = mid + 1;
|
|
67
|
+
else
|
|
68
|
+
hi = mid;
|
|
69
|
+
}
|
|
70
|
+
back[i] = tails[lo - 1] ?? -1;
|
|
71
|
+
tails[lo] = i;
|
|
72
|
+
});
|
|
73
|
+
const stays = new Set();
|
|
74
|
+
for (let i = tails.at(-1) ?? -1; i >= 0; i = back[i] ?? -1)
|
|
75
|
+
stays.add(i);
|
|
76
|
+
return stays;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=island-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-list.js","sourceRoot":"","sources":["../../src/internal/island-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { IslandCleanup, IslandEnhancer } from "../islands.js";
|
|
2
|
+
/** Own one host so removing a subtree can stop its islands without disturbing retained siblings. */
|
|
3
|
+
export declare function mountIsland(el: HTMLElement, enhancers: Readonly<Record<string, IslandEnhancer<never>>>): IslandCleanup | undefined;
|
|
4
|
+
//# sourceMappingURL=island-mount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-mount.d.ts","sourceRoot":"","sources":["../../src/internal/island-mount.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAalE,oGAAoG;AACpG,wBAAgB,WAAW,CACzB,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,GACzD,aAAa,GAAG,SAAS,CA6C3B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { MAX_MEDIA_QUERY_LENGTH, scheduleTrigger, } from "@nifrajs/island-trigger";
|
|
2
|
+
import { owned } from "./island-owner.js";
|
|
3
|
+
function readProps(el) {
|
|
4
|
+
const raw = el.dataset.islandProps;
|
|
5
|
+
if (raw === undefined || raw === "")
|
|
6
|
+
return undefined;
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(raw);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Own one host so removing a subtree can stop its islands without disturbing retained siblings. */
|
|
15
|
+
export function mountIsland(el, enhancers) {
|
|
16
|
+
const id = el.dataset.island;
|
|
17
|
+
if (id === undefined || el.dataset.islandMounted !== undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
const enhancer = Object.hasOwn(enhancers, id) ? enhancers[id] : undefined;
|
|
20
|
+
if (enhancer === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
const strategyAttr = el.dataset.islandStrategy;
|
|
23
|
+
const media = el.dataset.islandMedia;
|
|
24
|
+
const strategy = strategyAttr === "idle" || strategyAttr === "visible" || strategyAttr === "load"
|
|
25
|
+
? strategyAttr
|
|
26
|
+
: strategyAttr === "media" &&
|
|
27
|
+
media !== undefined &&
|
|
28
|
+
media.length > 0 &&
|
|
29
|
+
media.length <= MAX_MEDIA_QUERY_LENGTH
|
|
30
|
+
? { media }
|
|
31
|
+
: strategyAttr === undefined
|
|
32
|
+
? "load"
|
|
33
|
+
: undefined;
|
|
34
|
+
// Invalid markers must stay inert, including untrusted oversized media queries.
|
|
35
|
+
if (strategy === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
const disposers = [];
|
|
38
|
+
el.dataset.islandMounted = "";
|
|
39
|
+
disposers.push(() => {
|
|
40
|
+
delete el.dataset.islandMounted;
|
|
41
|
+
});
|
|
42
|
+
const props = readProps(el);
|
|
43
|
+
const run = () => {
|
|
44
|
+
try {
|
|
45
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: enhancer props are the authored SSR contract, as in defineIsland
|
|
46
|
+
const cleanup = owned(disposers, () => enhancer(el, props));
|
|
47
|
+
if (typeof cleanup === "function")
|
|
48
|
+
disposers.push(cleanup);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
console.error(`[nifra/islands] enhancer "${id}" failed:`, err);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
disposers.push(scheduleTrigger(strategy, run, { target: el }));
|
|
55
|
+
return () => {
|
|
56
|
+
for (const dispose of disposers.splice(0)) {
|
|
57
|
+
try {
|
|
58
|
+
dispose();
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Best-effort teardown: one failing cleanup must not block the rest.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=island-mount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-mount.js","sourceRoot":"","sources":["../../src/internal/island-mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EACtB,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAEzC,SAAS,SAAS,CAAC,EAAe;IAChC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAA;IAClC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IACrD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CACzB,EAAe,EACf,SAA0D;IAE1D,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAA;IAC5B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACzE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC5C,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,CAAA;IAC9C,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAA;IACpC,MAAM,QAAQ,GACZ,YAAY,KAAK,MAAM,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,MAAM;QAC9E,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,YAAY,KAAK,OAAO;YACtB,KAAK,KAAK,SAAS;YACnB,KAAK,CAAC,MAAM,GAAG,CAAC;YAChB,KAAK,CAAC,MAAM,IAAI,sBAAsB;YACxC,CAAC,CAAC,EAAE,KAAK,EAAE;YACX,CAAC,CAAC,YAAY,KAAK,SAAS;gBAC1B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,SAAS,CAAA;IACnB,gFAAgF;IAChF,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC5C,MAAM,SAAS,GAAsB,EAAE,CAAA;IACvC,EAAE,CAAC,OAAO,CAAC,aAAa,GAAG,EAAE,CAAA;IAC7B,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE;QAClB,OAAO,EAAE,CAAC,OAAO,CAAC,aAAa,CAAA;IACjC,CAAC,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;IAC3B,MAAM,GAAG,GAAG,GAAS,EAAE;QACrB,IAAI,CAAC;YACH,kIAAkI;YAClI,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAc,CAAC,CAAC,CAAA;YACpE,IAAI,OAAO,OAAO,KAAK,UAAU;gBAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,WAAW,EAAE,GAAG,CAAC,CAAA;QAChE,CAAC;IACH,CAAC,CAAA;IACD,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9D,OAAO,GAAG,EAAE;QACV,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACH,OAAO,EAAE,CAAA;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;YACvE,CAAC;QACH,CAAC;IACH,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Run `fn` with every disposer it registers pushed onto `kids`. */
|
|
2
|
+
export declare function owned<T>(kids: Array<() => void>, fn: () => T): T;
|
|
3
|
+
/** Register `stop` with the running island, if any. Outside an enhancer it stays the caller's. */
|
|
4
|
+
export declare function adopt(stop: () => void): void;
|
|
5
|
+
//# sourceMappingURL=island-owner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-owner.d.ts","sourceRoot":"","sources":["../../src/internal/island-owner.ts"],"names":[],"mappings":"AAKA,oEAAoE;AACpE,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQhE;AAED,kGAAkG;AAClG,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAE5C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The disposer list of the island whose enhancer is running, so every effect, computed, list binding
|
|
2
|
+
// and resource it creates stops when the island unmounts. A separate module so an imperative-only
|
|
3
|
+
// island bundle carries no signal code.
|
|
4
|
+
let owner;
|
|
5
|
+
/** Run `fn` with every disposer it registers pushed onto `kids`. */
|
|
6
|
+
export function owned(kids, fn) {
|
|
7
|
+
const prev = owner;
|
|
8
|
+
owner = kids;
|
|
9
|
+
try {
|
|
10
|
+
return fn();
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
owner = prev;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Register `stop` with the running island, if any. Outside an enhancer it stays the caller's. */
|
|
17
|
+
export function adopt(stop) {
|
|
18
|
+
owner?.push(stop);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=island-owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"island-owner.js","sourceRoot":"","sources":["../../src/internal/island-owner.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,kGAAkG;AAClG,wCAAwC;AACxC,IAAI,KAAoC,CAAA;AAExC,oEAAoE;AACpE,MAAM,UAAU,KAAK,CAAI,IAAuB,EAAE,EAAW;IAC3D,MAAM,IAAI,GAAG,KAAK,CAAA;IAClB,KAAK,GAAG,IAAI,CAAA;IACZ,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;YAAS,CAAC;QACT,KAAK,GAAG,IAAI,CAAA;IACd,CAAC;AACH,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,KAAK,CAAC,IAAgB;IACpC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACnB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** An async value's state. `status` narrows `value` and `error`, so no branch can be skipped. */
|
|
2
|
+
export type ResourceState<T> = {
|
|
3
|
+
readonly status: "pending";
|
|
4
|
+
readonly value: undefined;
|
|
5
|
+
readonly error: undefined;
|
|
6
|
+
} | {
|
|
7
|
+
readonly status: "ready";
|
|
8
|
+
readonly value: T;
|
|
9
|
+
readonly error: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
readonly status: "error";
|
|
12
|
+
readonly value: undefined;
|
|
13
|
+
readonly error: unknown;
|
|
14
|
+
};
|
|
15
|
+
/** Call it to read the current state (tracking, like a signal). */
|
|
16
|
+
export type Resource<T> = {
|
|
17
|
+
(): ResourceState<T>;
|
|
18
|
+
/** Fetch the current key again; once disposed, nothing. */
|
|
19
|
+
refetch(): void;
|
|
20
|
+
/** Stop refetching and abort the request in flight; its result is dropped. */
|
|
21
|
+
dispose(): void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* An async value keyed by `source`. `source` runs tracked, so a write to any signal it reads starts a
|
|
25
|
+
* new fetch; `fetcher` runs untracked with that key, so nothing it reads (before or after an `await`)
|
|
26
|
+
* is a dependency. A newer fetch aborts the older one and only the newest result lands. Inside an
|
|
27
|
+
* island, unmounting disposes it: the request in flight is aborted and its late result dropped.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resource<K, T>(source: () => K, fetcher: (key: K, abort: AbortSignal) => Promise<T>): Resource<T>;
|
|
30
|
+
//# sourceMappingURL=island-resource.d.ts.map
|