@timber-js/app 0.2.0-alpha.4 → 0.2.0-alpha.40
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 +169 -17
- package/src/server/ssr-render.ts +266 -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/index.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { Plugin, PluginOption } from 'vite';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
5
4
|
import { createRequire } from 'node:module';
|
|
6
|
-
import react from '@vitejs/plugin-react';
|
|
5
|
+
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
|
|
7
6
|
import { cacheTransformPlugin } from './plugins/cache-transform';
|
|
8
7
|
import { timberContent } from './plugins/content';
|
|
9
8
|
import { timberDevServer } from './plugins/dev-server';
|
|
@@ -13,12 +12,12 @@ import { timberRouting } from './plugins/routing';
|
|
|
13
12
|
import { timberShims } from './plugins/shims';
|
|
14
13
|
import { timberFonts } from './plugins/fonts';
|
|
15
14
|
import { timberStaticBuild } from './plugins/static-build';
|
|
16
|
-
import { timberDynamicTransform } from './plugins/dynamic-transform';
|
|
17
15
|
import { timberServerActionExports } from './plugins/server-action-exports';
|
|
18
16
|
import { timberBuildManifest } from './plugins/build-manifest';
|
|
19
17
|
import { timberDevLogs } from './plugins/dev-logs';
|
|
20
18
|
import { timberReactProd } from './plugins/react-prod';
|
|
21
19
|
import { timberChunks } from './plugins/chunks';
|
|
20
|
+
import { clientChunkGroup } from './plugins/client-chunks';
|
|
22
21
|
import { timberServerBundle } from './plugins/server-bundle';
|
|
23
22
|
import { timberAdapterBuild } from './plugins/adapter-build';
|
|
24
23
|
import { timberBuildReport } from './plugins/build-report';
|
|
@@ -26,6 +25,7 @@ import type { RouteTree } from './routing/types';
|
|
|
26
25
|
import type { BuildManifest } from './server/build-manifest';
|
|
27
26
|
import type { StartupTimer } from './utils/startup-timer';
|
|
28
27
|
import { createStartupTimer, createNoopTimer } from './utils/startup-timer';
|
|
28
|
+
import { resolveEncryptionKeyExpression, shouldEnableEncryption } from './server/action-encryption';
|
|
29
29
|
|
|
30
30
|
/** Configuration for client-side JavaScript output. */
|
|
31
31
|
export interface ClientJavascriptConfig {
|
|
@@ -90,23 +90,39 @@ export interface TimberUserConfig {
|
|
|
90
90
|
* See design/17-logging.md §"slowRequestMs".
|
|
91
91
|
*/
|
|
92
92
|
slowRequestMs?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Render timeout in milliseconds. If an SSR render or RSC stream read
|
|
95
|
+
* does not complete within this duration, the render is aborted and
|
|
96
|
+
* the connection is closed. Protects against hung fetches and Suspense
|
|
97
|
+
* components that never resolve.
|
|
98
|
+
*
|
|
99
|
+
* Set to 0 to disable (not recommended in production).
|
|
100
|
+
* Default: 30000 (30 seconds).
|
|
101
|
+
*
|
|
102
|
+
* See design/02-rendering-pipeline.md §"Streaming Constraints".
|
|
103
|
+
*/
|
|
104
|
+
renderTimeoutMs?: number;
|
|
93
105
|
/** Dev-mode options. These have no effect in production builds. */
|
|
94
106
|
dev?: {
|
|
95
107
|
/** Threshold in ms to highlight slow phases in dev logging output. Default: 200. */
|
|
96
108
|
slowPhaseMs?: number;
|
|
97
109
|
};
|
|
98
110
|
/**
|
|
99
|
-
*
|
|
111
|
+
* Control Server-Timing header output.
|
|
112
|
+
*
|
|
113
|
+
* - `'detailed'` — per-phase breakdown (proxy, middleware, render). Useful
|
|
114
|
+
* for APM / network monitoring. Exposes phase names to clients.
|
|
115
|
+
* - `'total'` — single `total;dur=N` entry. Safe to expose, gives
|
|
116
|
+
* browser DevTools useful timing without internal details.
|
|
117
|
+
* - `false` — no Server-Timing header at all.
|
|
118
|
+
*
|
|
119
|
+
* Default: `'detailed'` in dev, `'total'` in production.
|
|
100
120
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
121
|
+
* This is separate from `debug` / `TIMBER_DEBUG` — it's an intentional
|
|
122
|
+
* decision to expose timing data to clients, not a side effect of debug
|
|
123
|
+
* logging.
|
|
103
124
|
*/
|
|
104
|
-
|
|
105
|
-
/** Single signing secret. Shorthand for `secrets: [secret]`. */
|
|
106
|
-
secret?: string;
|
|
107
|
-
/** Array of signing secrets for key rotation. Index 0 signs; all verify. */
|
|
108
|
-
secrets?: string[];
|
|
109
|
-
};
|
|
125
|
+
serverTiming?: 'detailed' | 'total' | false;
|
|
110
126
|
/**
|
|
111
127
|
* Override the app directory location. By default, timber auto-detects
|
|
112
128
|
* `app/` at the project root, falling back to `src/app/`.
|
|
@@ -132,6 +148,46 @@ export interface TimberUserConfig {
|
|
|
132
148
|
*
|
|
133
149
|
* See LOCAL-336 for design decisions.
|
|
134
150
|
*/
|
|
151
|
+
/**
|
|
152
|
+
* Server action bound args encryption configuration.
|
|
153
|
+
*
|
|
154
|
+
* The RSC plugin encrypts closure variables captured by 'use server' functions
|
|
155
|
+
* using AES-256-GCM so they are opaque and tamper-proof in the Flight payload.
|
|
156
|
+
* Encryption is always enabled in production.
|
|
157
|
+
*
|
|
158
|
+
* The encryption key is auto-generated at build time and embedded in the server bundle,
|
|
159
|
+
* so all instances running the same build share the same key automatically.
|
|
160
|
+
* For rolling/blue-green deployments where multiple builds coexist, set
|
|
161
|
+
* `TIMBER_ACTIONS_ENCRYPTION_KEY` env var to share a key across builds.
|
|
162
|
+
*
|
|
163
|
+
* See design/08-forms-and-actions.md §"Security"
|
|
164
|
+
*/
|
|
165
|
+
actionEncryption?: {
|
|
166
|
+
/**
|
|
167
|
+
* Disable encryption in dev mode for easier debugging of bound args.
|
|
168
|
+
* Has no effect in production — encryption is always enabled.
|
|
169
|
+
* Default: false (encryption is on in dev too).
|
|
170
|
+
*/
|
|
171
|
+
disableInDev?: boolean;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Enable the React Compiler (babel-plugin-react-compiler) for automatic
|
|
175
|
+
* memoization of components and hooks at build time.
|
|
176
|
+
*
|
|
177
|
+
* - `true` — enable with default options
|
|
178
|
+
* - `{ compilationMode, target }` — enable with custom options
|
|
179
|
+
* - `compilationMode: 'annotation'` — only compile files with `'use memo'`
|
|
180
|
+
* - `target: '18'` — target React 18 (uses react-compiler-runtime package)
|
|
181
|
+
* - `false` or omitted — disabled (default)
|
|
182
|
+
*
|
|
183
|
+
* Uses `@vitejs/plugin-react`'s built-in `reactCompilerPreset`, which:
|
|
184
|
+
* - Applies Babel only for the compiler pass (OXC handles JSX)
|
|
185
|
+
* - Automatically scopes to client environment only
|
|
186
|
+
* - Uses `react/compiler-runtime` built into React 19
|
|
187
|
+
*
|
|
188
|
+
* Requires `babel-plugin-react-compiler` as a peer dependency.
|
|
189
|
+
*/
|
|
190
|
+
reactCompiler?: boolean | { compilationMode?: string; target?: string };
|
|
135
191
|
topLoader?: {
|
|
136
192
|
/** Whether the top-loader is enabled. Default: true. */
|
|
137
193
|
enabled?: boolean;
|
|
@@ -146,34 +202,6 @@ export interface TimberUserConfig {
|
|
|
146
202
|
/** CSS z-index. Default: 1600. */
|
|
147
203
|
zIndex?: number;
|
|
148
204
|
};
|
|
149
|
-
/**
|
|
150
|
-
* Response-level caching and deduplication.
|
|
151
|
-
*
|
|
152
|
-
* When enabled, concurrent requests to the same URL share a single render
|
|
153
|
-
* (singleflight), and recently rendered responses are reused from a short-TTL
|
|
154
|
-
* LRU cache without re-executing the RSC-to-SSR pipeline.
|
|
155
|
-
*
|
|
156
|
-
* Set to `false` to disable entirely. Default: enabled with sensible defaults.
|
|
157
|
-
*
|
|
158
|
-
* See design/31-benchmarking.md for performance context.
|
|
159
|
-
*/
|
|
160
|
-
responseCache?:
|
|
161
|
-
| false
|
|
162
|
-
| {
|
|
163
|
-
/** Maximum number of entries in the LRU cache. Default: 150. */
|
|
164
|
-
maxSize?: number;
|
|
165
|
-
/** TTL for cached entries in milliseconds. Default: 5000 (5s). */
|
|
166
|
-
ttlMs?: number;
|
|
167
|
-
/**
|
|
168
|
-
* When true (default), requests with Cookie or Authorization headers
|
|
169
|
-
* bypass the cache entirely. This prevents sharing user-specific
|
|
170
|
-
* responses across requests.
|
|
171
|
-
*
|
|
172
|
-
* Set to false to cache all responses regardless of auth state.
|
|
173
|
-
* Only do this if your pages are truly public and don't vary by user.
|
|
174
|
-
*/
|
|
175
|
-
publicOnly?: boolean;
|
|
176
|
-
};
|
|
177
205
|
}
|
|
178
206
|
|
|
179
207
|
/**
|
|
@@ -221,6 +249,8 @@ export interface PluginContext {
|
|
|
221
249
|
dev: boolean;
|
|
222
250
|
/** CSS build manifest (populated by adapter after client build, null in dev) */
|
|
223
251
|
buildManifest: BuildManifest | null;
|
|
252
|
+
/** Per-build deployment ID for version skew detection (null in dev) */
|
|
253
|
+
deploymentId: string | null;
|
|
224
254
|
/** Startup timer for profiling cold start phases (active in dev, no-op in prod) */
|
|
225
255
|
timer: StartupTimer;
|
|
226
256
|
}
|
|
@@ -256,7 +286,10 @@ export function resolveAppDir(root: string, configAppDir?: string): string {
|
|
|
256
286
|
|
|
257
287
|
function createPluginContext(config?: TimberUserConfig, root?: string): PluginContext {
|
|
258
288
|
const projectRoot = root ?? process.cwd();
|
|
259
|
-
|
|
289
|
+
// Don't apply defaults here — they would override file-based config
|
|
290
|
+
// during mergeFileConfig (inline spreads over file). Defaults are
|
|
291
|
+
// applied after merge in timber(). See TIM-451.
|
|
292
|
+
const resolvedConfig: TimberUserConfig = { ...config };
|
|
260
293
|
// Timer starts as active — swapped to noop in configResolved for production builds
|
|
261
294
|
return {
|
|
262
295
|
config: resolvedConfig,
|
|
@@ -266,6 +299,7 @@ function createPluginContext(config?: TimberUserConfig, root?: string): PluginCo
|
|
|
266
299
|
root: projectRoot,
|
|
267
300
|
dev: false,
|
|
268
301
|
buildManifest: null,
|
|
302
|
+
deploymentId: null,
|
|
269
303
|
timer: createStartupTimer(),
|
|
270
304
|
};
|
|
271
305
|
}
|
|
@@ -273,14 +307,18 @@ function createPluginContext(config?: TimberUserConfig, root?: string): PluginCo
|
|
|
273
307
|
/**
|
|
274
308
|
* Load timber.config.ts (or .js, .mjs) from the project root.
|
|
275
309
|
* Returns the config object or null if no config file is found.
|
|
310
|
+
*
|
|
311
|
+
* Uses require() which works for ESM modules on Node 22.12+.
|
|
312
|
+
* This keeps timber() synchronous — no async config loading needed.
|
|
276
313
|
*/
|
|
277
|
-
|
|
314
|
+
export function loadTimberConfigFile(root: string): TimberUserConfig | null {
|
|
278
315
|
const configNames = ['timber.config.ts', 'timber.config.js', 'timber.config.mjs'];
|
|
316
|
+
const req = createRequire(join(root, 'package.json'));
|
|
279
317
|
|
|
280
318
|
for (const name of configNames) {
|
|
281
319
|
const configPath = join(root, name);
|
|
282
320
|
if (existsSync(configPath)) {
|
|
283
|
-
const mod =
|
|
321
|
+
const mod = req(configPath);
|
|
284
322
|
return (mod.default ?? mod) as TimberUserConfig;
|
|
285
323
|
}
|
|
286
324
|
}
|
|
@@ -300,7 +338,6 @@ export function warnConfigConflicts(
|
|
|
300
338
|
): string[] {
|
|
301
339
|
const conflicts: string[] = [];
|
|
302
340
|
for (const key of Object.keys(fileConfig) as (keyof TimberUserConfig)[]) {
|
|
303
|
-
if (key === 'output') continue;
|
|
304
341
|
if (key in inline && inline[key] !== undefined) {
|
|
305
342
|
conflicts.push(key);
|
|
306
343
|
}
|
|
@@ -339,28 +376,155 @@ function mergeFileConfig(ctx: PluginContext, fileConfig: TimberUserConfig): void
|
|
|
339
376
|
};
|
|
340
377
|
}
|
|
341
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Resolve the React Compiler plugin via @rolldown/plugin-babel.
|
|
381
|
+
*
|
|
382
|
+
* Uses the `reactCompilerPreset` from @vitejs/plugin-react, which:
|
|
383
|
+
* - Uses Babel ONLY for the compiler pass (OXC handles JSX)
|
|
384
|
+
* - Automatically scopes to client environment via applyToEnvironmentHook
|
|
385
|
+
* - Uses react/compiler-runtime built into React 19
|
|
386
|
+
*
|
|
387
|
+
* @rolldown/plugin-babel and babel-plugin-react-compiler are optional peer deps.
|
|
388
|
+
* If either is missing, require() fails with a clear error message.
|
|
389
|
+
*/
|
|
390
|
+
function resolveReactCompilerPlugin(
|
|
391
|
+
config: true | { compilationMode?: string; target?: string },
|
|
392
|
+
req: NodeRequire
|
|
393
|
+
): PluginOption {
|
|
394
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
395
|
+
let babel: any;
|
|
396
|
+
try {
|
|
397
|
+
babel = req('@rolldown/plugin-babel');
|
|
398
|
+
} catch {
|
|
399
|
+
throw new Error(
|
|
400
|
+
'[timber] reactCompiler requires @rolldown/plugin-babel. ' +
|
|
401
|
+
'Install it: pnpm add -D @rolldown/plugin-babel babel-plugin-react-compiler'
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
const options = typeof config === 'object' ? config : {};
|
|
405
|
+
const babelPlugin = babel.default ?? babel;
|
|
406
|
+
return babelPlugin({
|
|
407
|
+
presets: [reactCompilerPreset(options as Parameters<typeof reactCompilerPreset>[0])],
|
|
408
|
+
}) as PluginOption;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Build the options object for @vitejs/plugin-rsc.
|
|
413
|
+
*
|
|
414
|
+
* Uses a getter for `enableActionEncryption` so the RSC plugin reads
|
|
415
|
+
* the value lazily — after ctx.dev is set in configResolved. This lets
|
|
416
|
+
* `actionEncryption.disableInDev` work correctly even though the RSC
|
|
417
|
+
* plugin is created before Vite resolves the command.
|
|
418
|
+
*/
|
|
419
|
+
function createRscOptions(
|
|
420
|
+
ctx: PluginContext,
|
|
421
|
+
encryptionKeyExpr: string | undefined
|
|
422
|
+
): Record<string, unknown> {
|
|
423
|
+
const options: Record<string, unknown> = {
|
|
424
|
+
serverHandler: false,
|
|
425
|
+
customClientEntry: true,
|
|
426
|
+
entries: {
|
|
427
|
+
rsc: 'virtual:timber-rsc-entry',
|
|
428
|
+
ssr: 'virtual:timber-ssr-entry',
|
|
429
|
+
client: 'virtual:timber-browser-entry',
|
|
430
|
+
},
|
|
431
|
+
// Group client references by layout boundary to balance route-scoped code
|
|
432
|
+
// splitting with HTTP request count. A constant group name ('client-refs')
|
|
433
|
+
// would collapse all routes into one chunk — any page downloads every
|
|
434
|
+
// client component. Per-serverChunk grouping creates many sub-500B files.
|
|
435
|
+
// Layout-boundary grouping is the middle ground: components under the same
|
|
436
|
+
// layout segment share a chunk. See design/27-chunking-strategy.md, TIM-440, TIM-499.
|
|
437
|
+
clientChunks: (meta: { id: string; normalizedId: string; serverChunk: string }) =>
|
|
438
|
+
clientChunkGroup(meta, ctx.appDir),
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
// Bound args encryption — AES-256-GCM authenticated encryption for
|
|
442
|
+
// closure variables in 'use server' functions. Always on in production,
|
|
443
|
+
// configurable in dev. See design/08-forms-and-actions.md §"Bound Args Encryption".
|
|
444
|
+
//
|
|
445
|
+
// Uses a getter so the RSC plugin reads the value lazily in its transform
|
|
446
|
+
// hooks, after ctx.dev is set in configResolved. This lets disableInDev
|
|
447
|
+
// work correctly — ctx.dev is false at construction time but true during
|
|
448
|
+
// dev server transforms.
|
|
449
|
+
Object.defineProperty(options, 'enableActionEncryption', {
|
|
450
|
+
get() {
|
|
451
|
+
return shouldEnableEncryption(ctx.dev, ctx.config.actionEncryption);
|
|
452
|
+
},
|
|
453
|
+
enumerable: true,
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// When TIMBER_ACTIONS_ENCRYPTION_KEY is set, pass it as a runtime expression
|
|
457
|
+
// so the RSC plugin uses it instead of auto-generating a per-build key.
|
|
458
|
+
if (encryptionKeyExpr) {
|
|
459
|
+
options.defineEncryptionKey = encryptionKeyExpr;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return options;
|
|
463
|
+
}
|
|
464
|
+
|
|
342
465
|
function timberCache(_ctx: PluginContext): Plugin {
|
|
343
466
|
return cacheTransformPlugin();
|
|
344
467
|
}
|
|
345
468
|
|
|
469
|
+
/**
|
|
470
|
+
* Create the timber Vite plugin array.
|
|
471
|
+
*
|
|
472
|
+
* Loads timber.config.ts and all dependencies synchronously before
|
|
473
|
+
* constructing the plugin array. This ensures ALL plugins — including
|
|
474
|
+
* the RSC plugin and React Compiler — see the fully merged config
|
|
475
|
+
* (inline + file-based). No async, no deferred config, no stale reads.
|
|
476
|
+
*
|
|
477
|
+
* Requires Node >= 22.12 for synchronous require() of ESM modules
|
|
478
|
+
* (@vitejs/plugin-rsc is ESM-only).
|
|
479
|
+
*
|
|
480
|
+
* Previous versions used async loading and deferred config merging,
|
|
481
|
+
* causing file-based config for reactCompiler, actionEncryption, and
|
|
482
|
+
* output mode to be silently ignored. See TIM-451.
|
|
483
|
+
*/
|
|
346
484
|
export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
347
485
|
const ctx = createPluginContext(config);
|
|
348
|
-
|
|
349
|
-
//
|
|
350
|
-
//
|
|
486
|
+
|
|
487
|
+
// Resolve dependencies from the consumer's project (process.cwd()),
|
|
488
|
+
// not from timber's own node_modules. This is critical for pnpm link:
|
|
489
|
+
// when linked, timber's node_modules has a separate vite instance, and
|
|
490
|
+
// the RSC plugin must use the same vite instance as the dev server.
|
|
491
|
+
const consumerRequire = createRequire(join(process.cwd(), 'package.json'));
|
|
492
|
+
|
|
493
|
+
// ── Step 1: Load @vitejs/plugin-rsc ─────────────────────────────────
|
|
494
|
+
// Synchronous require() works for ESM modules on Node 22.12+.
|
|
495
|
+
ctx.timer.start('rsc-plugin-import');
|
|
496
|
+
const rscMod = consumerRequire('@vitejs/plugin-rsc');
|
|
497
|
+
const vitePluginRsc = rscMod.default ?? rscMod;
|
|
498
|
+
ctx.timer.end('rsc-plugin-import');
|
|
499
|
+
|
|
500
|
+
// ── Step 2: Compute config-dependent options ────────────────────────
|
|
501
|
+
// encryptionKeyExpr is env-based and doesn't depend on file config.
|
|
502
|
+
const encryptionKeyExpr = resolveEncryptionKeyExpression();
|
|
503
|
+
|
|
504
|
+
// ── Step 3: Build rootSync plugin ───────────────────────────────────
|
|
505
|
+
// rootSync loads timber.config.ts and resolves the Vite root.
|
|
506
|
+
// Config file loading happens in the `config` hook so it uses Vite's
|
|
507
|
+
// resolved root (from userConfig.root) instead of process.cwd().
|
|
508
|
+
// This is critical when running from a workspace root with
|
|
509
|
+
// `vite --config subdir/vite.config.ts` or a custom `root` option.
|
|
510
|
+
// See TIM-498.
|
|
351
511
|
const rootSync: Plugin = {
|
|
352
512
|
name: 'timber-root-sync',
|
|
353
|
-
|
|
354
|
-
// Load timber.config.ts
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
|
|
513
|
+
config(userConfig, { command }) {
|
|
514
|
+
// ── Load timber.config.ts from the correct root ───────────────
|
|
515
|
+
// Vite's `config` hook fires before `configResolved`. The user's
|
|
516
|
+
// `root` option (if set) tells us where the project lives.
|
|
517
|
+
// `resolve()` mirrors Vite's own root resolution logic.
|
|
518
|
+
const viteRoot = resolve(userConfig.root ?? process.cwd());
|
|
358
519
|
ctx.timer.start('config-load');
|
|
359
|
-
const fileConfig =
|
|
520
|
+
const fileConfig = loadTimberConfigFile(viteRoot);
|
|
360
521
|
if (fileConfig) {
|
|
361
522
|
mergeFileConfig(ctx, fileConfig);
|
|
362
523
|
ctx.clientJavascript = resolveClientJavascript(ctx.config);
|
|
363
524
|
}
|
|
525
|
+
// Apply defaults AFTER merge so file-based config isn't overridden
|
|
526
|
+
// by defaults that were baked into the inline config object.
|
|
527
|
+
ctx.config.output ??= 'server';
|
|
364
528
|
ctx.timer.end('config-load');
|
|
365
529
|
|
|
366
530
|
// Force production JSX transform for builds.
|
|
@@ -399,17 +563,49 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
399
563
|
}
|
|
400
564
|
},
|
|
401
565
|
};
|
|
566
|
+
|
|
567
|
+
// ── Step 4: Resolve optional plugins ────────────────────────────────
|
|
568
|
+
// React Compiler — controlled by reactCompiler in config (inline or file).
|
|
569
|
+
// If set in inline config, resolve immediately. If it comes from
|
|
570
|
+
// timber.config.ts, it's picked up in rootSync's config hook and
|
|
571
|
+
// resolved lazily via the timber-react-compiler wrapper plugin.
|
|
572
|
+
const reactCompilerPlugins: PluginOption[] = [];
|
|
573
|
+
if (config?.reactCompiler) {
|
|
574
|
+
// Inline config — resolve eagerly (preserves sync throw on missing dep)
|
|
575
|
+
reactCompilerPlugins.push(resolveReactCompilerPlugin(config.reactCompiler, consumerRequire));
|
|
576
|
+
}
|
|
577
|
+
// Lazy wrapper for file-based reactCompiler config (timber.config.ts).
|
|
578
|
+
// After rootSync loads the file config in its `config` hook, this plugin's
|
|
579
|
+
// `configResolved` hook checks if reactCompiler was added by the file and
|
|
580
|
+
// not already resolved from inline config. If so, it resolves and copies
|
|
581
|
+
// the babel plugin's hooks onto itself so Vite invokes them.
|
|
582
|
+
const lazyReactCompiler: Plugin = {
|
|
583
|
+
name: 'timber-react-compiler',
|
|
584
|
+
configResolved() {
|
|
585
|
+
// Skip if already resolved from inline config or not configured
|
|
586
|
+
if (config?.reactCompiler || !ctx.config.reactCompiler) return;
|
|
587
|
+
// File config set reactCompiler — resolve and copy hooks
|
|
588
|
+
const resolved = resolveReactCompilerPlugin(
|
|
589
|
+
ctx.config.reactCompiler,
|
|
590
|
+
consumerRequire
|
|
591
|
+
) as Plugin;
|
|
592
|
+
// Copy transform/resolveId/etc hooks from the babel plugin
|
|
593
|
+
for (const key of Object.keys(resolved) as (keyof Plugin)[]) {
|
|
594
|
+
if (key !== 'name') {
|
|
595
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
596
|
+
(lazyReactCompiler as any)[key] = resolved[key];
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
// ── Step 6: Assemble plugin array ───────────────────────────────────
|
|
402
603
|
// @vitejs/plugin-rsc handles:
|
|
403
604
|
// - RSC/SSR/client environment setup
|
|
404
605
|
// - "use client" directive → client reference proxy transformation
|
|
405
606
|
// - "use server" directive → server reference transformation
|
|
406
607
|
// - Client reference tracking and module map generation
|
|
407
608
|
//
|
|
408
|
-
// Loaded via dynamic import() because @vitejs/plugin-rsc is ESM-only.
|
|
409
|
-
// Vite's config loader uses esbuild to transpile to CJS, which breaks
|
|
410
|
-
// static imports of ESM-only packages. The dynamic import() is preserved
|
|
411
|
-
// by esbuild and runs natively in ESM at runtime.
|
|
412
|
-
//
|
|
413
609
|
// serverHandler: false — timber has its own dev server (timber-dev-server)
|
|
414
610
|
// entries — tells the RSC plugin about timber's virtual entry modules so
|
|
415
611
|
// it correctly wires up the browser entry (needed for React Fast Refresh
|
|
@@ -422,30 +618,6 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
422
618
|
// We do NOT set customBuildApp — the RSC plugin's orchestration is correct
|
|
423
619
|
// and handles bundle ordering, asset manifest generation, and environment
|
|
424
620
|
// imports manifest. See @vitejs/plugin-rsc's buildApp implementation.
|
|
425
|
-
// Resolve @vitejs/plugin-rsc from the consumer's project (process.cwd()),
|
|
426
|
-
// not from timber's own node_modules. This is critical for pnpm link:
|
|
427
|
-
// when linked, timber's node_modules has a separate vite instance, and
|
|
428
|
-
// the RSC plugin must use the same vite instance as the dev server.
|
|
429
|
-
const consumerRequire = createRequire(join(process.cwd(), 'package.json'));
|
|
430
|
-
const rscPluginPath = consumerRequire.resolve('@vitejs/plugin-rsc');
|
|
431
|
-
ctx.timer.start('rsc-plugin-import');
|
|
432
|
-
const rscPluginsPromise = import(pathToFileURL(rscPluginPath).href).then(
|
|
433
|
-
({ default: vitePluginRsc }) => {
|
|
434
|
-
ctx.timer.end('rsc-plugin-import');
|
|
435
|
-
return vitePluginRsc({
|
|
436
|
-
serverHandler: false,
|
|
437
|
-
customClientEntry: true,
|
|
438
|
-
entries: {
|
|
439
|
-
rsc: 'virtual:timber-rsc-entry',
|
|
440
|
-
ssr: 'virtual:timber-ssr-entry',
|
|
441
|
-
client: 'virtual:timber-browser-entry',
|
|
442
|
-
},
|
|
443
|
-
// No custom clientChunks — Rolldown handles natural code splitting.
|
|
444
|
-
// See design/27-chunking-strategy.md and LOCAL-337.
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
);
|
|
448
|
-
|
|
449
621
|
return [
|
|
450
622
|
rootSync,
|
|
451
623
|
timberReactProd(),
|
|
@@ -454,15 +626,16 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
454
626
|
// following Vinext's convention — the RSC plugin's virtual browser entry
|
|
455
627
|
// coordinates with plugin-react via __vite_plugin_react_preamble_installed__.
|
|
456
628
|
react(),
|
|
629
|
+
...reactCompilerPlugins,
|
|
630
|
+
lazyReactCompiler,
|
|
457
631
|
timberServerActionExports(),
|
|
458
|
-
|
|
632
|
+
vitePluginRsc(createRscOptions(ctx, encryptionKeyExpr)),
|
|
459
633
|
timberShims(ctx),
|
|
460
634
|
timberRouting(ctx),
|
|
461
635
|
timberEntries(ctx),
|
|
462
636
|
timberBuildManifest(ctx),
|
|
463
637
|
timberCache(ctx),
|
|
464
638
|
timberStaticBuild(ctx),
|
|
465
|
-
timberDynamicTransform(ctx),
|
|
466
639
|
timberFonts(ctx),
|
|
467
640
|
timberMdx(ctx),
|
|
468
641
|
timberContent(ctx),
|
|
@@ -488,4 +661,26 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
488
661
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
489
662
|
export interface Routes {}
|
|
490
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Type-safe helper for timber.config.ts files.
|
|
666
|
+
*
|
|
667
|
+
* A pass-through identity function that provides autocomplete and
|
|
668
|
+
* type checking for timber configuration. No runtime validation —
|
|
669
|
+
* purely a DX convenience (same pattern as Vite's defineConfig).
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* // timber.config.ts
|
|
674
|
+
* import { defineConfig } from '@timber-js/app';
|
|
675
|
+
*
|
|
676
|
+
* export default defineConfig({
|
|
677
|
+
* output: 'server',
|
|
678
|
+
* pageExtensions: ['tsx', 'ts', 'mdx'],
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
export function defineConfig(config: TimberUserConfig): TimberUserConfig {
|
|
683
|
+
return config;
|
|
684
|
+
}
|
|
685
|
+
|
|
491
686
|
export default timber;
|