@timber-js/app 0.1.51 → 0.1.53
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/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +22 -8
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/client/index.js +248 -22
- 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 +2 -0
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-merger.d.ts +96 -0
- package/dist/client/segment-merger.d.ts.map +1 -0
- package/dist/client/stale-reload.d.ts +44 -0
- package/dist/client/stale-reload.d.ts.map +1 -0
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/server/compress.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/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/package.json +1 -1
- package/src/adapters/compress-module.ts +18 -5
- package/src/adapters/nitro.ts +4 -3
- package/src/client/browser-entry.ts +68 -8
- package/src/client/router.ts +48 -188
- package/src/client/rsc-fetch.ts +234 -0
- package/src/client/segment-cache.ts +2 -0
- package/src/client/segment-merger.ts +297 -0
- package/src/client/stale-reload.ts +89 -0
- package/src/server/compress.ts +23 -4
- package/src/server/route-element-builder.ts +14 -0
- package/src/server/rsc-entry/index.ts +3 -2
- package/src/server/rsc-entry/rsc-payload.ts +8 -1
|
@@ -61,6 +61,13 @@ export interface RouteElementResult {
|
|
|
61
61
|
segments: ManifestSegmentNode[];
|
|
62
62
|
/** Max deferSuspenseFor hold window across all segments. */
|
|
63
63
|
deferSuspenseFor: number;
|
|
64
|
+
/**
|
|
65
|
+
* Segment paths that were skipped because the client already has them cached.
|
|
66
|
+
* Ordered outermost to innermost. Empty when no segments were skipped.
|
|
67
|
+
* The client uses this to merge the partial payload with cached segments.
|
|
68
|
+
* See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
69
|
+
*/
|
|
70
|
+
skippedSegments: string[];
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
/**
|
|
@@ -305,6 +312,10 @@ export async function buildRouteElement(
|
|
|
305
312
|
layoutComponents.map(({ component, segment }) => [segment, component])
|
|
306
313
|
);
|
|
307
314
|
|
|
315
|
+
// Track which segments were skipped for the X-Timber-Skipped-Segments header.
|
|
316
|
+
// The client uses this to merge the partial payload with its cached segments.
|
|
317
|
+
const skippedSegments: string[] = [];
|
|
318
|
+
|
|
308
319
|
// Wrap from innermost (leaf) to outermost (root), processing every
|
|
309
320
|
// segment in the chain. Each segment may contribute:
|
|
310
321
|
// 1. Error boundaries (status files + error.tsx)
|
|
@@ -334,6 +345,8 @@ export async function buildRouteElement(
|
|
|
334
345
|
// Skip this segment entirely — the client uses its cached version.
|
|
335
346
|
// Access.ts already ran in the pre-render loop (security guarantee).
|
|
336
347
|
// Metadata was already resolved above (head elements are correct).
|
|
348
|
+
// Record for X-Timber-Skipped-Segments header (outermost first, so prepend).
|
|
349
|
+
skippedSegments.unshift(segment.urlPath);
|
|
337
350
|
continue;
|
|
338
351
|
}
|
|
339
352
|
|
|
@@ -413,5 +426,6 @@ export async function buildRouteElement(
|
|
|
413
426
|
layoutComponents,
|
|
414
427
|
segments,
|
|
415
428
|
deferSuspenseFor,
|
|
429
|
+
skippedSegments,
|
|
416
430
|
};
|
|
417
431
|
}
|
|
@@ -330,7 +330,7 @@ async function renderRoute(
|
|
|
330
330
|
throw error;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
const { element, headElements, layoutComponents, deferSuspenseFor } = routeResult;
|
|
333
|
+
const { element, headElements, layoutComponents, deferSuspenseFor, skippedSegments } = routeResult;
|
|
334
334
|
|
|
335
335
|
// Build head HTML for injection into the SSR output.
|
|
336
336
|
// Collects CSS, fonts, and modulepreload from the build manifest for matched segments.
|
|
@@ -434,7 +434,8 @@ async function renderRoute(
|
|
|
434
434
|
layoutComponents,
|
|
435
435
|
headElements,
|
|
436
436
|
match,
|
|
437
|
-
responseHeaders
|
|
437
|
+
responseHeaders,
|
|
438
|
+
skippedSegments
|
|
438
439
|
);
|
|
439
440
|
}
|
|
440
441
|
|
|
@@ -41,7 +41,8 @@ export async function buildRscPayloadResponse(
|
|
|
41
41
|
layoutComponents: LayoutComponentEntry[],
|
|
42
42
|
headElements: HeadElement[],
|
|
43
43
|
match: RouteMatch,
|
|
44
|
-
responseHeaders: Headers
|
|
44
|
+
responseHeaders: Headers,
|
|
45
|
+
skippedSegments?: string[]
|
|
45
46
|
): Promise<Response> {
|
|
46
47
|
// Read the first chunk from the RSC stream before committing headers.
|
|
47
48
|
const reader = rscStream.getReader();
|
|
@@ -113,6 +114,12 @@ export async function buildRscPayloadResponse(
|
|
|
113
114
|
const segmentInfo = buildSegmentInfo(segments, layoutComponents);
|
|
114
115
|
responseHeaders.set('X-Timber-Segments', JSON.stringify(segmentInfo));
|
|
115
116
|
|
|
117
|
+
// Send skipped segments so the client can merge the partial RSC payload
|
|
118
|
+
// with its cached segment elements. See design/19-client-navigation.md.
|
|
119
|
+
if (skippedSegments && skippedSegments.length > 0) {
|
|
120
|
+
responseHeaders.set('X-Timber-Skipped-Segments', JSON.stringify(skippedSegments));
|
|
121
|
+
}
|
|
122
|
+
|
|
116
123
|
// Send route params so the client can populate useParams() after
|
|
117
124
|
// SPA navigation. Without this, useParams() returns {}.
|
|
118
125
|
if (Object.keys(match.params).length > 0) {
|