@timber-js/app 0.1.52 → 0.1.54
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/client/index.js +300 -48
- package/dist/client/index.js.map +1 -1
- package/dist/client/router.d.ts +6 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +80 -0
- package/dist/client/rsc-fetch.d.ts.map +1 -0
- package/dist/client/segment-cache.d.ts +8 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-context.d.ts +8 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-merger.d.ts +119 -0
- package/dist/client/segment-merger.d.ts.map +1 -0
- package/dist/server/route-element-builder.d.ts +7 -0
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/state-tree-diff.d.ts +1 -1
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client/browser-entry.ts +7 -0
- package/src/client/router.ts +72 -209
- package/src/client/rsc-fetch.ts +234 -0
- package/src/client/segment-cache.ts +16 -5
- package/src/client/segment-context.ts +8 -1
- package/src/client/segment-merger.ts +345 -0
- package/src/server/route-element-builder.ts +56 -6
- package/src/server/rsc-entry/index.ts +3 -2
- package/src/server/rsc-entry/rsc-payload.ts +8 -1
- package/src/server/state-tree-diff.ts +18 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/client/router.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAoB,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/client/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RSC Fetch — handles fetching and parsing RSC Flight payloads.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from router.ts to keep both files under the 500-line limit.
|
|
5
|
+
* This module handles:
|
|
6
|
+
* - Cache-busting URL generation for RSC requests
|
|
7
|
+
* - Building RSC request headers (Accept, X-Timber-State-Tree)
|
|
8
|
+
* - Extracting metadata from RSC response headers
|
|
9
|
+
* - Fetching and decoding RSC payloads
|
|
10
|
+
*
|
|
11
|
+
* See design/19-client-navigation.md §"RSC Payload Handling"
|
|
12
|
+
*/
|
|
13
|
+
import type { SegmentInfo } from './segment-cache';
|
|
14
|
+
import type { HeadElement } from './head';
|
|
15
|
+
import type { RouterDeps } from './router';
|
|
16
|
+
/** Result of fetching an RSC payload — includes head elements and segment metadata. */
|
|
17
|
+
export interface FetchResult {
|
|
18
|
+
payload: unknown;
|
|
19
|
+
headElements: HeadElement[] | null;
|
|
20
|
+
/** Segment metadata from X-Timber-Segments header for populating the segment cache. */
|
|
21
|
+
segmentInfo: SegmentInfo[] | null;
|
|
22
|
+
/** Route params from X-Timber-Params header for populating useParams(). */
|
|
23
|
+
params: Record<string, string | string[]> | null;
|
|
24
|
+
/** Segment paths that were skipped by the server (for client-side merging). */
|
|
25
|
+
skippedSegments: string[] | null;
|
|
26
|
+
}
|
|
27
|
+
export declare const RSC_CONTENT_TYPE = "text/x-component";
|
|
28
|
+
export declare function buildRscHeaders(stateTree: {
|
|
29
|
+
segments: string[];
|
|
30
|
+
} | undefined, currentUrl?: string): Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Extract head elements from the X-Timber-Head response header.
|
|
33
|
+
* Returns null if the header is missing or malformed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function extractHeadElements(response: Response): HeadElement[] | null;
|
|
36
|
+
/**
|
|
37
|
+
* Extract segment metadata from the X-Timber-Segments response header.
|
|
38
|
+
* Returns null if the header is missing or malformed.
|
|
39
|
+
*
|
|
40
|
+
* Format: JSON array of {path, isAsync} objects describing the rendered
|
|
41
|
+
* segment chain from root to leaf. Used to populate the client-side
|
|
42
|
+
* segment cache for state tree diffing on subsequent navigations.
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractSegmentInfo(response: Response): SegmentInfo[] | null;
|
|
45
|
+
/**
|
|
46
|
+
* Extract skipped segment paths from the X-Timber-Skipped-Segments header.
|
|
47
|
+
* Returns null if the header is missing or malformed.
|
|
48
|
+
*
|
|
49
|
+
* When the server skips sync layouts the client already has cached,
|
|
50
|
+
* it sends this header listing the skipped segment paths (outermost first).
|
|
51
|
+
* The client uses this to merge the partial payload with cached segments.
|
|
52
|
+
*/
|
|
53
|
+
export declare function extractSkippedSegments(response: Response): string[] | null;
|
|
54
|
+
/**
|
|
55
|
+
* Extract route params from the X-Timber-Params response header.
|
|
56
|
+
* Returns null if the header is missing or malformed.
|
|
57
|
+
*
|
|
58
|
+
* Used to populate useParams() after client-side navigation.
|
|
59
|
+
*/
|
|
60
|
+
export declare function extractParams(response: Response): Record<string, string | string[]> | null;
|
|
61
|
+
/**
|
|
62
|
+
* Thrown when an RSC payload response contains X-Timber-Redirect header.
|
|
63
|
+
* Caught in navigate() to trigger a soft router navigation to the redirect target.
|
|
64
|
+
*/
|
|
65
|
+
export declare class RedirectError extends Error {
|
|
66
|
+
readonly redirectUrl: string;
|
|
67
|
+
constructor(url: string);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Fetch an RSC payload from the server. If a decodeRsc function is provided,
|
|
71
|
+
* the response is decoded into a React element tree via createFromFetch.
|
|
72
|
+
* Otherwise, the raw response text is returned (test mode).
|
|
73
|
+
*
|
|
74
|
+
* Also extracts head elements from the X-Timber-Head response header
|
|
75
|
+
* so the client can update document.title and <meta> tags after navigation.
|
|
76
|
+
*/
|
|
77
|
+
export declare function fetchRscPayload(url: string, deps: RouterDeps, stateTree?: {
|
|
78
|
+
segments: string[];
|
|
79
|
+
}, currentUrl?: string): Promise<FetchResult>;
|
|
80
|
+
//# sourceMappingURL=rsc-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsc-fetch.d.ts","sourceRoot":"","sources":["../../src/client/rsc-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,uFAAuF;AACvF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACnC,uFAAuF;IACvF,WAAW,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAClC,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IACjD,+EAA+E;IAC/E,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAClC;AAID,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AA2BnD,wBAAgB,eAAe,CAC7B,SAAS,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,GAAG,IAAI,CAQ5E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,GAAG,IAAI,CAQ3E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,GAAG,IAAI,CAS1E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAQ1F;AAID;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBACjB,GAAG,EAAE,MAAM;CAIxB;AAID;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,EAChB,SAAS,CAAC,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,EAClC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CAuDtB"}
|
|
@@ -7,6 +7,8 @@ export interface PrefetchResult {
|
|
|
7
7
|
segmentInfo?: SegmentInfo[] | null;
|
|
8
8
|
/** Route params from X-Timber-Params header for populating useParams(). */
|
|
9
9
|
params?: Record<string, string | string[]> | null;
|
|
10
|
+
/** Segment paths skipped by the server (for client-side merging). */
|
|
11
|
+
skippedSegments?: string[] | null;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* A node in the client-side segment tree. Each node represents a mounted
|
|
@@ -44,10 +46,15 @@ export declare class SegmentCache {
|
|
|
44
46
|
* Only includes sync segments — async segments are excluded because the
|
|
45
47
|
* server must always re-render them (they may depend on request context).
|
|
46
48
|
*
|
|
49
|
+
* When mergeableFilter is provided, only segments whose paths are in the
|
|
50
|
+
* set are included. This ensures the server only skips segments that the
|
|
51
|
+
* client can actually merge (i.e., segments whose cached element tree
|
|
52
|
+
* contains an inner SegmentProvider the merger can splice into).
|
|
53
|
+
*
|
|
47
54
|
* This is a performance optimization only, NOT a security boundary.
|
|
48
55
|
* The server always runs all access.ts files regardless of the state tree.
|
|
49
56
|
*/
|
|
50
|
-
serializeStateTree(): StateTree;
|
|
57
|
+
serializeStateTree(mergeableFilter?: Set<string>): StateTree;
|
|
51
58
|
}
|
|
52
59
|
/**
|
|
53
60
|
* Segment metadata from the server, sent via X-Timber-Segments header.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segment-cache.d.ts","sourceRoot":"","sources":["../../src/client/segment-cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI1C,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACnC,uFAAuF;IACvF,WAAW,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACnC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"segment-cache.d.ts","sourceRoot":"","sources":["../../src/client/segment-cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI1C,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACnC,uFAAuF;IACvF,WAAW,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACnC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IAClD,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAA0B;IAEtC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAO7C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI;IAM7C,KAAK,IAAI,IAAI;IAIb;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS;CAO7D;AAkBD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,GAAG,SAAS,CA+BjF;AASD;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAU;IACxC,OAAO,CAAC,OAAO,CAAoC;IAEnD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IAO9C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAU5C,0EAA0E;IAC1E,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;CAOjD"}
|
|
@@ -20,6 +20,13 @@ export interface SegmentContextValue {
|
|
|
20
20
|
export declare function useSegmentContext(): SegmentContextValue | null;
|
|
21
21
|
interface SegmentProviderProps {
|
|
22
22
|
segments: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Unique identifier for this segment, used by the client-side segment
|
|
25
|
+
* merger for element caching. For route groups this includes the group
|
|
26
|
+
* name (e.g., "/(marketing)") since groups share their parent's urlPath.
|
|
27
|
+
* Falls back to the reconstructed path from `segments` if not provided.
|
|
28
|
+
*/
|
|
29
|
+
segmentId?: string;
|
|
23
30
|
parallelRouteKeys: string[];
|
|
24
31
|
children: React.ReactNode;
|
|
25
32
|
}
|
|
@@ -27,6 +34,6 @@ interface SegmentProviderProps {
|
|
|
27
34
|
* Wraps each layout to provide segment position context.
|
|
28
35
|
* Injected by rsc-entry.ts during element tree construction.
|
|
29
36
|
*/
|
|
30
|
-
export declare function SegmentProvider({ segments, parallelRouteKeys, children }: SegmentProviderProps): import("react").FunctionComponentElement<import("react").ProviderProps<SegmentContextValue | null>>;
|
|
37
|
+
export declare function SegmentProvider({ segments, segmentId: _segmentId, parallelRouteKeys, children }: SegmentProviderProps): import("react").FunctionComponentElement<import("react").ProviderProps<SegmentContextValue | null>>;
|
|
31
38
|
export {};
|
|
32
39
|
//# sourceMappingURL=segment-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segment-context.d.ts","sourceRoot":"","sources":["../../src/client/segment-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0FAA0F;IAC1F,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAMD,qFAAqF;AACrF,wBAAgB,iBAAiB,IAAI,mBAAmB,GAAG,IAAI,CAE9D;AAID,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"segment-context.d.ts","sourceRoot":"","sources":["../../src/client/segment-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0FAA0F;IAC1F,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAMD,qFAAqF;AACrF,wBAAgB,iBAAiB,IAAI,mBAAmB,GAAG,IAAI,CAE9D;AAID,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,oBAAoB,uGASrH"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Segment Merger — client-side tree merging for partial RSC payloads.
|
|
3
|
+
*
|
|
4
|
+
* When the server skips rendering sync layouts (because the client already
|
|
5
|
+
* has them cached), the RSC payload is missing outer segment wrappers.
|
|
6
|
+
* This module reconstructs the full element tree by splicing the partial
|
|
7
|
+
* payload into cached segment subtrees.
|
|
8
|
+
*
|
|
9
|
+
* The approach:
|
|
10
|
+
* 1. After each full RSC payload render, walk the decoded element tree
|
|
11
|
+
* and cache each segment's subtree (identified by SegmentProvider boundaries)
|
|
12
|
+
* 2. When a partial payload arrives, wrap it with cached segment elements
|
|
13
|
+
* using React.cloneElement to preserve component identity
|
|
14
|
+
*
|
|
15
|
+
* React.cloneElement preserves the element's `type` — React sees the same
|
|
16
|
+
* component at the same tree position and reconciles (preserving state)
|
|
17
|
+
* rather than remounting. This is how layout state survives navigations.
|
|
18
|
+
*
|
|
19
|
+
* Design docs: 19-client-navigation.md §"Navigation Reconciliation"
|
|
20
|
+
* Security: access.ts runs on the server regardless of skipping — this
|
|
21
|
+
* is a performance optimization only. See 13-security.md.
|
|
22
|
+
*/
|
|
23
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
24
|
+
/**
|
|
25
|
+
* A cached segment entry. Stores the full subtree rooted at a SegmentProvider
|
|
26
|
+
* and the path through the tree to the next SegmentProvider (or leaf).
|
|
27
|
+
*/
|
|
28
|
+
export interface CachedSegmentEntry {
|
|
29
|
+
/** The segment's URL path (e.g., "/", "/dashboard") */
|
|
30
|
+
segmentPath: string;
|
|
31
|
+
/** The SegmentProvider element for this segment */
|
|
32
|
+
element: ReactElement;
|
|
33
|
+
/**
|
|
34
|
+
* Whether this segment's cached element contains a nested SegmentProvider.
|
|
35
|
+
* Only segments with inner SegmentProviders are safe to skip — the merger
|
|
36
|
+
* can only replace inner SegmentProviders, not pages embedded in layout output.
|
|
37
|
+
* Used by the state tree serialization to exclude non-mergeable segments.
|
|
38
|
+
*/
|
|
39
|
+
hasMergeableChild: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Cache of React element subtrees per segment path.
|
|
43
|
+
* Updated after each navigation with the full decoded RSC element tree.
|
|
44
|
+
*/
|
|
45
|
+
export declare class SegmentElementCache {
|
|
46
|
+
private entries;
|
|
47
|
+
get(segmentPath: string): CachedSegmentEntry | undefined;
|
|
48
|
+
set(segmentPath: string, entry: CachedSegmentEntry): void;
|
|
49
|
+
has(segmentPath: string): boolean;
|
|
50
|
+
clear(): void;
|
|
51
|
+
get size(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Get the set of segment paths that are safe for the server to skip.
|
|
54
|
+
* Only segments with an inner SegmentProvider (hasMergeableChild) are
|
|
55
|
+
* included — the merger can only replace inner SegmentProviders, not
|
|
56
|
+
* pages embedded in layout output. Used to filter the state tree.
|
|
57
|
+
*
|
|
58
|
+
* Returns an empty set if the element cache is empty (no elements
|
|
59
|
+
* cached yet). This is the safe default — an empty set means no
|
|
60
|
+
* segments pass the filter, so the state tree is empty and the server
|
|
61
|
+
* does a full render. The element cache is populated lazily after the
|
|
62
|
+
* first SPA navigation (RSC-decoded elements from hydration are
|
|
63
|
+
* thenables that can't be walked until React resolves them).
|
|
64
|
+
*/
|
|
65
|
+
getMergeablePaths(): Set<string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a React element is a SegmentProvider by looking for the
|
|
69
|
+
* `segments` prop (an array of path segments). This is the only
|
|
70
|
+
* component that receives this prop shape.
|
|
71
|
+
*/
|
|
72
|
+
export declare function isSegmentProvider(element: unknown): element is ReactElement;
|
|
73
|
+
/**
|
|
74
|
+
* Extract the segment path from a SegmentProvider element.
|
|
75
|
+
*
|
|
76
|
+
* Uses the `segmentId` prop if available (set by the server for route groups
|
|
77
|
+
* to distinguish siblings that share the same urlPath). Falls back to
|
|
78
|
+
* reconstructing from the `segments` array prop.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getSegmentPath(element: ReactElement): string;
|
|
81
|
+
/**
|
|
82
|
+
* Walk a React element tree and extract all SegmentProvider boundaries.
|
|
83
|
+
* Returns an ordered list of segment entries from outermost to innermost.
|
|
84
|
+
*
|
|
85
|
+
* This only finds SegmentProviders along the main children path — it does
|
|
86
|
+
* not descend into parallel routes/slots (those are separate subtrees).
|
|
87
|
+
*/
|
|
88
|
+
export declare function extractSegments(element: unknown): CachedSegmentEntry[];
|
|
89
|
+
/**
|
|
90
|
+
* Cache all segment subtrees from a fully-rendered RSC element tree.
|
|
91
|
+
* Call this after every full RSC payload render (navigate, refresh, hydration).
|
|
92
|
+
*/
|
|
93
|
+
export declare function cacheSegmentElements(element: unknown, cache: SegmentElementCache): void;
|
|
94
|
+
/**
|
|
95
|
+
* Replace a nested SegmentProvider within a cached element tree with
|
|
96
|
+
* new content. Uses cloneElement along the path to produce a new tree
|
|
97
|
+
* with preserved component identity at every level except the replaced node.
|
|
98
|
+
*
|
|
99
|
+
* @param cachedElement The cached SegmentProvider element for this segment
|
|
100
|
+
* @param newInnerContent The new React element to splice in at the inner segment position
|
|
101
|
+
* @param innerSegmentPath The path of the inner segment to replace (optional — replaces first found)
|
|
102
|
+
* @returns New element tree with the inner segment replaced
|
|
103
|
+
*/
|
|
104
|
+
export declare function replaceInnerSegment(cachedElement: ReactElement, newInnerContent: ReactNode, innerSegmentPath?: string): ReactElement;
|
|
105
|
+
/**
|
|
106
|
+
* Merge a partial RSC payload with cached segment elements.
|
|
107
|
+
*
|
|
108
|
+
* When the server skips segments, the partial payload starts from the
|
|
109
|
+
* first non-skipped segment. This function wraps it with cached elements
|
|
110
|
+
* for the skipped segments, producing a full tree that React can
|
|
111
|
+
* reconcile with the mounted tree (preserving layout state).
|
|
112
|
+
*
|
|
113
|
+
* @param partialPayload The RSC payload element (may be partial)
|
|
114
|
+
* @param skippedSegments Ordered list of segment paths that were skipped (outermost first)
|
|
115
|
+
* @param cache The segment element cache
|
|
116
|
+
* @returns The merged full element tree, or the partial payload if merging isn't possible
|
|
117
|
+
*/
|
|
118
|
+
export declare function mergeSegmentTree(partialPayload: unknown, skippedSegments: string[], cache: SegmentElementCache): unknown;
|
|
119
|
+
//# sourceMappingURL=segment-merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-merger.d.ts","sourceRoot":"","sources":["../../src/client/segment-merger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxF;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,OAAO,EAAE,YAAY,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAID;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAyC;IAExD,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIxD,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAIzD,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;;;;OAYG;IACH,iBAAiB,IAAI,GAAG,CAAC,MAAM,CAAC;CASjC;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,YAAY,CAI3E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAM5D;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,EAAE,CAUtE;AAuCD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,mBAAmB,GACzB,IAAI,CAKN;AAqDD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,YAAY,EAC3B,eAAe,EAAE,SAAS,EAC1B,gBAAgB,CAAC,EAAE,MAAM,GACxB,YAAY,CAoCd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,OAAO,EACvB,eAAe,EAAE,MAAM,EAAE,EACzB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CA0BT"}
|
|
@@ -41,6 +41,13 @@ export interface RouteElementResult {
|
|
|
41
41
|
segments: ManifestSegmentNode[];
|
|
42
42
|
/** Max deferSuspenseFor hold window across all segments. */
|
|
43
43
|
deferSuspenseFor: number;
|
|
44
|
+
/**
|
|
45
|
+
* Segment paths that were skipped because the client already has them cached.
|
|
46
|
+
* Ordered outermost to innermost. Empty when no segments were skipped.
|
|
47
|
+
* The client uses this to merge the partial payload with cached segments.
|
|
48
|
+
* See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
49
|
+
*/
|
|
50
|
+
skippedSegments: string[];
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
46
53
|
* Wraps a DenySignal or RedirectSignal with the layout components loaded
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAO7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAKzD,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC;IAC5B,2CAA2C;IAC3C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,wDAAwD;IACxD,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,qCAAqC;IACrC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAO7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAKzD,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC;IAC5B,2CAA2C;IAC3C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,wDAAwD;IACxD,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,qCAAqC;IACrC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,MAAM,EAAE,UAAU,GAAG,cAAc;aACnC,gBAAgB,EAAE,oBAAoB,EAAE;aACxC,QAAQ,EAAE,mBAAmB,EAAE;gBAF/B,MAAM,EAAE,UAAU,GAAG,cAAc,EACnC,gBAAgB,EAAE,oBAAoB,EAAE,EACxC,QAAQ,EAAE,mBAAmB,EAAE;CAIlD;AAID;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,YAAY,CAAC,EAAE,mBAAmB,EAClC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GACnC,OAAO,CAAC,kBAAkB,CAAC,CA2W7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/index.ts"],"names":[],"mappings":"AA0EA;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAE/F;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/index.ts"],"names":[],"mappings":"AA0EA;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAE/F;AAyXD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;8BA7P3C,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;AA+PhD,wBAAiE"}
|
|
@@ -21,5 +21,5 @@ import type { RenderSignals } from './rsc-stream.js';
|
|
|
21
21
|
* initial component tree, allowing onError to capture DenySignal/
|
|
22
22
|
* RedirectSignal before we commit the response. See TIM-344.
|
|
23
23
|
*/
|
|
24
|
-
export declare function buildRscPayloadResponse(req: Request, rscStream: ReadableStream<Uint8Array>, signals: RenderSignals, segments: ManifestSegmentNode[], layoutComponents: LayoutComponentEntry[], headElements: HeadElement[], match: RouteMatch, responseHeaders: Headers): Promise<Response>;
|
|
24
|
+
export declare function buildRscPayloadResponse(req: Request, rscStream: ReadableStream<Uint8Array>, signals: RenderSignals, segments: ManifestSegmentNode[], layoutComponents: LayoutComponentEntry[], headElements: HeadElement[], match: RouteMatch, responseHeaders: Headers, skippedSegments?: string[]): Promise<Response>;
|
|
25
25
|
//# sourceMappingURL=rsc-payload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsc-payload.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAQrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,oBAAoB,EAAE,EACxC,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"rsc-payload.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAQrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,oBAAoB,EAAE,EACxC,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,OAAO,CAAC,QAAQ,CAAC,CAuFnB"}
|
|
@@ -39,5 +39,5 @@ export declare function parseClientStateTree(req: Request): Set<string> | null;
|
|
|
39
39
|
* @param isLeaf - Whether this is the leaf segment (page segment)
|
|
40
40
|
* @param clientSegments - Set of paths from X-Timber-State-Tree, or null
|
|
41
41
|
*/
|
|
42
|
-
export declare function shouldSkipSegment(
|
|
42
|
+
export declare function shouldSkipSegment(urlPath: string, layoutComponent: ((...args: unknown[]) => unknown) | undefined, isLeaf: boolean, clientSegments: Set<string> | null): boolean;
|
|
43
43
|
//# sourceMappingURL=state-tree-diff.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-tree-diff.d.ts","sourceRoot":"","sources":["../../src/server/state-tree-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAarE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,
|
|
1
|
+
{"version":3,"file":"state-tree-diff.d.ts","sourceRoot":"","sources":["../../src/server/state-tree-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAarE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,SAAS,EAC9D,MAAM,EAAE,OAAO,EACf,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GACjC,OAAO,CAeT"}
|
package/package.json
CHANGED
|
@@ -545,6 +545,13 @@ function bootstrap(runtimeConfig: typeof config): void {
|
|
|
545
545
|
delete (self as unknown as Record<string, unknown>).__timber_segments;
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
// NOTE: We do NOT cache segment elements from the initial RSC payload here.
|
|
549
|
+
// The decoded element from createFromReadableStream is a thenable/lazy
|
|
550
|
+
// element that React resolves during render — the segment walker can't
|
|
551
|
+
// traverse it. The element cache is populated lazily after the first SPA
|
|
552
|
+
// navigation (via mergeAndCachePayload in renderViaTransition), when
|
|
553
|
+
// the decoded payload is a fully resolved React element tree.
|
|
554
|
+
|
|
548
555
|
// Note: __timber_params is read before hydrateRoot (see above) so that
|
|
549
556
|
// NavigationProvider has correct values during hydration. If the hydration
|
|
550
557
|
// path was skipped (no RSC payload), populate the fallback here.
|