@timber-js/app 0.2.0-alpha.127 → 0.2.0-alpha.129
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/dist/_chunks/{actions-DX2gkoOZ.js → actions-CdzSSeTh.js} +2 -2
- package/dist/_chunks/{actions-DX2gkoOZ.js.map → actions-CdzSSeTh.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-vdobDWwX.js → cli-schema-sync-CObqjGWF.js} +1 -1
- package/dist/_chunks/{cli-schema-sync-DFHBj6yZ.js → cli-schema-sync-q-Ce6-iG.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-DFHBj6yZ.js.map → cli-schema-sync-q-Ce6-iG.js.map} +1 -1
- package/dist/_chunks/{logger-DDmK5skc.js → logger-CMd9P1xQ.js} +2 -2
- package/dist/_chunks/{logger-DDmK5skc.js.map → logger-CMd9P1xQ.js.map} +1 -1
- package/dist/_chunks/{tracing-DvKLzCFa.js → tracing-DP5djRq5.js} +43 -14
- package/dist/_chunks/tracing-DP5djRq5.js.map +1 -0
- package/dist/_chunks/{walkers-E5ss0qES.js → walkers-BbEu2_Pp.js} +2 -2
- package/dist/_chunks/{walkers-E5ss0qES.js.map → walkers-BbEu2_Pp.js.map} +1 -1
- package/dist/_chunks/{warnings-B30wpfaS.js → warnings-CAzunaGo.js} +2 -2
- package/dist/_chunks/{warnings-B30wpfaS.js.map → warnings-CAzunaGo.js.map} +1 -1
- package/dist/cache/index.js +2 -2
- package/dist/cli.js +1 -1
- package/dist/index.js +21 -7
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/server/als-registry.d.ts +17 -6
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +1 -1
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +4 -4
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +121 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +1 -72
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +15 -0
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/plugins/fonts.ts +9 -1
- package/src/plugins/routing.ts +15 -2
- package/src/server/als-registry.ts +53 -13
- package/src/server/deny-renderer.ts +2 -2
- package/src/server/rsc-entry/error-renderer.ts +14 -4
- package/src/server/rsc-entry/ssr-bridge.ts +5 -1
- package/src/server/rsc-entry/ssr-renderer.ts +25 -21
- package/src/server/ssr-bridge-types.ts +124 -0
- package/src/server/ssr-entry.ts +9 -77
- package/src/server/ssr-render.ts +40 -4
- package/dist/_chunks/tracing-DvKLzCFa.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0B1D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAElF;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0B1D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAElF;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAsLtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/plugins/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAoBlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/plugins/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAoBlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAwG1D,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAuNxD"}
|
package/dist/routing/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { i as INTERCEPTION_MARKERS, n as classifyUrlSegment, r as DEFAULT_PAGE_EXTENSIONS, t as classifySegment } from "../_chunks/segment-classify-BjfuctV2.js";
|
|
2
|
-
import { m as scanRoutes } from "../_chunks/cli-schema-sync-
|
|
3
|
-
import { a as generateRouteMap, i as collectInterceptionRewrites, n as collectDynamicSegmentsFromTree, r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "../_chunks/walkers-
|
|
2
|
+
import { m as scanRoutes } from "../_chunks/cli-schema-sync-q-Ce6-iG.js";
|
|
3
|
+
import { a as generateRouteMap, i as collectInterceptionRewrites, n as collectDynamicSegmentsFromTree, r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "../_chunks/walkers-BbEu2_Pp.js";
|
|
4
4
|
export { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS, classifySegment, classifyUrlSegment, collectDynamicSegmentsFromTree, collectInterceptionRewrites, collectLeafRoutes, generateRouteMap, scanRoutes, validateSchemaAgainstRoutes };
|
|
@@ -6,18 +6,29 @@
|
|
|
6
6
|
* this registry and re-export public accessor functions.
|
|
7
7
|
*
|
|
8
8
|
* Why: ALS instances require singleton semantics — if two copies of the
|
|
9
|
-
* same ALS exist (one from a relative import, one from a barrel import
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* same ALS exist (one from a relative import, one from a barrel import,
|
|
10
|
+
* or the same file re-evaluated by Vite after an HMR invalidation), one
|
|
11
|
+
* module writes to its copy and another reads from an empty copy.
|
|
12
|
+
* Centralizing ALS creation in a single module + anchoring each instance
|
|
13
|
+
* on `globalThis` under a `Symbol.for(...)` key eliminates this class of
|
|
14
|
+
* bug, including the Vite-dev case where module instance split would
|
|
15
|
+
* otherwise hand two copies of this file out of a single evaluation cycle.
|
|
12
16
|
*
|
|
13
|
-
* The `timber-shims` plugin
|
|
14
|
-
*
|
|
17
|
+
* The `timber-shims` plugin remaps `@timber-js/app/server` to src/ in
|
|
18
|
+
* RSC and SSR environments so import-specifier paths converge here, and
|
|
19
|
+
* the `globalThis[SYMBOL_FOR]` anchor below closes the remaining gap: any
|
|
20
|
+
* second evaluation of this module picks up the ALS the first evaluation
|
|
21
|
+
* already stored rather than instantiating a fresh one. Same pattern the
|
|
22
|
+
* Cloudflare bindings ALS uses in `adapters/cloudflare.ts`.
|
|
15
23
|
*
|
|
16
24
|
* DO NOT create ALS instances outside this file. If you need a new ALS,
|
|
17
25
|
* add it here and import from `./als-registry.js` in the consuming module.
|
|
26
|
+
* Inside this file, always route through `getOrCreateAls(symbol)` — a raw
|
|
27
|
+
* `new AsyncLocalStorage()` reintroduces the instance-split hazard.
|
|
18
28
|
*
|
|
19
29
|
* See design/18-build-system.md §"Module Singleton Strategy" and
|
|
20
|
-
* §"Singleton State Registry".
|
|
30
|
+
* §"Singleton State Registry". Regression test:
|
|
31
|
+
* `tests/als-registry-singleton.test.ts`.
|
|
21
32
|
*/
|
|
22
33
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
23
34
|
import type { DebugComponentEntry } from './rsc-entry/helpers.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"als-registry.d.ts","sourceRoot":"","sources":["../../src/server/als-registry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"als-registry.d.ts","sourceRoot":"","sources":["../../src/server/als-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AA2BlE,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,wCAE7B,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,uEAAuE;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,YAAY,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/D,wFAAwF;IACxF,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,4DAA4D;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,cAAc,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,mBAAmB,EAAE,CAAC;CACrD;AAED,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;CACtD;AAMD,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,mDAAmD;AACnD,eAAO,MAAM,QAAQ,+BAA6D,CAAC;AAMnF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;CACrD;AAED,yDAAyD;AACzD,eAAO,MAAM,SAAS,gCAA+D,CAAC;AAMtF,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,mDAAmD;AACnD,eAAO,MAAM,eAAe,sCAE3B,CAAC;AAMF,sDAAsD;AACtD,eAAO,MAAM,YAAY,4DAExB,CAAC;AAMF,4EAA4E;AAC5E,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE3D,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,uCAE/B,CAAC;AAMF,6EAA6E;AAC7E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AAE9D,4DAA4D;AAC5D,eAAO,MAAM,YAAY,gCAAmE,CAAC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { DenySignal } from './primitives.js';
|
|
18
18
|
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
19
19
|
import type { RouteMatch } from './pipeline.js';
|
|
20
|
-
import type { NavContext } from './ssr-
|
|
20
|
+
import type { NavContext } from './ssr-bridge-types.js';
|
|
21
21
|
import type { ClientBootstrapConfig } from './html-injectors.js';
|
|
22
22
|
/** Layout component entry for deny page wrapping. */
|
|
23
23
|
export interface LayoutEntry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deny-renderer.d.ts","sourceRoot":"","sources":["../../src/server/deny-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"deny-renderer.d.ts","sourceRoot":"","sources":["../../src/server/deny-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAOjE,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,iEAAiE;AACjE,MAAM,MAAM,mBAAmB,GAAG,MAAM;IACtC,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,SAAS,GAAG,CACtB,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,KACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;AAUvB;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,WAAW,EAAE,EAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,EACtC,sBAAsB,EAAE,mBAAmB,EAC3C,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,QAAQ,CAAC,CAiGnB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,WAAW,EAAE,EAC/B,eAAe,EAAE,OAAO,EACxB,sBAAsB,EAAE,mBAAmB,GAC1C,OAAO,CAAC,QAAQ,CAAC,CA2CnB"}
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-
|
|
1
|
+
import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-DP5djRq5.js";
|
|
2
2
|
import { t as formatSize } from "../_chunks/format-BjN9HLu9.js";
|
|
3
|
-
import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, o as coerce, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-
|
|
3
|
+
import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, o as coerce, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-CdzSSeTh.js";
|
|
4
4
|
//#region src/server/sensitive-fields.ts
|
|
5
5
|
/**
|
|
6
6
|
* Sensitive field stripping — removes password/token/CVV-style fields
|
package/dist/server/internal.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as replaceTraceId, d as withSpan, f as earlyHintsSenderAls, g as timingAls, i as getOtelTraceId, l as runWithTraceId, m as requestContextAls, o as getTraceId, r as generateTraceId, u as setSpanAttribute, v as isDebug } from "../_chunks/tracing-
|
|
2
|
-
import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as warnRedirectInAccess, n as setViteServer, o as warnSlowSlotWithoutSuspense, r as warnDenyInSuspense, s as warnStaticRequestApi, t as WarningId } from "../_chunks/warnings-
|
|
1
|
+
import { c as replaceTraceId, d as withSpan, f as earlyHintsSenderAls, g as timingAls, i as getOtelTraceId, l as runWithTraceId, m as requestContextAls, o as getTraceId, r as generateTraceId, u as setSpanAttribute, v as isDebug } from "../_chunks/tracing-DP5djRq5.js";
|
|
2
|
+
import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as warnRedirectInAccess, n as setViteServer, o as warnSlowSlotWithoutSuspense, r as warnDenyInSuspense, s as warnStaticRequestApi, t as WarningId } from "../_chunks/warnings-CAzunaGo.js";
|
|
3
3
|
import { i as getMetadataRouteServePath, n as classifyMetadataRoute, r as getMetadataRouteAutoLink, t as METADATA_ROUTE_CONVENTIONS } from "../_chunks/metadata-routes-DESG8uk5.js";
|
|
4
4
|
import { n as classifyUrlSegment } from "../_chunks/segment-classify-BjfuctV2.js";
|
|
5
|
-
import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-
|
|
6
|
-
import { C as setMatchedSegmentPath, E as getCookie, O as getSetCookieHeaders, S as runWithRequestContext, T as setSegmentParams, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setMutableCookieContext, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-
|
|
5
|
+
import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-CMd9P1xQ.js";
|
|
6
|
+
import { C as setMatchedSegmentPath, E as getCookie, O as getSetCookieHeaders, S as runWithRequestContext, T as setSegmentParams, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setMutableCookieContext, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-CdzSSeTh.js";
|
|
7
7
|
import "../client/error-boundary.js";
|
|
8
8
|
import { n as toBracketKey } from "../_chunks/resolve-schema-DU2nbVOi.js";
|
|
9
9
|
import "../_chunks/segment-context-Bg0pFbLT.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/error-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAYvD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqHD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,WAAW,EAAE,EAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,EACtC,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAwCnB;AAqID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,mBAAmB,EAChC,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,GACrC,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"error-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/error-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAYvD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqHD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,WAAW,EAAE,EAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,EACtC,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAwCnB;AAqID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,mBAAmB,EAChC,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,GACrC,OAAO,CAAC,QAAQ,CAAC,CAuCnB"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SSR Bridge — loads the SSR entry and passes the RSC stream for HTML rendering.
|
|
3
|
+
*
|
|
4
|
+
* This is the RSC → SSR environment hop. The two environments are separate
|
|
5
|
+
* Vite module graphs; `NavContext` is the serializable contract that crosses
|
|
6
|
+
* the boundary. See `../ssr-bridge-types.ts` for the contract definition.
|
|
3
7
|
*/
|
|
4
|
-
import type { NavContext } from '../ssr-
|
|
8
|
+
import type { NavContext } from '../ssr-bridge-types.js';
|
|
5
9
|
export declare function callSsr(rscStream: ReadableStream<Uint8Array>, navContext: NavContext): Promise<Response>;
|
|
6
10
|
//# sourceMappingURL=ssr-bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-bridge.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-bridge.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ssr-bridge.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,wBAAsB,OAAO,CAC3B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,QAAQ,CAAC,CAenB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAW/D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAarD;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,CAAC;AAEhF,UAAU,gBAAgB;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAW/D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAarD;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,CAAC;AAEhF,UAAU,gBAAgB;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqSjF"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RSC ↔ SSR Bridge Contract
|
|
3
|
+
*
|
|
4
|
+
* This file defines the payload that crosses the RSC → SSR environment
|
|
5
|
+
* boundary. The RSC environment calls `handleSsr(rscStream, navContext)`
|
|
6
|
+
* in the SSR environment via `import.meta.viteRsc.import(...)` (see
|
|
7
|
+
* `rsc-entry/ssr-bridge.ts`). RSC and SSR are separate Vite module graphs
|
|
8
|
+
* with separate module instances, so every per-request field that SSR
|
|
9
|
+
* needs must be declared here and passed explicitly.
|
|
10
|
+
*
|
|
11
|
+
* Rules for changes to this file:
|
|
12
|
+
*
|
|
13
|
+
* 1. **Structurally serializable shape.** Fields must be values that can
|
|
14
|
+
* cross the environment boundary as plain data or as platform-neutral
|
|
15
|
+
* primitives (`Headers`, `ReadableStream`, `AbortSignal`, `Map`). Do
|
|
16
|
+
* not add closures, class instances tied to RSC-only modules, or
|
|
17
|
+
* anything whose identity must be preserved across the bridge.
|
|
18
|
+
*
|
|
19
|
+
* 2. **No runtime imports of RSC-only modules.** This file is read by
|
|
20
|
+
* both environments at type-check time. Keep it type-only. Importing
|
|
21
|
+
* an RSC-only runtime module here couples SSR to RSC internals.
|
|
22
|
+
*
|
|
23
|
+
* 3. **Shape changes are public-surface changes.** Adding, removing, or
|
|
24
|
+
* renaming a field is a change to the contract between two
|
|
25
|
+
* independently-built bundles. Update every caller in the same PR —
|
|
26
|
+
* do not rely on back-compat shims.
|
|
27
|
+
*
|
|
28
|
+
* See `design/02-rendering-pipeline.md` §"RSC → SSR → Client Hydration"
|
|
29
|
+
* and `CLAUDE.md` §"RSC and SSR Are Separate Vite Environments".
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Navigation context passed from the RSC environment to SSR.
|
|
33
|
+
*
|
|
34
|
+
* Per-request state must be explicitly passed across the RSC→SSR
|
|
35
|
+
* environment boundary since they are separate Vite module graphs.
|
|
36
|
+
*/
|
|
37
|
+
export interface NavContext {
|
|
38
|
+
/** The requested pathname */
|
|
39
|
+
pathname: string;
|
|
40
|
+
/** Extracted route segment params (catch-all segments produce string[]) */
|
|
41
|
+
segmentParams: Record<string, string | string[]>;
|
|
42
|
+
/** Search params from the URL */
|
|
43
|
+
searchParams: Record<string, string>;
|
|
44
|
+
/** The committed HTTP status code */
|
|
45
|
+
statusCode: number;
|
|
46
|
+
/** Response headers from middleware/proxy */
|
|
47
|
+
responseHeaders: Headers;
|
|
48
|
+
/** Pre-rendered metadata HTML to inject before </head> */
|
|
49
|
+
headHtml: string;
|
|
50
|
+
/** Inline JS for React's bootstrapScriptContent — kicks off module loading */
|
|
51
|
+
bootstrapScriptContent: string;
|
|
52
|
+
/** Tee'd RSC stream for client-side hydration (inlined into HTML) */
|
|
53
|
+
rscStream?: ReadableStream<Uint8Array>;
|
|
54
|
+
/** Max Suspense hold window (ms). SSR delays the first flush by this
|
|
55
|
+
* duration, racing allReady so that fast-resolving boundaries render inline
|
|
56
|
+
* without ever showing a fallback. Derived from route `deferSuspenseFor` exports.
|
|
57
|
+
* See design/05-streaming.md §"deferSuspenseFor". */
|
|
58
|
+
deferSuspenseFor?: number;
|
|
59
|
+
/** Request abort signal. When the client disconnects (page refresh,
|
|
60
|
+
* navigation away), this signal fires. Passed to renderToReadableStream
|
|
61
|
+
* so React stops rendering and doesn't fire error boundaries for aborts. */
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
/** Request cookies as name→value pairs. Used by useCookie() during SSR
|
|
64
|
+
* to return correct cookie values before hydration. */
|
|
65
|
+
cookies?: Map<string, string>;
|
|
66
|
+
/**
|
|
67
|
+
* Mutable flag: set by TimberErrorBoundary during SSR when it catches
|
|
68
|
+
* a DenySignal (via digest). This tells the RSC entry that the denial
|
|
69
|
+
* was contained by a slot error boundary and should NOT be promoted
|
|
70
|
+
* to a page-level deny. See LOCAL-298.
|
|
71
|
+
*/
|
|
72
|
+
_denyHandledByBoundary?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Mutable: SSR timing data populated by handleSsr().
|
|
75
|
+
* Read by the RSC entry to record sub-phase Server-Timing entries
|
|
76
|
+
* when `serverTiming: 'detailed'` is configured.
|
|
77
|
+
*
|
|
78
|
+
* This bridges the RSC→SSR environment boundary: the SSR entry populates
|
|
79
|
+
* these fields, the RSC entry reads them after callSsr() returns.
|
|
80
|
+
*/
|
|
81
|
+
_ssrTimings?: {
|
|
82
|
+
/** Time to decode RSC stream (createFromReadableStream/createFromNodeStream) */
|
|
83
|
+
decodeMs: number;
|
|
84
|
+
/** Time for Fizz to render the shell (onShellReady) */
|
|
85
|
+
shellMs: number;
|
|
86
|
+
/** Time for pipe() to flush shell bytes to the output stream */
|
|
87
|
+
pipeMs: number;
|
|
88
|
+
/** Time to set up Node.js Transform pipeline / Web Stream transforms */
|
|
89
|
+
pipelineMs: number;
|
|
90
|
+
/** Total SSR time (decode → response ready) */
|
|
91
|
+
totalMs: number;
|
|
92
|
+
/** Whether the Node.js native stream path was used */
|
|
93
|
+
nodeStreams: boolean;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Signal that fires when an unhandled RSC error is detected.
|
|
97
|
+
* The Flight injector checks this before writing each script tag —
|
|
98
|
+
* when aborted, it stops injecting Flight data to prevent corrupted
|
|
99
|
+
* chunks from crashing the client's Flight decoder.
|
|
100
|
+
*/
|
|
101
|
+
_errorSignal?: AbortSignal;
|
|
102
|
+
/**
|
|
103
|
+
* Mutable flag: set by the SSR entry when Fizz's `stream.allReady`
|
|
104
|
+
* settled before the `deferSuspenseFor` hold ended.
|
|
105
|
+
*
|
|
106
|
+
* When true, the RSC entry can skip its signal-promotion
|
|
107
|
+
* microtask-retry wait: Fizz allReady implies Flight closed its
|
|
108
|
+
* stream, which implies `onError` already fired for every rejected
|
|
109
|
+
* Flight task. Any DenySignal/RedirectSignal/RenderError in-tree has
|
|
110
|
+
* already been captured in `RenderSignals`.
|
|
111
|
+
*
|
|
112
|
+
* When false or undefined (hold timed out, no hold window, shell-only
|
|
113
|
+
* return, Node error path), no such guarantee — the RSC entry falls
|
|
114
|
+
* back to the bounded microtask retry loop.
|
|
115
|
+
*
|
|
116
|
+
* See design/05-streaming.md §"deferSuspenseFor and the Hold Window"
|
|
117
|
+
* and design/spike-signal-promotion-protocol.md (Option 1).
|
|
118
|
+
*/
|
|
119
|
+
_fizzAllReadyResolved?: boolean;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=ssr-bridge-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-bridge-types.d.ts","sourceRoot":"","sources":["../../src/server/ssr-bridge-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IACjD,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC;;;0DAGsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;iFAE6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4DACwD;IACxD,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE;QACZ,gFAAgF;QAChF,QAAQ,EAAE,MAAM,CAAC;QACjB,uDAAuD;QACvD,OAAO,EAAE,MAAM,CAAC;QAChB,gEAAgE;QAChE,MAAM,EAAE,MAAM,CAAC;QACf,wEAAwE;QACxE,UAAU,EAAE,MAAM,CAAC;QACnB,+CAA+C;QAC/C,OAAO,EAAE,MAAM,CAAC;QAChB,sDAAsD;QACtD,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IAEF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAE3B;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC"}
|
|
@@ -12,78 +12,7 @@
|
|
|
12
12
|
* Design docs: 18-build-system.md §"Entry Files", 02-rendering-pipeline.md
|
|
13
13
|
*/
|
|
14
14
|
import 'virtual:timber-search-params-registry';
|
|
15
|
-
|
|
16
|
-
* Navigation context passed from the RSC environment to SSR.
|
|
17
|
-
*
|
|
18
|
-
* Per-request state must be explicitly passed across the RSC→SSR
|
|
19
|
-
* environment boundary since they are separate Vite module graphs.
|
|
20
|
-
*/
|
|
21
|
-
export interface NavContext {
|
|
22
|
-
/** The requested pathname */
|
|
23
|
-
pathname: string;
|
|
24
|
-
/** Extracted route params (catch-all segments produce string[]) */
|
|
25
|
-
params: Record<string, string | string[]>;
|
|
26
|
-
/** Search params from the URL */
|
|
27
|
-
searchParams: Record<string, string>;
|
|
28
|
-
/** The committed HTTP status code */
|
|
29
|
-
statusCode: number;
|
|
30
|
-
/** Response headers from middleware/proxy */
|
|
31
|
-
responseHeaders: Headers;
|
|
32
|
-
/** Pre-rendered metadata HTML to inject before </head> */
|
|
33
|
-
headHtml: string;
|
|
34
|
-
/** Inline JS for React's bootstrapScriptContent — kicks off module loading */
|
|
35
|
-
bootstrapScriptContent: string;
|
|
36
|
-
/** Tee'd RSC stream for client-side hydration (inlined into HTML) */
|
|
37
|
-
rscStream?: ReadableStream<Uint8Array>;
|
|
38
|
-
/** Max Suspense hold window (ms). SSR delays the first flush by this
|
|
39
|
-
* duration, racing allReady so that fast-resolving boundaries render inline
|
|
40
|
-
* without ever showing a fallback. Derived from route `deferSuspenseFor` exports.
|
|
41
|
-
* See design/05-streaming.md §"deferSuspenseFor". */
|
|
42
|
-
deferSuspenseFor?: number;
|
|
43
|
-
/** Request abort signal. When the client disconnects (page refresh,
|
|
44
|
-
* navigation away), this signal fires. Passed to renderToReadableStream
|
|
45
|
-
* so React stops rendering and doesn't fire error boundaries for aborts. */
|
|
46
|
-
signal?: AbortSignal;
|
|
47
|
-
/** Request cookies as name→value pairs. Used by useCookie() during SSR
|
|
48
|
-
* to return correct cookie values before hydration. */
|
|
49
|
-
cookies?: Map<string, string>;
|
|
50
|
-
/**
|
|
51
|
-
* Mutable flag: set by TimberErrorBoundary during SSR when it catches
|
|
52
|
-
* a DenySignal (via digest). This tells the RSC entry that the denial
|
|
53
|
-
* was contained by a slot error boundary and should NOT be promoted
|
|
54
|
-
* to a page-level deny. See LOCAL-298.
|
|
55
|
-
*/
|
|
56
|
-
_denyHandledByBoundary?: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Mutable: SSR timing data populated by handleSsr().
|
|
59
|
-
* Read by the RSC entry to record sub-phase Server-Timing entries
|
|
60
|
-
* when `serverTiming: 'detailed'` is configured.
|
|
61
|
-
*
|
|
62
|
-
* This bridges the RSC→SSR environment boundary: the SSR entry populates
|
|
63
|
-
* these fields, the RSC entry reads them after callSsr() returns.
|
|
64
|
-
*/
|
|
65
|
-
_ssrTimings?: {
|
|
66
|
-
/** Time to decode RSC stream (createFromReadableStream/createFromNodeStream) */
|
|
67
|
-
decodeMs: number;
|
|
68
|
-
/** Time for Fizz to render the shell (onShellReady) */
|
|
69
|
-
shellMs: number;
|
|
70
|
-
/** Time for pipe() to flush shell bytes to the output stream */
|
|
71
|
-
pipeMs: number;
|
|
72
|
-
/** Time to set up Node.js Transform pipeline / Web Stream transforms */
|
|
73
|
-
pipelineMs: number;
|
|
74
|
-
/** Total SSR time (decode → response ready) */
|
|
75
|
-
totalMs: number;
|
|
76
|
-
/** Whether the Node.js native stream path was used */
|
|
77
|
-
nodeStreams: boolean;
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Signal that fires when an unhandled RSC error is detected.
|
|
81
|
-
* The Flight injector checks this before writing each script tag —
|
|
82
|
-
* when aborted, it stops injecting Flight data to prevent corrupted
|
|
83
|
-
* chunks from crashing the client's Flight decoder.
|
|
84
|
-
*/
|
|
85
|
-
_errorSignal?: AbortSignal;
|
|
86
|
-
}
|
|
15
|
+
import type { NavContext } from './ssr-bridge-types.js';
|
|
87
16
|
/**
|
|
88
17
|
* Handle SSR: decode an RSC stream and render it to hydration-ready HTML.
|
|
89
18
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,uCAAuC,CAAC;AA4B/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAsDxD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,QAAQ,CAAC,CAmMnB;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -39,6 +39,14 @@ export declare function renderSsrStream(element: ReactNode, options?: {
|
|
|
39
39
|
deferSuspenseFor?: number;
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
renderTimeoutMs?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Fired synchronously when the render function is about to resolve
|
|
44
|
+
* (i.e. at hold-end / shell-ready). `resolved` reports whether Fizz's
|
|
45
|
+
* `stream.allReady` had already settled by that moment. Callers use
|
|
46
|
+
* this to decide whether signal promotion can be short-circuited.
|
|
47
|
+
* See NavContext._fizzAllReadyResolved.
|
|
48
|
+
*/
|
|
49
|
+
onFizzAllReadyResolved?: (resolved: boolean) => void;
|
|
42
50
|
}): Promise<ReadableStream<Uint8Array>>;
|
|
43
51
|
/** Whether the current platform uses native Node.js streams for SSR. */
|
|
44
52
|
export declare const useNodeStreams: boolean;
|
|
@@ -54,6 +62,13 @@ export declare function renderSsrNodeStream(element: ReactNode, options?: {
|
|
|
54
62
|
deferSuspenseFor?: number;
|
|
55
63
|
signal?: AbortSignal;
|
|
56
64
|
renderTimeoutMs?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Fired synchronously at the moment `renderSsrNodeStream`'s returned
|
|
67
|
+
* Promise is about to resolve. `resolved` reports whether Fizz's
|
|
68
|
+
* `onAllReady` had already fired by then. See the twin callback on
|
|
69
|
+
* `renderSsrStream`.
|
|
70
|
+
*/
|
|
71
|
+
onFizzAllReadyResolved?: (resolved: boolean) => void;
|
|
57
72
|
}): Promise<import('node:stream').Readable>;
|
|
58
73
|
/** Convert a Node.js Readable to a Web ReadableStream (zero-copy bridge). */
|
|
59
74
|
export declare function nodeReadableToWeb(readable: import('node:stream').Readable): ReadableStream<Uint8Array>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAuFvC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAuFvC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD,GACA,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAErC;AAED,wEAAwE;AACxE,eAAO,MAAM,cAAc,SAAkB,CAAC;AAU9C;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD,GACA,OAAO,CAAC,OAAO,aAAa,EAAE,QAAQ,CAAC,CAgGzC;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,aAAa,EAAE,QAAQ,GACvC,cAAc,CAAC,UAAU,CAAC,CAE5B;AAqGD;;;;;;;;;;;;GAYG;AACH,2CAA2C;AAC3C,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,UAAU,CAAC,CA2B5B;AAWD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,OAAO,GACvB,QAAQ,CASV"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timber-js/app",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.129",
|
|
4
4
|
"description": "Vite-native React framework built for Servers and Serverless Platforms — correct HTTP semantics, real status codes, pages that work without JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare-workers",
|
package/src/plugins/fonts.ts
CHANGED
|
@@ -98,6 +98,7 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
98
98
|
resolveId(id: string) {
|
|
99
99
|
let cleanId = id.startsWith('\0') ? id.slice(1) : id;
|
|
100
100
|
const qIdx = cleanId.indexOf('?');
|
|
101
|
+
const query = qIdx !== -1 ? cleanId.slice(qIdx) : '';
|
|
101
102
|
if (qIdx !== -1) cleanId = cleanId.slice(0, qIdx);
|
|
102
103
|
if (cleanId.startsWith(ctx.root)) {
|
|
103
104
|
const stripped = cleanId.slice(ctx.root.length);
|
|
@@ -110,7 +111,14 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
110
111
|
|
|
111
112
|
if (cleanId === VIRTUAL_GOOGLE) return RESOLVED_GOOGLE;
|
|
112
113
|
if (cleanId === VIRTUAL_LOCAL) return RESOLVED_LOCAL;
|
|
113
|
-
|
|
114
|
+
// Preserve query suffix (notably `?direct`) on the resolved CSS id.
|
|
115
|
+
// Vite's transform middleware appends `?direct` when the browser
|
|
116
|
+
// fetches the URL as a `<link rel="stylesheet">`, and the CSS plugin
|
|
117
|
+
// only skips its JS-wrapping step when `isDirectCSSRequest(id)` sees
|
|
118
|
+
// that query on the resolved id. Dropping it here caused virtual
|
|
119
|
+
// font CSS to be served as Vite's HMR JS shim, leaving the
|
|
120
|
+
// `<link>`-loaded stylesheet empty (TIM-937 follow-up).
|
|
121
|
+
if (pipeline.cssIdMap.matches(cleanId)) return '\0' + cleanId + query;
|
|
114
122
|
return null;
|
|
115
123
|
},
|
|
116
124
|
|
package/src/plugins/routing.ts
CHANGED
|
@@ -84,12 +84,25 @@ const CODEGEN_OUTPUT = '.timber/timber-routes.d.ts';
|
|
|
84
84
|
* Uses a triple-slash reference so TypeScript auto-discovers the generated
|
|
85
85
|
* route map without the user needing to edit tsconfig.json — same pattern
|
|
86
86
|
* as Next.js's next-env.d.ts.
|
|
87
|
+
*
|
|
88
|
+
* Also references `vite/client` so side-effect imports like
|
|
89
|
+
* `import './globals.css'` type-check without ts(2882), and so
|
|
90
|
+
* `import.meta.env`, `import.meta.hot`, `import.meta.glob`, asset
|
|
91
|
+
* imports (`*.png`, `*.svg`, …), CSS modules, and `?url`/`?raw`/
|
|
92
|
+
* `?inline` query variants all resolve without the user editing
|
|
93
|
+
* tsconfig.json themselves. Next.js's next-env.d.ts plays the same
|
|
94
|
+
* role via `next/types/global`.
|
|
95
|
+
*
|
|
96
|
+
* `vite` is a peer dep of `@timber-js/app`, so the reference always
|
|
97
|
+
* resolves in a correctly-installed project.
|
|
87
98
|
*/
|
|
88
99
|
const TIMBER_ENV_DTS = [
|
|
89
100
|
'// This file is auto-generated by timber.js. Do not edit.',
|
|
90
|
-
'// It ensures TypeScript picks up the generated route types
|
|
91
|
-
'//
|
|
101
|
+
'// It ensures TypeScript picks up the generated route types and',
|
|
102
|
+
'// Vite-provided ambient types (CSS, assets, import.meta.env, HMR).',
|
|
103
|
+
'/* eslint-disable @typescript-eslint/triple-slash-reference */',
|
|
92
104
|
'/// <reference path=".timber/timber-routes.d.ts" />',
|
|
105
|
+
'/// <reference types="vite/client" />',
|
|
93
106
|
'',
|
|
94
107
|
].join('\n');
|
|
95
108
|
|
|
@@ -6,29 +6,63 @@
|
|
|
6
6
|
* this registry and re-export public accessor functions.
|
|
7
7
|
*
|
|
8
8
|
* Why: ALS instances require singleton semantics — if two copies of the
|
|
9
|
-
* same ALS exist (one from a relative import, one from a barrel import
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* same ALS exist (one from a relative import, one from a barrel import,
|
|
10
|
+
* or the same file re-evaluated by Vite after an HMR invalidation), one
|
|
11
|
+
* module writes to its copy and another reads from an empty copy.
|
|
12
|
+
* Centralizing ALS creation in a single module + anchoring each instance
|
|
13
|
+
* on `globalThis` under a `Symbol.for(...)` key eliminates this class of
|
|
14
|
+
* bug, including the Vite-dev case where module instance split would
|
|
15
|
+
* otherwise hand two copies of this file out of a single evaluation cycle.
|
|
12
16
|
*
|
|
13
|
-
* The `timber-shims` plugin
|
|
14
|
-
*
|
|
17
|
+
* The `timber-shims` plugin remaps `@timber-js/app/server` to src/ in
|
|
18
|
+
* RSC and SSR environments so import-specifier paths converge here, and
|
|
19
|
+
* the `globalThis[SYMBOL_FOR]` anchor below closes the remaining gap: any
|
|
20
|
+
* second evaluation of this module picks up the ALS the first evaluation
|
|
21
|
+
* already stored rather than instantiating a fresh one. Same pattern the
|
|
22
|
+
* Cloudflare bindings ALS uses in `adapters/cloudflare.ts`.
|
|
15
23
|
*
|
|
16
24
|
* DO NOT create ALS instances outside this file. If you need a new ALS,
|
|
17
25
|
* add it here and import from `./als-registry.js` in the consuming module.
|
|
26
|
+
* Inside this file, always route through `getOrCreateAls(symbol)` — a raw
|
|
27
|
+
* `new AsyncLocalStorage()` reintroduces the instance-split hazard.
|
|
18
28
|
*
|
|
19
29
|
* See design/18-build-system.md §"Module Singleton Strategy" and
|
|
20
|
-
* §"Singleton State Registry".
|
|
30
|
+
* §"Singleton State Registry". Regression test:
|
|
31
|
+
* `tests/als-registry-singleton.test.ts`.
|
|
21
32
|
*/
|
|
22
33
|
|
|
23
34
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
24
35
|
import type { DebugComponentEntry } from './rsc-entry/helpers.js';
|
|
25
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Return a process-wide singleton `AsyncLocalStorage` keyed by `symbol`.
|
|
39
|
+
*
|
|
40
|
+
* `Symbol.for(...)` keys live in the cross-realm symbol registry, and
|
|
41
|
+
* `globalThis` is shared across every module evaluation inside the same
|
|
42
|
+
* Node.js process. Together they give a stable anchor that survives
|
|
43
|
+
* re-evaluation of this file — the second evaluation observes the
|
|
44
|
+
* `globalThis[symbol]` slot already populated by the first and hands
|
|
45
|
+
* back the identical ALS instance.
|
|
46
|
+
*/
|
|
47
|
+
function getOrCreateAls<T>(symbol: symbol): AsyncLocalStorage<T> {
|
|
48
|
+
const g = globalThis as unknown as Record<symbol, unknown>;
|
|
49
|
+
const existing = g[symbol];
|
|
50
|
+
if (existing instanceof AsyncLocalStorage) {
|
|
51
|
+
return existing as AsyncLocalStorage<T>;
|
|
52
|
+
}
|
|
53
|
+
const created = new AsyncLocalStorage<T>();
|
|
54
|
+
g[symbol] = created;
|
|
55
|
+
return created;
|
|
56
|
+
}
|
|
57
|
+
|
|
26
58
|
// ─── Request Context ──────────────────────────────────────────────────────
|
|
27
59
|
// Used by: request-context.ts (getHeaders(), getCookies(), getSearchParams())
|
|
28
60
|
// Design doc: design/04-authorization.md
|
|
29
61
|
|
|
30
62
|
/** @internal — import via request-context.ts public API */
|
|
31
|
-
export const requestContextAls =
|
|
63
|
+
export const requestContextAls = getOrCreateAls<RequestContextStore>(
|
|
64
|
+
Symbol.for('timber:request-context-als')
|
|
65
|
+
);
|
|
32
66
|
|
|
33
67
|
export interface RequestContextStore {
|
|
34
68
|
/** Incoming request headers (read-only view). */
|
|
@@ -119,7 +153,7 @@ export interface TraceStore {
|
|
|
119
153
|
}
|
|
120
154
|
|
|
121
155
|
/** @internal — import via tracing.ts public API */
|
|
122
|
-
export const traceAls =
|
|
156
|
+
export const traceAls = getOrCreateAls<TraceStore>(Symbol.for('timber:trace-als'));
|
|
123
157
|
|
|
124
158
|
// ─── Server-Timing ────────────────────────────────────────────────────────
|
|
125
159
|
// Used by: server-timing.ts (recordTiming(), withTiming())
|
|
@@ -130,7 +164,7 @@ export interface TimingStore {
|
|
|
130
164
|
}
|
|
131
165
|
|
|
132
166
|
/** @internal — import via server-timing.ts public API */
|
|
133
|
-
export const timingAls =
|
|
167
|
+
export const timingAls = getOrCreateAls<TimingStore>(Symbol.for('timber:timing-als'));
|
|
134
168
|
|
|
135
169
|
// ─── Revalidation ─────────────────────────────────────────────────────────
|
|
136
170
|
// Used by: actions.ts (revalidatePath(), revalidateTag())
|
|
@@ -144,14 +178,18 @@ export interface RevalidationState {
|
|
|
144
178
|
}
|
|
145
179
|
|
|
146
180
|
/** @internal — import via actions.ts public API */
|
|
147
|
-
export const revalidationAls =
|
|
181
|
+
export const revalidationAls = getOrCreateAls<RevalidationState>(
|
|
182
|
+
Symbol.for('timber:revalidation-als')
|
|
183
|
+
);
|
|
148
184
|
|
|
149
185
|
// ─── Form Flash ───────────────────────────────────────────────────────────
|
|
150
186
|
// Used by: form-flash.ts (getFormFlash())
|
|
151
187
|
// Design doc: design/08-forms-and-actions.md §"No-JS Error Round-Trip"
|
|
152
188
|
|
|
153
189
|
/** @internal — import via form-flash.ts public API */
|
|
154
|
-
export const formFlashAls =
|
|
190
|
+
export const formFlashAls = getOrCreateAls<import('./form-flash.js').FormFlashData>(
|
|
191
|
+
Symbol.for('timber:form-flash-als')
|
|
192
|
+
);
|
|
155
193
|
|
|
156
194
|
// ─── Early Hints Sender ──────────────────────────────────────────────────
|
|
157
195
|
// Used by: early-hints-sender.ts (sendEarlyHints103())
|
|
@@ -161,7 +199,9 @@ export const formFlashAls = new AsyncLocalStorage<import('./form-flash.js').Form
|
|
|
161
199
|
export type EarlyHintsSenderFn = (links: string[]) => void;
|
|
162
200
|
|
|
163
201
|
/** @internal — import via early-hints-sender.ts public API */
|
|
164
|
-
export const earlyHintsSenderAls =
|
|
202
|
+
export const earlyHintsSenderAls = getOrCreateAls<EarlyHintsSenderFn>(
|
|
203
|
+
Symbol.for('timber:early-hints-sender-als')
|
|
204
|
+
);
|
|
165
205
|
|
|
166
206
|
// ─── waitUntil Bridge ────────────────────────────────────────────────────
|
|
167
207
|
// Used by: waituntil-bridge.ts (waitUntil())
|
|
@@ -171,4 +211,4 @@ export const earlyHintsSenderAls = new AsyncLocalStorage<EarlyHintsSenderFn>();
|
|
|
171
211
|
export type WaitUntilFn = (promise: Promise<unknown>) => void;
|
|
172
212
|
|
|
173
213
|
/** @internal — import via waituntil-bridge.ts public API */
|
|
174
|
-
export const waitUntilAls =
|
|
214
|
+
export const waitUntilAls = getOrCreateAls<WaitUntilFn>(Symbol.for('timber:wait-until-als'));
|
|
@@ -27,7 +27,7 @@ import { resolveMetadata, renderMetadataToElements } from './metadata.js';
|
|
|
27
27
|
import { resolveStatusFile } from './status-code-resolver.js';
|
|
28
28
|
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
29
29
|
import type { RouteMatch } from './pipeline.js';
|
|
30
|
-
import type { NavContext } from './ssr-
|
|
30
|
+
import type { NavContext } from './ssr-bridge-types.js';
|
|
31
31
|
import { flightInitScript } from './flight-scripts.js';
|
|
32
32
|
import type { ClientBootstrapConfig } from './html-injectors.js';
|
|
33
33
|
import type { Metadata } from './types.js';
|
|
@@ -166,7 +166,7 @@ export async function renderDenyPage(
|
|
|
166
166
|
|
|
167
167
|
const navContext: NavContext = {
|
|
168
168
|
pathname: new URL(req.url).pathname,
|
|
169
|
-
|
|
169
|
+
segmentParams: match.segmentParams,
|
|
170
170
|
searchParams: Object.fromEntries(new URL(req.url).searchParams),
|
|
171
171
|
statusCode: deny.status,
|
|
172
172
|
responseHeaders,
|