@wular/pnext 0.0.4 → 0.0.7
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/README.md +22 -16
- package/bin/pnext +6 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +87 -22
- package/reference/config.md +40 -93
- package/reference/css.md +42 -33
- package/reference/dev.md +26 -33
- package/reference/env.md +18 -20
- package/reference/getting-started.md +132 -0
- package/reference/metadata.md +31 -46
- package/reference/navigation.md +65 -105
- package/reference/performance.md +21 -142
- package/reference/rendering.md +78 -75
- package/reference/routing.md +97 -107
- package/reference/typegen.md +27 -29
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +121 -114
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +52 -53
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +72 -64
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +94 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +802 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +32 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +2022 -1995
- package/src/{api → client}/router/types.ts +98 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +86 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2087 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +87 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +954 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +428 -406
- package/src/styles.d.ts +9 -0
- package/src/types.ts +324 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/reference/overview.md +0 -35
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -14,26 +14,26 @@
|
|
|
14
14
|
// client unbuffered. JSON cannot carry a stream, so the server responds with the raw stream body
|
|
15
15
|
// under a marker header/content type and the client returns a live ReadableStream from the call.
|
|
16
16
|
//
|
|
17
|
-
// These helpers are pure and node-safe. The client counterparts live inline in actions/
|
|
17
|
+
// These helpers are pure and node-safe. The client counterparts live inline in actions/client.ts.
|
|
18
18
|
|
|
19
19
|
/** Marker key naming a temporary-reference id in the args / return wire. */
|
|
20
|
-
export const TEMP_REF_MARKER = '$$pnext_temp_ref'
|
|
21
|
-
export const ACTION_ELEMENT_MARKER = '$$pnext_element'
|
|
20
|
+
export const TEMP_REF_MARKER = '$$pnext_temp_ref'
|
|
21
|
+
export const ACTION_ELEMENT_MARKER = '$$pnext_element'
|
|
22
22
|
/**
|
|
23
23
|
* Marker carrying the SERVER-RENDERED HTML of a React element tree an action returned (host elements /
|
|
24
24
|
* async server components - NOT a client-reference element, which uses ACTION_ELEMENT_MARKER). The
|
|
25
25
|
* client revives it into a renderable node for useActionState.
|
|
26
26
|
*/
|
|
27
|
-
export const ACTION_ELEMENT_HTML_MARKER = '$$pnext_element_html'
|
|
27
|
+
export const ACTION_ELEMENT_HTML_MARKER = '$$pnext_element_html'
|
|
28
28
|
|
|
29
|
-
const clientReferenceSymbol = Symbol.for('pnext.clientReference')
|
|
29
|
+
const clientReferenceSymbol = Symbol.for('pnext.clientReference')
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Response content-type/marker for a streamed action return. The client detects
|
|
33
33
|
* this and returns the response body as a ReadableStream from the call instead
|
|
34
34
|
* of parsing JSON.
|
|
35
35
|
*/
|
|
36
|
-
export const ACTION_STREAM_CONTENT_TYPE = 'x-component/pnext-stream'
|
|
36
|
+
export const ACTION_STREAM_CONTENT_TYPE = 'x-component/pnext-stream'
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Per-request association of a decoded arg object -> the temp-ref id the client
|
|
@@ -42,29 +42,29 @@ export const ACTION_STREAM_CONTENT_TYPE = 'x-component/pnext-stream';
|
|
|
42
42
|
*/
|
|
43
43
|
export interface TempRefScope {
|
|
44
44
|
/** Record that a decoded arg object carries the client's temp-ref id. */
|
|
45
|
-
track(object: object, id: string): void
|
|
45
|
+
track(object: object, id: string): void
|
|
46
46
|
/** The temp-ref id the client sent for this object, if any. */
|
|
47
|
-
idFor(value: unknown): string | undefined
|
|
47
|
+
idFor(value: unknown): string | undefined
|
|
48
48
|
/** True once any temp-ref arg has been seen (skip serialization walk otherwise). */
|
|
49
|
-
readonly active: boolean
|
|
49
|
+
readonly active: boolean
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export function createTempRefScope(): TempRefScope {
|
|
53
|
-
const ids = new WeakMap<object, string>()
|
|
54
|
-
let active = false
|
|
53
|
+
const ids = new WeakMap<object, string>()
|
|
54
|
+
let active = false
|
|
55
55
|
return {
|
|
56
56
|
track(object, id) {
|
|
57
|
-
ids.set(object, id)
|
|
58
|
-
active = true
|
|
57
|
+
ids.set(object, id)
|
|
58
|
+
active = true
|
|
59
59
|
},
|
|
60
60
|
idFor(value) {
|
|
61
|
-
if (value === null || typeof value !== 'object') return undefined
|
|
62
|
-
return ids.get(value)
|
|
61
|
+
if (value === null || typeof value !== 'object') return undefined
|
|
62
|
+
return ids.get(value)
|
|
63
63
|
},
|
|
64
64
|
get active() {
|
|
65
|
-
return active
|
|
65
|
+
return active
|
|
66
66
|
},
|
|
67
|
-
}
|
|
67
|
+
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -73,24 +73,28 @@ export function createTempRefScope(): TempRefScope {
|
|
|
73
73
|
* resulting object is tracked under `id`, so the action sees a clean object and
|
|
74
74
|
* a later return of that same object serializes back to the marker.
|
|
75
75
|
*/
|
|
76
|
-
export function extractTempRefs(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
seen
|
|
76
|
+
export function extractTempRefs(
|
|
77
|
+
value: unknown,
|
|
78
|
+
scope: TempRefScope,
|
|
79
|
+
seen = new Set<unknown>(),
|
|
80
|
+
): unknown {
|
|
81
|
+
if (value === null || typeof value !== 'object') return value
|
|
82
|
+
if (seen.has(value)) return value
|
|
83
|
+
seen.add(value)
|
|
80
84
|
if (Array.isArray(value)) {
|
|
81
|
-
for (let i = 0; i < value.length; i++) value[i] = extractTempRefs(value[i], scope, seen)
|
|
82
|
-
return value
|
|
85
|
+
for (let i = 0; i < value.length; i++) value[i] = extractTempRefs(value[i], scope, seen)
|
|
86
|
+
return value
|
|
83
87
|
}
|
|
84
|
-
const record = value as Record<string, unknown
|
|
85
|
-
const id = record[TEMP_REF_MARKER]
|
|
88
|
+
const record = value as Record<string, unknown>
|
|
89
|
+
const id = record[TEMP_REF_MARKER]
|
|
86
90
|
if (typeof id === 'string') {
|
|
87
|
-
delete record[TEMP_REF_MARKER]
|
|
88
|
-
scope.track(record, id)
|
|
91
|
+
delete record[TEMP_REF_MARKER]
|
|
92
|
+
scope.track(record, id)
|
|
89
93
|
}
|
|
90
94
|
for (const key of Object.keys(record)) {
|
|
91
|
-
record[key] = extractTempRefs(record[key], scope, seen)
|
|
95
|
+
record[key] = extractTempRefs(record[key], scope, seen)
|
|
92
96
|
}
|
|
93
|
-
return record
|
|
97
|
+
return record
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
/**
|
|
@@ -107,12 +111,12 @@ export async function serializeReturnWithTempRefs(
|
|
|
107
111
|
renderElement?: (element: unknown) => Promise<string>,
|
|
108
112
|
): Promise<unknown> {
|
|
109
113
|
const walk = async (input: unknown, seen: Set<unknown>): Promise<unknown> => {
|
|
110
|
-
if (input === null || typeof input !== 'object') return input
|
|
111
|
-
const marker = scope.active ? scope.idFor(input) : undefined
|
|
112
|
-
if (marker !== undefined) return { [TEMP_REF_MARKER]: marker }
|
|
113
|
-
if (seen.has(input)) return input
|
|
114
|
-
seen.add(input)
|
|
115
|
-
const element = clientReferenceElement(input)
|
|
114
|
+
if (input === null || typeof input !== 'object') return input
|
|
115
|
+
const marker = scope.active ? scope.idFor(input) : undefined
|
|
116
|
+
if (marker !== undefined) return { [TEMP_REF_MARKER]: marker }
|
|
117
|
+
if (seen.has(input)) return input
|
|
118
|
+
seen.add(input)
|
|
119
|
+
const element = clientReferenceElement(input)
|
|
116
120
|
if (element) {
|
|
117
121
|
return {
|
|
118
122
|
[ACTION_ELEMENT_MARKER]: {
|
|
@@ -120,21 +124,21 @@ export async function serializeReturnWithTempRefs(
|
|
|
120
124
|
props: await walk(element.props, seen),
|
|
121
125
|
...(element.key !== undefined ? { key: element.key } : {}),
|
|
122
126
|
},
|
|
123
|
-
}
|
|
127
|
+
}
|
|
124
128
|
}
|
|
125
129
|
if (renderElement && isServerElement(input)) {
|
|
126
|
-
return { [ACTION_ELEMENT_HTML_MARKER]: await renderElement(input) }
|
|
130
|
+
return { [ACTION_ELEMENT_HTML_MARKER]: await renderElement(input) }
|
|
127
131
|
}
|
|
128
|
-
if (Array.isArray(input)) return Promise.all(input.map(item => walk(item, seen)))
|
|
129
|
-
const proto = Object.getPrototypeOf(input) as object | null
|
|
130
|
-
if (proto !== Object.prototype && proto !== null) return input
|
|
131
|
-
const out: Record<string, unknown> = {}
|
|
132
|
+
if (Array.isArray(input)) return Promise.all(input.map(item => walk(item, seen)))
|
|
133
|
+
const proto = Object.getPrototypeOf(input) as object | null
|
|
134
|
+
if (proto !== Object.prototype && proto !== null) return input
|
|
135
|
+
const out: Record<string, unknown> = {}
|
|
132
136
|
for (const [key, item] of Object.entries(input as Record<string, unknown>)) {
|
|
133
|
-
out[key] = await walk(item, seen)
|
|
137
|
+
out[key] = await walk(item, seen)
|
|
134
138
|
}
|
|
135
|
-
return out
|
|
136
|
-
}
|
|
137
|
-
return walk(value, new Set())
|
|
139
|
+
return out
|
|
140
|
+
}
|
|
141
|
+
return walk(value, new Set())
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
/**
|
|
@@ -145,29 +149,28 @@ export async function serializeReturnWithTempRefs(
|
|
|
145
149
|
* element (it stays JSON-serialized).
|
|
146
150
|
*/
|
|
147
151
|
function isServerElement(value: object): boolean {
|
|
148
|
-
const vnode = value as { type?: unknown; props?: unknown; $$typeof?: unknown }
|
|
149
|
-
if (!('type' in vnode) || !('props' in vnode)) return false
|
|
150
|
-
if (vnode.$$typeof === Symbol.for('react.element')) return true
|
|
152
|
+
const vnode = value as { type?: unknown; props?: unknown; $$typeof?: unknown }
|
|
153
|
+
if (!('type' in vnode) || !('props' in vnode)) return false
|
|
154
|
+
if (vnode.$$typeof === Symbol.for('react.element')) return true
|
|
151
155
|
return (
|
|
152
156
|
Object.prototype.hasOwnProperty.call(value, 'constructor') &&
|
|
153
157
|
(value as { constructor?: unknown }).constructor === undefined
|
|
154
|
-
)
|
|
158
|
+
)
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
function clientReferenceElement(
|
|
158
162
|
value: object,
|
|
159
163
|
): { id: string; props: unknown; key?: string | number } | undefined {
|
|
160
|
-
const vnode = value as { type?: unknown; props?: unknown; key?: unknown }
|
|
161
|
-
if (typeof vnode.type !== 'function') return undefined
|
|
164
|
+
const vnode = value as { type?: unknown; props?: unknown; key?: unknown }
|
|
165
|
+
if (typeof vnode.type !== 'function') return undefined
|
|
162
166
|
const reference = (vnode.type as unknown as Record<symbol, unknown>)[clientReferenceSymbol] as
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return { id: reference.id, props: vnode.props ?? {}, ...(key !== undefined ? { key } : {}) };
|
|
167
|
+
{ id?: unknown } | undefined
|
|
168
|
+
if (typeof reference?.id !== 'string') return undefined
|
|
169
|
+
const key = typeof vnode.key === 'string' || typeof vnode.key === 'number' ? vnode.key : undefined
|
|
170
|
+
return { id: reference.id, props: vnode.props ?? {}, ...(key !== undefined ? { key } : {}) }
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
/** True for a value the streaming action path must send as a raw stream body. */
|
|
171
174
|
export function isReadableStreamReturn(value: unknown): value is ReadableStream {
|
|
172
|
-
return typeof ReadableStream !== 'undefined' && value instanceof ReadableStream
|
|
175
|
+
return typeof ReadableStream !== 'undefined' && value instanceof ReadableStream
|
|
173
176
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { inlineUseServerFunctions, moduleLevelUseServer } from './detect'
|
|
2
|
-
import { workspaceRelative } from './ids'
|
|
1
|
+
import { inlineUseServerFunctions, moduleLevelUseServer } from './detect'
|
|
2
|
+
import { workspaceRelative } from './ids'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Compile-time tagging for MODULE-SCOPE inline server actions: top-level functions whose body opens
|
|
@@ -12,30 +12,30 @@ import { workspaceRelative } from './ids';
|
|
|
12
12
|
* untouched - they register per render through the render-scoped instance registry.
|
|
13
13
|
*/
|
|
14
14
|
export function rewriteInlineActionTags(source: string, file: string, root?: string): string {
|
|
15
|
-
if (!source.includes('use server')) return source
|
|
16
|
-
if (moduleLevelUseServer(source)) return source
|
|
15
|
+
if (!source.includes('use server')) return source
|
|
16
|
+
if (moduleLevelUseServer(source)) return source
|
|
17
17
|
|
|
18
18
|
const topLevel = inlineUseServerFunctions(source).filter(
|
|
19
19
|
action => action.start === 0 || source[action.start - 1] === '\n',
|
|
20
|
-
)
|
|
21
|
-
if (topLevel.length === 0) return source
|
|
20
|
+
)
|
|
21
|
+
if (topLevel.length === 0) return source
|
|
22
22
|
|
|
23
|
-
const key = workspaceRelative(file, root)
|
|
24
|
-
const insertions: { at: number; text: string }[] = []
|
|
25
|
-
const fallbacks: string[] = []
|
|
23
|
+
const key = workspaceRelative(file, root)
|
|
24
|
+
const insertions: { at: number; text: string }[] = []
|
|
25
|
+
const fallbacks: string[] = []
|
|
26
26
|
for (const action of topLevel) {
|
|
27
|
-
const id = inlineActionId(key, action.name)
|
|
28
|
-
const tag = `\n;typeof ${action.name} === 'function' && globalThis.__pnextTagInlineAction && globalThis.__pnextTagInlineAction(${action.name}, ${JSON.stringify(id)})
|
|
29
|
-
const at = declarationEnd(source, action.directiveEnd)
|
|
30
|
-
if (at === undefined) fallbacks.push(tag)
|
|
31
|
-
else insertions.push({ at, text: tag })
|
|
27
|
+
const id = inlineActionId(key, action.name)
|
|
28
|
+
const tag = `\n;typeof ${action.name} === 'function' && globalThis.__pnextTagInlineAction && globalThis.__pnextTagInlineAction(${action.name}, ${JSON.stringify(id)});`
|
|
29
|
+
const at = declarationEnd(source, action.directiveEnd)
|
|
30
|
+
if (at === undefined) fallbacks.push(tag)
|
|
31
|
+
else insertions.push({ at, text: tag })
|
|
32
32
|
}
|
|
33
|
-
let out = source
|
|
33
|
+
let out = source
|
|
34
34
|
for (const { at, text } of insertions.sort((a, b) => b.at - a.at)) {
|
|
35
|
-
out = out.slice(0, at) + text + out.slice(at)
|
|
35
|
+
out = out.slice(0, at) + text + out.slice(at)
|
|
36
36
|
}
|
|
37
|
-
if (fallbacks.length > 0) out = `${out}\n${fallbacks.join('\n')}\n
|
|
38
|
-
return out
|
|
37
|
+
if (fallbacks.length > 0) out = `${out}\n${fallbacks.join('\n')}\n`
|
|
38
|
+
return out
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -50,28 +50,28 @@ export function rewriteInlineActionTags(source: string, file: string, root?: str
|
|
|
50
50
|
* expression position are wrapped, and a `'use server'` string right after an unrelated brace can match.
|
|
51
51
|
*/
|
|
52
52
|
export function rewriteAnonymousInlineActionMarks(source: string): string {
|
|
53
|
-
if (!source.includes('use server')) return source
|
|
54
|
-
if (moduleLevelUseServer(source)) return source
|
|
53
|
+
if (!source.includes('use server')) return source
|
|
54
|
+
if (moduleLevelUseServer(source)) return source
|
|
55
55
|
|
|
56
|
-
const wraps = anonymousInlineActionSpans(source)
|
|
57
|
-
if (wraps.length === 0) return source
|
|
56
|
+
const wraps = anonymousInlineActionSpans(source)
|
|
57
|
+
if (wraps.length === 0) return source
|
|
58
58
|
|
|
59
|
-
let out = source
|
|
59
|
+
let out = source
|
|
60
60
|
for (const { start, end } of wraps.sort((a, b) => b.start - a.start)) {
|
|
61
|
-
const fn = out.slice(start, end)
|
|
62
|
-
out = `${out.slice(0, start)}(globalThis.__pnextMarkInlineAction ? globalThis.__pnextMarkInlineAction(${fn}) : ${fn})${out.slice(end)}
|
|
61
|
+
const fn = out.slice(start, end)
|
|
62
|
+
out = `${out.slice(0, start)}(globalThis.__pnextMarkInlineAction ? globalThis.__pnextMarkInlineAction(${fn}) : ${fn})${out.slice(end)}`
|
|
63
63
|
}
|
|
64
|
-
return out
|
|
64
|
+
return out
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/** One anonymous inline action: the span of its whole function expression. */
|
|
68
68
|
export interface AnonymousActionSpan {
|
|
69
69
|
/** Offset of the first character of the function expression. */
|
|
70
|
-
start: number
|
|
70
|
+
start: number
|
|
71
71
|
/** Offset just past its closing `}`. */
|
|
72
|
-
end: number
|
|
72
|
+
end: number
|
|
73
73
|
/** Offset just past the `'use server'` directive that identified it. */
|
|
74
|
-
directiveEnd: number
|
|
74
|
+
directiveEnd: number
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/**
|
|
@@ -80,16 +80,16 @@ export interface AnonymousActionSpan {
|
|
|
80
80
|
* ones filter themselves.
|
|
81
81
|
*/
|
|
82
82
|
export function anonymousInlineActionSpans(source: string): AnonymousActionSpan[] {
|
|
83
|
-
const directive = /\{\s*(['"])use server\1\s*;?/g
|
|
84
|
-
const spans: AnonymousActionSpan[] = []
|
|
85
|
-
for (let match; (match = directive.exec(source));
|
|
86
|
-
const start = functionExpressionStart(source, match.index)
|
|
87
|
-
if (start === undefined) continue
|
|
88
|
-
const end = bodyEnd(source, match.index)
|
|
89
|
-
if (end === undefined) continue
|
|
90
|
-
spans.push({ start, end, directiveEnd: match.index + match[0].length })
|
|
83
|
+
const directive = /\{\s*(['"])use server\1\s*;?/g
|
|
84
|
+
const spans: AnonymousActionSpan[] = []
|
|
85
|
+
for (let match; (match = directive.exec(source));) {
|
|
86
|
+
const start = functionExpressionStart(source, match.index)
|
|
87
|
+
if (start === undefined) continue
|
|
88
|
+
const end = bodyEnd(source, match.index)
|
|
89
|
+
if (end === undefined) continue
|
|
90
|
+
spans.push({ start, end, directiveEnd: match.index + match[0].length })
|
|
91
91
|
}
|
|
92
|
-
return spans
|
|
92
|
+
return spans
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -98,39 +98,39 @@ export function anonymousInlineActionSpans(source: string): AnonymousActionSpan[
|
|
|
98
98
|
* *declaration*, an object method, or a plain block).
|
|
99
99
|
*/
|
|
100
100
|
function functionExpressionStart(source: string, open: number): number | undefined {
|
|
101
|
-
let i = skipBackWhitespace(source, open - 1)
|
|
101
|
+
let i = skipBackWhitespace(source, open - 1)
|
|
102
102
|
if (source[i] === '>' && source[i - 1] === '=') {
|
|
103
103
|
// arrow: `(...) =>` or `param =>`
|
|
104
|
-
i = skipBackWhitespace(source, i - 2)
|
|
105
|
-
const head = source[i] === ')' ? matchingOpenParen(source, i) : identifierStart(source, i)
|
|
106
|
-
if (head === undefined) return undefined
|
|
107
|
-
i = head
|
|
104
|
+
i = skipBackWhitespace(source, i - 2)
|
|
105
|
+
const head = source[i] === ')' ? matchingOpenParen(source, i) : identifierStart(source, i)
|
|
106
|
+
if (head === undefined) return undefined
|
|
107
|
+
i = head
|
|
108
108
|
} else if (source[i] === ')') {
|
|
109
109
|
// function expression: `function [name](...)`
|
|
110
|
-
const paren = matchingOpenParen(source, i)
|
|
111
|
-
if (paren === undefined) return undefined
|
|
112
|
-
let j = skipBackWhitespace(source, paren - 1)
|
|
113
|
-
const name = identifierStart(source, j)
|
|
114
|
-
if (name === undefined) return undefined
|
|
110
|
+
const paren = matchingOpenParen(source, i)
|
|
111
|
+
if (paren === undefined) return undefined
|
|
112
|
+
let j = skipBackWhitespace(source, paren - 1)
|
|
113
|
+
const name = identifierStart(source, j)
|
|
114
|
+
if (name === undefined) return undefined
|
|
115
115
|
if (source.slice(name, j + 1) !== 'function') {
|
|
116
|
-
j = skipBackWhitespace(source, name - 1)
|
|
117
|
-
const keyword = identifierStart(source, j)
|
|
118
|
-
if (keyword === undefined || source.slice(keyword, j + 1) !== 'function') return undefined
|
|
119
|
-
i = keyword
|
|
116
|
+
j = skipBackWhitespace(source, name - 1)
|
|
117
|
+
const keyword = identifierStart(source, j)
|
|
118
|
+
if (keyword === undefined || source.slice(keyword, j + 1) !== 'function') return undefined
|
|
119
|
+
i = keyword
|
|
120
120
|
} else {
|
|
121
|
-
i = name
|
|
121
|
+
i = name
|
|
122
122
|
}
|
|
123
123
|
} else {
|
|
124
|
-
return undefined
|
|
124
|
+
return undefined
|
|
125
125
|
}
|
|
126
|
-
const withAsync = precedingKeyword(source, i, 'async')
|
|
127
|
-
if (withAsync !== undefined) i = withAsync
|
|
126
|
+
const withAsync = precedingKeyword(source, i, 'async')
|
|
127
|
+
if (withAsync !== undefined) i = withAsync
|
|
128
128
|
// Only expression position: a `function`/`const` declaration statement or a
|
|
129
129
|
// bare block must not be wrapped.
|
|
130
|
-
const before = skipBackWhitespace(source, i - 1)
|
|
131
|
-
if (before < 0) return undefined
|
|
132
|
-
if (source[before] === '{') return isJsxExpressionContainer(source, before) ? i : undefined
|
|
133
|
-
return '(,:[=?&|'.includes(source[before] ?? '') ? i : undefined
|
|
130
|
+
const before = skipBackWhitespace(source, i - 1)
|
|
131
|
+
if (before < 0) return undefined
|
|
132
|
+
if (source[before] === '{') return isJsxExpressionContainer(source, before) ? i : undefined
|
|
133
|
+
return '(,:[=?&|'.includes(source[before] ?? '') ? i : undefined
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
@@ -140,143 +140,143 @@ function functionExpressionStart(source: string, open: number): number | undefin
|
|
|
140
140
|
* name the component still references, so rewriting it in place would leave that name unbound.
|
|
141
141
|
*/
|
|
142
142
|
function isJsxExpressionContainer(source: string, open: number): boolean {
|
|
143
|
-
const before = skipBackWhitespace(source, open - 1)
|
|
144
|
-
if (before < 0) return false
|
|
145
|
-
const ch = source[before]
|
|
143
|
+
const before = skipBackWhitespace(source, open - 1)
|
|
144
|
+
if (before < 0) return false
|
|
145
|
+
const ch = source[before]
|
|
146
146
|
// `prop={…` (attribute) or `<div>{…` (children) — but not `=>{` (arrow body)
|
|
147
147
|
// and not `==`/`>=` style operators.
|
|
148
|
-
if (source[before - 1] === '=') return false
|
|
149
|
-
return ch === '=' || ch === '>'
|
|
148
|
+
if (source[before - 1] === '=') return false
|
|
149
|
+
return ch === '=' || ch === '>'
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
function skipBackWhitespace(source: string, from: number): number {
|
|
153
|
-
let i = from
|
|
154
|
-
while (i >= 0 && /\s/.test(source[i] ?? '')) i
|
|
155
|
-
return i
|
|
153
|
+
let i = from
|
|
154
|
+
while (i >= 0 && /\s/.test(source[i] ?? '')) i--
|
|
155
|
+
return i
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
function identifierStart(source: string, end: number): number | undefined {
|
|
159
|
-
if (!/[\w$]/.test(source[end] ?? '')) return undefined
|
|
160
|
-
let i = end
|
|
161
|
-
while (i >= 0 && /[\w$]/.test(source[i] ?? '')) i
|
|
162
|
-
return i + 1
|
|
159
|
+
if (!/[\w$]/.test(source[end] ?? '')) return undefined
|
|
160
|
+
let i = end
|
|
161
|
+
while (i >= 0 && /[\w$]/.test(source[i] ?? '')) i--
|
|
162
|
+
return i + 1
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
function matchingOpenParen(source: string, close: number): number | undefined {
|
|
166
|
-
let depth = 0
|
|
166
|
+
let depth = 0
|
|
167
167
|
for (let i = close; i >= 0; i--) {
|
|
168
|
-
if (source[i] === ')') depth
|
|
168
|
+
if (source[i] === ')') depth++
|
|
169
169
|
else if (source[i] === '(') {
|
|
170
|
-
depth
|
|
171
|
-
if (depth === 0) return i
|
|
170
|
+
depth--
|
|
171
|
+
if (depth === 0) return i
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
return undefined
|
|
174
|
+
return undefined
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
/** Start offset of `keyword` when it directly precedes `at`, else undefined. */
|
|
178
178
|
function precedingKeyword(source: string, at: number, keyword: string): number | undefined {
|
|
179
|
-
const end = skipBackWhitespace(source, at - 1)
|
|
180
|
-
const start = identifierStart(source, end)
|
|
181
|
-
if (start === undefined || source.slice(start, end + 1) !== keyword) return undefined
|
|
182
|
-
return start
|
|
179
|
+
const end = skipBackWhitespace(source, at - 1)
|
|
180
|
+
const start = identifierStart(source, end)
|
|
181
|
+
if (start === undefined || source.slice(start, end + 1) !== keyword) return undefined
|
|
182
|
+
return start
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/** Offset just past the `}` closing the function body that opens at `open`. */
|
|
186
186
|
function bodyEnd(source: string, open: number): number | undefined {
|
|
187
|
-
const end = declarationEnd(source, open + 1)
|
|
188
|
-
if (end === undefined) return undefined
|
|
189
|
-
return source[end - 1] === ';' ? end - 1 : end
|
|
187
|
+
const end = declarationEnd(source, open + 1)
|
|
188
|
+
if (end === undefined) return undefined
|
|
189
|
+
return source[end - 1] === ';' ? end - 1 : end
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
function declarationEnd(source: string, directiveEnd: number): number | undefined {
|
|
193
193
|
// The body-open `{` is the last `{` at or before the directive.
|
|
194
|
-
let open = -1
|
|
194
|
+
let open = -1
|
|
195
195
|
for (let i = directiveEnd - 1; i >= 0; i--) {
|
|
196
196
|
if (source[i] === '{') {
|
|
197
|
-
open = i
|
|
198
|
-
break
|
|
197
|
+
open = i
|
|
198
|
+
break
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
-
if (open === -1) return undefined
|
|
202
|
-
let depth = 0
|
|
201
|
+
if (open === -1) return undefined
|
|
202
|
+
let depth = 0
|
|
203
203
|
for (let i = open; i < source.length; i++) {
|
|
204
|
-
const ch = source[i]
|
|
204
|
+
const ch = source[i]
|
|
205
205
|
// Skip string/template/comment spans so their braces don't miscount and
|
|
206
206
|
// shift the insertion point into the middle of an expression.
|
|
207
207
|
if (ch === '"' || ch === "'" || ch === '`') {
|
|
208
|
-
i = skipString(source, i, ch)
|
|
209
|
-
continue
|
|
208
|
+
i = skipString(source, i, ch)
|
|
209
|
+
continue
|
|
210
210
|
}
|
|
211
211
|
if (ch === '/' && source[i + 1] === '/') {
|
|
212
|
-
const nl = source.indexOf('\n', i + 2)
|
|
213
|
-
if (nl === -1) return undefined
|
|
214
|
-
i = nl
|
|
215
|
-
continue
|
|
212
|
+
const nl = source.indexOf('\n', i + 2)
|
|
213
|
+
if (nl === -1) return undefined
|
|
214
|
+
i = nl
|
|
215
|
+
continue
|
|
216
216
|
}
|
|
217
217
|
if (ch === '/' && source[i + 1] === '*') {
|
|
218
|
-
const end = source.indexOf('*/', i + 2)
|
|
219
|
-
if (end === -1) return undefined
|
|
220
|
-
i = end + 1
|
|
221
|
-
continue
|
|
218
|
+
const end = source.indexOf('*/', i + 2)
|
|
219
|
+
if (end === -1) return undefined
|
|
220
|
+
i = end + 1
|
|
221
|
+
continue
|
|
222
222
|
}
|
|
223
|
-
if (ch === '{') depth
|
|
223
|
+
if (ch === '{') depth++
|
|
224
224
|
else if (ch === '}') {
|
|
225
|
-
depth
|
|
225
|
+
depth--
|
|
226
226
|
if (depth === 0) {
|
|
227
|
-
let end = i + 1
|
|
228
|
-
if (source[end] === ';') end += 1
|
|
229
|
-
return end
|
|
227
|
+
let end = i + 1
|
|
228
|
+
if (source[end] === ';') end += 1
|
|
229
|
+
return end
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
-
return undefined
|
|
233
|
+
return undefined
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
/** Return the index of the closing quote of a string/template starting at `i`. */
|
|
237
237
|
function skipString(source: string, i: number, quote: string): number {
|
|
238
238
|
for (let j = i + 1; j < source.length; j++) {
|
|
239
|
-
const ch = source[j]
|
|
239
|
+
const ch = source[j]
|
|
240
240
|
if (ch === '\\') {
|
|
241
|
-
j += 1
|
|
242
|
-
continue
|
|
241
|
+
j += 1
|
|
242
|
+
continue
|
|
243
243
|
}
|
|
244
|
-
if (ch === quote) return j
|
|
244
|
+
if (ch === quote) return j
|
|
245
245
|
// Nested `${...}` in template literals can contain braces/strings; a
|
|
246
246
|
// conservative bail (treat the rest as opaque) is safer than miscounting.
|
|
247
247
|
if (quote === '`' && ch === '$' && source[j + 1] === '{') {
|
|
248
|
-
let depth = 1
|
|
249
|
-
j += 2
|
|
248
|
+
let depth = 1
|
|
249
|
+
j += 2
|
|
250
250
|
while (j < source.length && depth > 0) {
|
|
251
|
-
if (source[j] === '{') depth
|
|
252
|
-
else if (source[j] === '}') depth
|
|
253
|
-
j
|
|
251
|
+
if (source[j] === '{') depth++
|
|
252
|
+
else if (source[j] === '}') depth--
|
|
253
|
+
j++
|
|
254
254
|
}
|
|
255
|
-
j -= 1
|
|
255
|
+
j -= 1
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
return source.length
|
|
258
|
+
return source.length
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
function inlineActionId(fileKey: string, name: string): string {
|
|
262
262
|
// 'if:' ids embed the module key so a cold lookup can import the module
|
|
263
263
|
// (running the injected registration) and retry — see resolveAction.
|
|
264
|
-
return `if:${encodeURIComponent(fileKey)}:${encodeURIComponent(name)}
|
|
264
|
+
return `if:${encodeURIComponent(fileKey)}:${encodeURIComponent(name)}`
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
/** Parse the module key out of an 'if:' inline-action id. */
|
|
268
268
|
export function inlineActionModuleKey(id: string): string | undefined {
|
|
269
|
-
if (!id.startsWith('if:')) return undefined
|
|
270
|
-
const rest = id.slice(3)
|
|
271
|
-
const separator = rest.lastIndexOf(':')
|
|
272
|
-
if (separator === -1) return undefined
|
|
269
|
+
if (!id.startsWith('if:')) return undefined
|
|
270
|
+
const rest = id.slice(3)
|
|
271
|
+
const separator = rest.lastIndexOf(':')
|
|
272
|
+
if (separator === -1) return undefined
|
|
273
273
|
try {
|
|
274
|
-
return decodeURIComponent(rest.slice(0, separator))
|
|
274
|
+
return decodeURIComponent(rest.slice(0, separator))
|
|
275
275
|
} catch {
|
|
276
|
-
return undefined
|
|
276
|
+
return undefined
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
export function isInlineActionId(id: string): boolean {
|
|
281
|
-
return id.startsWith('if:')
|
|
281
|
+
return id.startsWith('if:')
|
|
282
282
|
}
|
|
@@ -5,30 +5,30 @@
|
|
|
5
5
|
// redirect/refresh/error semantics, island prop revival, and <form action={fn}> interception.
|
|
6
6
|
// Only imported into client entries when Next compat is enabled.
|
|
7
7
|
|
|
8
|
-
import { softNavigate } from '../../
|
|
9
|
-
import { installActionRuntime } from './
|
|
8
|
+
import { softNavigate } from '../../client/router'
|
|
9
|
+
import { installActionRuntime } from './client'
|
|
10
10
|
|
|
11
11
|
interface PNextRouterGlobal {
|
|
12
|
-
navigate: (href: string) => Promise<void
|
|
13
|
-
refresh: () => Promise<void
|
|
12
|
+
navigate: (href: string) => Promise<void>
|
|
13
|
+
refresh: () => Promise<void>
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
declare global {
|
|
17
17
|
interface Window {
|
|
18
|
-
__PNEXT_ROUTER__?: PNextRouterGlobal
|
|
18
|
+
__PNEXT_ROUTER__?: PNextRouterGlobal
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export function installActionRouter() {
|
|
23
|
-
if (!process.browser && typeof window === 'undefined') return
|
|
24
|
-
installActionRuntime()
|
|
25
|
-
const existing = window.__PNEXT_ROUTER__
|
|
23
|
+
if (!process.browser && typeof window === 'undefined') return
|
|
24
|
+
installActionRuntime()
|
|
25
|
+
const existing = window.__PNEXT_ROUTER__
|
|
26
26
|
if (
|
|
27
27
|
existing &&
|
|
28
28
|
typeof existing.navigate === 'function' &&
|
|
29
29
|
typeof existing.refresh === 'function'
|
|
30
30
|
) {
|
|
31
|
-
return
|
|
31
|
+
return
|
|
32
32
|
}
|
|
33
33
|
window.__PNEXT_ROUTER__ = {
|
|
34
34
|
navigate: (href: string) => softNavigate(href),
|
|
@@ -36,5 +36,5 @@ export function installActionRouter() {
|
|
|
36
36
|
// re-runs the server render (picking up any revalidated data). replace:true
|
|
37
37
|
// keeps history intact; scroll:false avoids jumping to the top.
|
|
38
38
|
refresh: () => softNavigate(location.href, { replace: true, scroll: false }),
|
|
39
|
-
}
|
|
39
|
+
}
|
|
40
40
|
}
|