@timber-js/app 0.2.0-alpha.4 → 0.2.0-alpha.41
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/LICENSE +8 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-Ba7URUIn.js} +1 -1
- package/dist/_chunks/als-registry-Ba7URUIn.js.map +1 -0
- package/dist/_chunks/chunk-DYhsFzuS.js +33 -0
- package/dist/_chunks/debug-ECi_61pb.js +108 -0
- package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
- package/dist/_chunks/define-cookie-BmKbSyp0.js +93 -0
- package/dist/_chunks/define-cookie-BmKbSyp0.js.map +1 -0
- package/dist/_chunks/error-boundary-BAN3751q.js +211 -0
- package/dist/_chunks/error-boundary-BAN3751q.js.map +1 -0
- package/dist/_chunks/{format-CwdaB0_2.js → format-cX7wzEp2.js} +2 -2
- package/dist/_chunks/{format-CwdaB0_2.js.map → format-cX7wzEp2.js.map} +1 -1
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-D2djYaIm.js} +112 -77
- package/dist/_chunks/interception-D2djYaIm.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-BU684ls2.js} +1 -1
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-BU684ls2.js.map} +1 -1
- package/dist/_chunks/{request-context-CZJi4CuK.js → request-context-BxYIJM24.js} +93 -69
- package/dist/_chunks/request-context-BxYIJM24.js.map +1 -0
- package/dist/_chunks/segment-context-C6byCyZU.js +69 -0
- package/dist/_chunks/segment-context-C6byCyZU.js.map +1 -0
- package/dist/_chunks/stale-reload-C0ValzG7.js +47 -0
- package/dist/_chunks/stale-reload-C0ValzG7.js.map +1 -0
- package/dist/_chunks/{tracing-Cwn7697K.js → tracing-CuXiCP5p.js} +17 -3
- package/dist/_chunks/{tracing-Cwn7697K.js.map → tracing-CuXiCP5p.js.map} +1 -1
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-BvW0TKDn.js} +1 -1
- package/dist/_chunks/{use-query-states-D5KaffOK.js.map → use-query-states-BvW0TKDn.js.map} +1 -1
- package/dist/_chunks/wrappers-C6J0nNji.js +331 -0
- package/dist/_chunks/wrappers-C6J0nNji.js.map +1 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -13
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/fast-hash.d.ts +22 -0
- package/dist/cache/fast-hash.d.ts.map +1 -0
- package/dist/cache/index.d.ts +5 -2
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +88 -18
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/register-cached-function.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +10 -1
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -125
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +213 -93
- package/dist/client/index.js.map +1 -1
- package/dist/client/link.d.ts +22 -8
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +2 -2
- package/dist/client/router.d.ts +25 -3
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +23 -2
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-context.d.ts +1 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-merger.d.ts.map +1 -1
- package/dist/client/stale-reload.d.ts +15 -0
- package/dist/client/stale-reload.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +1 -1
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/transition-root.d.ts +1 -1
- package/dist/client/transition-root.d.ts.map +1 -1
- package/dist/client/use-params.d.ts +2 -2
- package/dist/client/use-params.d.ts.map +1 -1
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/codec.d.ts +21 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/cookies/define-cookie.d.ts +33 -12
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -83
- package/dist/fonts/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/fonts/local.d.ts +4 -2
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/index.d.ts +112 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +635 -233
- package/dist/index.js.map +1 -1
- package/dist/params/define.d.ts +76 -0
- package/dist/params/define.d.ts.map +1 -0
- package/dist/params/index.d.ts +8 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +104 -0
- package/dist/params/index.js.map +1 -0
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +32 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/dev-error-overlay.d.ts +26 -1
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +7 -0
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +9 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +6 -0
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen.d.ts +2 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/index.js +1 -1
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/status-file-lint.d.ts +2 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +6 -4
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/search-params/codecs.d.ts +1 -1
- package/dist/search-params/define.d.ts +153 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -5
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +3 -474
- package/dist/search-params/registry.d.ts +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/server/access-gate.d.ts +4 -0
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +18 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +2 -2
- package/dist/server/debug.d.ts +46 -15
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -5
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +4 -0
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +78 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +39 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/flush.d.ts.map +1 -1
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +5 -11
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1975 -1649
- package/dist/server/index.js.map +1 -1
- package/dist/server/logger.d.ts +24 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +77 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +7 -4
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +30 -3
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +65 -38
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +7 -0
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +2 -2
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +46 -3
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +6 -1
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +9 -0
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +22 -0
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +39 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +10 -0
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +19 -12
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -3
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/server/waituntil-bridge.d.ts.map +1 -1
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shims/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +17 -14
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +58 -9
- package/src/cache/fast-hash.ts +34 -0
- package/src/cache/index.ts +5 -2
- package/src/cache/register-cached-function.ts +7 -3
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/timber-cache.ts +34 -26
- package/src/cli.ts +0 -0
- package/src/client/browser-entry.ts +94 -90
- package/src/client/error-boundary.tsx +18 -1
- package/src/client/index.ts +10 -1
- package/src/client/link.tsx +78 -19
- package/src/client/navigation-context.ts +2 -2
- package/src/client/router.ts +105 -60
- package/src/client/rsc-fetch.ts +63 -2
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-context.ts +6 -1
- package/src/client/segment-merger.ts +2 -8
- package/src/client/stale-reload.ts +32 -6
- package/src/client/top-loader.tsx +10 -9
- package/src/client/transition-root.tsx +7 -1
- package/src/client/use-params.ts +3 -3
- package/src/client/use-query-states.ts +1 -1
- package/src/codec.ts +21 -0
- package/src/cookies/define-cookie.ts +69 -18
- package/src/fonts/css.ts +2 -1
- package/src/fonts/local.ts +7 -3
- package/src/index.ts +280 -85
- package/src/params/define.ts +260 -0
- package/src/params/index.ts +28 -0
- package/src/plugins/adapter-build.ts +6 -0
- package/src/plugins/build-manifest.ts +11 -0
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/dev-error-overlay.ts +70 -1
- package/src/plugins/dev-server.ts +38 -4
- package/src/plugins/entries.ts +12 -11
- package/src/plugins/fonts.ts +171 -19
- package/src/plugins/mdx.ts +9 -5
- package/src/plugins/routing.ts +40 -14
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +1 -1
- package/src/plugins/static-build.ts +8 -4
- package/src/routing/codegen.ts +109 -88
- package/src/routing/scanner.ts +55 -6
- package/src/routing/status-file-lint.ts +2 -1
- package/src/routing/types.ts +7 -4
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/search-params/codecs.ts +1 -1
- package/src/search-params/define.ts +504 -0
- package/src/search-params/index.ts +12 -18
- package/src/search-params/registry.ts +1 -1
- package/src/search-params/wrappers.ts +85 -0
- package/src/server/access-gate.tsx +40 -9
- package/src/server/action-client.ts +14 -5
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +19 -2
- package/src/server/als-registry.ts +18 -4
- package/src/server/build-manifest.ts +4 -4
- package/src/server/compress.ts +25 -7
- package/src/server/debug.ts +55 -17
- package/src/server/default-logger.ts +98 -0
- package/src/server/deny-renderer.ts +2 -1
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +57 -14
- package/src/server/flight-injection-state.ts +152 -0
- package/src/server/flight-scripts.ts +59 -0
- package/src/server/flush.ts +2 -1
- package/src/server/form-data.ts +76 -0
- package/src/server/html-injectors.ts +103 -66
- package/src/server/index.ts +9 -4
- package/src/server/logger.ts +38 -35
- package/src/server/node-stream-transforms.ts +381 -0
- package/src/server/pipeline.ts +131 -39
- package/src/server/primitives.ts +47 -5
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +112 -119
- package/src/server/route-element-builder.ts +106 -114
- package/src/server/route-handler.ts +2 -1
- package/src/server/route-matcher.ts +2 -2
- package/src/server/rsc-entry/error-renderer.ts +5 -3
- package/src/server/rsc-entry/helpers.ts +122 -3
- package/src/server/rsc-entry/index.ts +125 -49
- package/src/server/rsc-entry/rsc-payload.ts +52 -12
- package/src/server/rsc-entry/rsc-stream.ts +33 -8
- package/src/server/rsc-entry/ssr-renderer.ts +40 -13
- package/src/server/slot-resolver.ts +199 -210
- package/src/server/ssr-entry.ts +168 -22
- package/src/server/ssr-render.ts +289 -67
- package/src/server/tracing.ts +23 -0
- package/src/server/tree-builder.ts +91 -57
- package/src/server/types.ts +1 -3
- package/src/server/version-skew.ts +104 -0
- package/src/server/waituntil-bridge.ts +4 -1
- package/src/shared/merge-search-params.ts +48 -0
- package/src/shims/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +1 -1
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-B4WUeqJ-.js +0 -75
- package/dist/_chunks/debug-B4WUeqJ-.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/request-context-CZJi4CuK.js.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js +0 -88
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/client/error-boundary.js.map +0 -1
- package/dist/cookies/index.js.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/search-params/index.js.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/response-cache.d.ts +0 -53
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/create.ts +0 -321
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -277
package/src/server/ssr-entry.ts
CHANGED
|
@@ -14,11 +14,21 @@
|
|
|
14
14
|
|
|
15
15
|
// @ts-expect-error — virtual module provided by timber-entries plugin
|
|
16
16
|
import config from 'virtual:timber-config';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
createFromReadableStream,
|
|
19
|
+
createFromNodeStream,
|
|
20
|
+
hasNodeStreamDecode,
|
|
21
|
+
} from '#/rsc-runtime/ssr.js';
|
|
18
22
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
19
23
|
|
|
20
|
-
import {
|
|
21
|
-
|
|
24
|
+
import {
|
|
25
|
+
renderSsrStream,
|
|
26
|
+
renderSsrNodeStream,
|
|
27
|
+
nodeReadableToWeb,
|
|
28
|
+
useNodeStreams,
|
|
29
|
+
buildSsrResponse,
|
|
30
|
+
} from './ssr-render.js';
|
|
31
|
+
import { logRenderError } from './logger.js';
|
|
22
32
|
import { SsrStreamError } from './primitives.js';
|
|
23
33
|
import { injectHead, injectRscPayload } from './html-injectors.js';
|
|
24
34
|
import { withNuqsSsrAdapter } from './nuqs-ssr-provider.js';
|
|
@@ -26,6 +36,41 @@ import { withSpan } from './tracing.js';
|
|
|
26
36
|
import { setCurrentParams } from '#/client/use-params.js';
|
|
27
37
|
import { registerSsrDataProvider, type SsrData } from '#/client/ssr-data.js';
|
|
28
38
|
|
|
39
|
+
// Pre-import Node.js stream modules at module load time — not per-request.
|
|
40
|
+
// Dynamic imports of node-stream-transforms and node:stream/promises were
|
|
41
|
+
// costing 3-17ms per request due to module resolution overhead.
|
|
42
|
+
let _nodeStreamImports: {
|
|
43
|
+
createNodeHeadInjector: typeof import('./node-stream-transforms.js').createNodeHeadInjector;
|
|
44
|
+
createNodeFlightInjector: typeof import('./node-stream-transforms.js').createNodeFlightInjector;
|
|
45
|
+
createNodeErrorHandler: typeof import('./node-stream-transforms.js').createNodeErrorHandler;
|
|
46
|
+
pipeline: typeof import('node:stream/promises').pipeline;
|
|
47
|
+
PassThrough: typeof import('node:stream').PassThrough;
|
|
48
|
+
ReadableFromWeb: (
|
|
49
|
+
webStream: import('stream/web').ReadableStream
|
|
50
|
+
) => import('node:stream').Readable;
|
|
51
|
+
} | null = null;
|
|
52
|
+
|
|
53
|
+
if (useNodeStreams) {
|
|
54
|
+
try {
|
|
55
|
+
const [transforms, streamPromises, stream] = await Promise.all([
|
|
56
|
+
import('./node-stream-transforms.js'),
|
|
57
|
+
import('node:stream/promises'),
|
|
58
|
+
import('node:stream'),
|
|
59
|
+
]);
|
|
60
|
+
_nodeStreamImports = {
|
|
61
|
+
createNodeHeadInjector: transforms.createNodeHeadInjector,
|
|
62
|
+
createNodeFlightInjector: transforms.createNodeFlightInjector,
|
|
63
|
+
createNodeErrorHandler: transforms.createNodeErrorHandler,
|
|
64
|
+
pipeline: streamPromises.pipeline,
|
|
65
|
+
PassThrough: stream.PassThrough,
|
|
66
|
+
ReadableFromWeb: (webStream: import('stream/web').ReadableStream) =>
|
|
67
|
+
stream.Readable.fromWeb(webStream) as import('node:stream').Readable,
|
|
68
|
+
};
|
|
69
|
+
} catch {
|
|
70
|
+
// Fall back to Web Streams path
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
29
74
|
// ─── SSR Data ALS ─────────────────────────────────────────────────────────
|
|
30
75
|
//
|
|
31
76
|
// Per-request SSR data stored in AsyncLocalStorage, ensuring correct
|
|
@@ -81,6 +126,29 @@ export interface NavContext {
|
|
|
81
126
|
* to a page-level deny. See LOCAL-298.
|
|
82
127
|
*/
|
|
83
128
|
_denyHandledByBoundary?: boolean;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Mutable: SSR timing data populated by handleSsr().
|
|
132
|
+
* Read by the RSC entry to record sub-phase Server-Timing entries
|
|
133
|
+
* when `serverTiming: 'detailed'` is configured.
|
|
134
|
+
*
|
|
135
|
+
* This bridges the RSC→SSR environment boundary: the SSR entry populates
|
|
136
|
+
* these fields, the RSC entry reads them after callSsr() returns.
|
|
137
|
+
*/
|
|
138
|
+
_ssrTimings?: {
|
|
139
|
+
/** Time to decode RSC stream (createFromReadableStream/createFromNodeStream) */
|
|
140
|
+
decodeMs: number;
|
|
141
|
+
/** Time for Fizz to render the shell (onShellReady) */
|
|
142
|
+
shellMs: number;
|
|
143
|
+
/** Time for pipe() to flush shell bytes to the output stream */
|
|
144
|
+
pipeMs: number;
|
|
145
|
+
/** Time to set up Node.js Transform pipeline / Web Stream transforms */
|
|
146
|
+
pipelineMs: number;
|
|
147
|
+
/** Total SSR time (decode → response ready) */
|
|
148
|
+
totalMs: number;
|
|
149
|
+
/** Whether the Node.js native stream path was used */
|
|
150
|
+
nodeStreams: boolean;
|
|
151
|
+
};
|
|
84
152
|
}
|
|
85
153
|
|
|
86
154
|
/**
|
|
@@ -127,7 +195,7 @@ export async function handleSsr(
|
|
|
127
195
|
// Client hooks read from getSsrData() which delegates to this
|
|
128
196
|
// ALS store via the registered provider.
|
|
129
197
|
return ssrDataAls.run(ssrData, async () => {
|
|
130
|
-
// Also set the module-level currentParams for
|
|
198
|
+
// Also set the module-level currentParams for useSegmentParams().
|
|
131
199
|
// useParams reads from getSsrData() during SSR (ALS-backed),
|
|
132
200
|
// but setCurrentParams is kept for the client-side path where
|
|
133
201
|
// the segment router updates params on navigation.
|
|
@@ -137,47 +205,125 @@ export async function handleSsr(
|
|
|
137
205
|
// createFromReadableStream resolves client component references
|
|
138
206
|
// (from "use client" modules) using the SSR environment's module
|
|
139
207
|
// map, importing the actual components for server-side rendering.
|
|
140
|
-
const
|
|
208
|
+
const _ssrStart = performance.now();
|
|
209
|
+
|
|
210
|
+
// Decode the RSC stream into a React element tree.
|
|
211
|
+
// On Node.js: convert Web ReadableStream → Node Readable → createFromNodeStream
|
|
212
|
+
// (eliminates Promise-per-chunk overhead from Web Streams reader)
|
|
213
|
+
// On Workers: createFromReadableStream (Web Streams are V8-native C++ there)
|
|
214
|
+
let element: React.ReactNode;
|
|
215
|
+
if (hasNodeStreamDecode && _nodeStreamImports) {
|
|
216
|
+
const nodeRscStream = _nodeStreamImports.ReadableFromWeb(
|
|
217
|
+
rscStream as import('stream/web').ReadableStream
|
|
218
|
+
);
|
|
219
|
+
element = createFromNodeStream(nodeRscStream) as React.ReactNode;
|
|
220
|
+
} else {
|
|
221
|
+
element = createFromReadableStream(rscStream) as React.ReactNode;
|
|
222
|
+
}
|
|
223
|
+
const _decodeEnd = performance.now();
|
|
141
224
|
|
|
142
225
|
// Wrap with a server-safe nuqs adapter so that 'use client' components
|
|
143
226
|
// that call nuqs hooks (useQueryStates, useQueryState) can SSR correctly.
|
|
144
|
-
// The client-side TimberNuqsAdapter (injected by browser-entry.ts) takes
|
|
145
|
-
// over after hydration. This provider supplies the request's search params
|
|
146
|
-
// as a static snapshot so nuqs renders the right initial values on the server.
|
|
147
227
|
const wrappedElement = withNuqsSsrAdapter(navContext.searchParams, element);
|
|
148
228
|
|
|
149
229
|
// Render to HTML stream (waits for onShellReady).
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
230
|
+
//
|
|
231
|
+
// Two paths based on platform:
|
|
232
|
+
// - Node.js: renderToPipeableStream → Node Transform pipeline → Readable.toWeb() → Response
|
|
233
|
+
// Entire pipeline stays in C++ native streams until the Response boundary.
|
|
234
|
+
// - Workers: renderToReadableStream → Web TransformStream pipeline → Response
|
|
235
|
+
// Web Streams are V8-native C++ built-ins on Workers.
|
|
236
|
+
if (_nodeStreamImports) {
|
|
237
|
+
// Node.js fast path: full pipeline in native streams
|
|
238
|
+
const {
|
|
239
|
+
createNodeHeadInjector,
|
|
240
|
+
createNodeFlightInjector,
|
|
241
|
+
createNodeErrorHandler,
|
|
242
|
+
pipeline,
|
|
243
|
+
PassThrough,
|
|
244
|
+
} = _nodeStreamImports;
|
|
245
|
+
|
|
246
|
+
const renderTimeoutMs = _runtimeConfig.renderTimeoutMs ?? undefined;
|
|
247
|
+
|
|
248
|
+
let nodeHtmlStream: import('node:stream').Readable;
|
|
249
|
+
try {
|
|
250
|
+
nodeHtmlStream = await renderSsrNodeStream(wrappedElement, {
|
|
251
|
+
bootstrapScriptContent: navContext.bootstrapScriptContent || undefined,
|
|
252
|
+
deferSuspenseFor: navContext.deferSuspenseFor,
|
|
253
|
+
signal: navContext.signal,
|
|
254
|
+
renderTimeoutMs,
|
|
255
|
+
});
|
|
256
|
+
} catch (renderError) {
|
|
257
|
+
logRenderError({ method: '', path: '', error: renderError });
|
|
258
|
+
throw new SsrStreamError(
|
|
259
|
+
'SSR renderToReadableStream failed due to RSC stream error',
|
|
260
|
+
renderError
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
const _renderEnd = performance.now();
|
|
264
|
+
|
|
265
|
+
// React 19.3+ emits <!DOCTYPE html> automatically when the root
|
|
266
|
+
// element is <html>, so no framework-level doctype prepend needed.
|
|
267
|
+
const errorHandler = createNodeErrorHandler(navContext.signal);
|
|
268
|
+
const headInjector = createNodeHeadInjector(navContext.headHtml);
|
|
269
|
+
const flightInjector = createNodeFlightInjector(navContext.rscStream, {
|
|
270
|
+
renderTimeoutMs,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const output = new PassThrough();
|
|
274
|
+
pipeline(nodeHtmlStream, errorHandler, headInjector, flightInjector, output).catch(() => {
|
|
275
|
+
// Pipeline errors are handled by errorHandler transform
|
|
276
|
+
});
|
|
277
|
+
const _pipelineEnd = performance.now();
|
|
278
|
+
|
|
279
|
+
// Record SSR sub-timings for Server-Timing header (detailed mode).
|
|
280
|
+
navContext._ssrTimings = {
|
|
281
|
+
decodeMs: Math.round(_decodeEnd - _ssrStart),
|
|
282
|
+
shellMs: Math.round(_renderEnd - _decodeEnd),
|
|
283
|
+
pipeMs: 0, // pipe() timing is inside renderSsrNodeStream
|
|
284
|
+
pipelineMs: Math.round(_pipelineEnd - _renderEnd),
|
|
285
|
+
totalMs: Math.round(_pipelineEnd - _ssrStart),
|
|
286
|
+
nodeStreams: true,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const webStream = nodeReadableToWeb(output);
|
|
290
|
+
return buildSsrResponse(webStream, navContext.statusCode, navContext.responseHeaders);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Web Streams path (CF Workers / fallback)
|
|
294
|
+
const renderTimeoutMs = _runtimeConfig.renderTimeoutMs ?? undefined;
|
|
154
295
|
let htmlStream: ReadableStream<Uint8Array>;
|
|
155
296
|
try {
|
|
156
297
|
htmlStream = await renderSsrStream(wrappedElement, {
|
|
157
298
|
bootstrapScriptContent: navContext.bootstrapScriptContent || undefined,
|
|
158
299
|
deferSuspenseFor: navContext.deferSuspenseFor,
|
|
159
300
|
signal: navContext.signal,
|
|
301
|
+
renderTimeoutMs,
|
|
160
302
|
});
|
|
161
303
|
} catch (renderError) {
|
|
162
|
-
|
|
163
|
-
// that wasn't caught by any error boundary in the decoded tree.
|
|
164
|
-
// Wrap in SsrStreamError so the RSC entry can handle it without
|
|
165
|
-
// re-executing server components via renderDenyPage.
|
|
166
|
-
// See LOCAL-293.
|
|
167
|
-
console.error(
|
|
168
|
-
'[timber] SSR shell failed from RSC stream error:',
|
|
169
|
-
formatSsrError(renderError)
|
|
170
|
-
);
|
|
304
|
+
logRenderError({ method: '', path: '', error: renderError });
|
|
171
305
|
throw new SsrStreamError(
|
|
172
306
|
'SSR renderToReadableStream failed due to RSC stream error',
|
|
173
307
|
renderError
|
|
174
308
|
);
|
|
175
309
|
}
|
|
176
310
|
|
|
311
|
+
const _renderEnd = performance.now();
|
|
312
|
+
|
|
177
313
|
// Inject metadata into <head>, then interleave RSC payload chunks
|
|
178
314
|
// into the body as they arrive from the tee'd RSC stream.
|
|
179
315
|
let outputStream = injectHead(htmlStream, navContext.headHtml);
|
|
180
|
-
outputStream = injectRscPayload(outputStream, navContext.rscStream);
|
|
316
|
+
outputStream = injectRscPayload(outputStream, navContext.rscStream, renderTimeoutMs);
|
|
317
|
+
const _pipelineEnd = performance.now();
|
|
318
|
+
|
|
319
|
+
navContext._ssrTimings = {
|
|
320
|
+
decodeMs: Math.round(_decodeEnd - _ssrStart),
|
|
321
|
+
shellMs: Math.round(_renderEnd - _decodeEnd),
|
|
322
|
+
pipeMs: 0,
|
|
323
|
+
pipelineMs: Math.round(_pipelineEnd - _renderEnd),
|
|
324
|
+
totalMs: Math.round(_pipelineEnd - _ssrStart),
|
|
325
|
+
nodeStreams: false,
|
|
326
|
+
};
|
|
181
327
|
|
|
182
328
|
// Build and return the Response.
|
|
183
329
|
return buildSsrResponse(outputStream, navContext.statusCode, navContext.responseHeaders);
|