@timber-js/app 0.2.0-alpha.160 → 0.2.0-alpha.163
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-C9yAuoX3.js → actions-cjklt63G.js} +7 -4
- package/dist/_chunks/{actions-C9yAuoX3.js.map → actions-cjklt63G.js.map} +1 -1
- package/dist/_chunks/{cache-api-swbefQ6F.js → cache-api-CzYUlgXA.js} +2 -2
- package/dist/_chunks/{cache-api-swbefQ6F.js.map → cache-api-CzYUlgXA.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-BhYDz_-x.js → cli-schema-sync-NfLbLnDw.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-BhYDz_-x.js.map → cli-schema-sync-NfLbLnDw.js.map} +1 -1
- package/dist/_chunks/{logger-CPoQkGK6.js → logger-B_O6-mdJ.js} +7 -45
- package/dist/_chunks/logger-B_O6-mdJ.js.map +1 -0
- package/dist/_chunks/{walkers-c8aReVgo.js → walkers-9mz9T7mb.js} +2 -2
- package/dist/_chunks/{walkers-c8aReVgo.js.map → walkers-9mz9T7mb.js.map} +1 -1
- package/dist/adapters/cloudflare.d.ts +13 -13
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +44 -46
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +1 -8
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/types.d.ts +0 -6
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/child-segment-context.d.ts +22 -0
- package/dist/client/child-segment-context.d.ts.map +1 -0
- package/dist/client/child-segment-outlet.d.ts +18 -0
- package/dist/client/child-segment-outlet.d.ts.map +1 -0
- package/dist/client/child-segment-provider.d.ts +21 -0
- package/dist/client/child-segment-provider.d.ts.map +1 -0
- package/dist/client/internal.js +1 -2
- package/dist/client/internal.js.map +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +5 -1
- package/dist/cookies/index.js.map +1 -1
- package/dist/index.js +256 -9
- package/dist/index.js.map +1 -1
- package/dist/plugins/cache.d.ts.map +1 -1
- package/dist/plugins/callsite-ast.d.ts +27 -5
- package/dist/plugins/callsite-ast.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +1 -0
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +85 -10
- package/dist/server/internal.js.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +5 -12
- package/dist/server/primitives.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/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +2 -2
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/state-tree-diff.d.ts +26 -3
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/adapters/cloudflare.ts +41 -63
- package/src/adapters/nitro.ts +0 -11
- package/src/adapters/types.ts +0 -7
- package/src/client/child-segment-context.ts +40 -0
- package/src/client/child-segment-outlet.tsx +25 -0
- package/src/client/child-segment-provider.tsx +27 -0
- package/src/client/segment-cache.ts +4 -5
- package/src/client/use-cookie.ts +11 -1
- package/src/plugins/cache.ts +44 -1
- package/src/plugins/callsite-ast.ts +310 -5
- package/src/plugins/fonts.ts +8 -0
- package/src/plugins/prebuilt-capture.ts +7 -0
- package/src/plugins/shims.ts +24 -0
- package/src/server/actions.ts +10 -1
- package/src/server/als-registry.ts +1 -0
- package/src/server/index.ts +1 -1
- package/src/server/prebuilt-builder.ts +120 -42
- package/src/server/prebuilt-runtime.ts +24 -1
- package/src/server/primitives.ts +5 -20
- package/src/server/route-element-builder.ts +113 -79
- package/src/server/rsc-entry/helpers.ts +12 -10
- package/src/server/rsc-entry/index.ts +40 -40
- package/src/server/rsc-entry/render-route.ts +6 -2
- package/src/server/rsc-entry/rsc-payload.ts +2 -2
- package/src/server/server-only-guard-noop.js +3 -0
- package/src/server/state-tree-diff.ts +49 -4
- package/dist/_chunks/logger-CPoQkGK6.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prebuilt-builder.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;
|
|
1
|
+
{"version":3,"file":"prebuilt-builder.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAuBH,OAAO,KAAK,EAAgB,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAO1F,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,mEAAmE;IACnE,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D;;;;OAIG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAyUD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAqSzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prebuilt-runtime.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;
|
|
1
|
+
{"version":3,"file":"prebuilt-runtime.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAmCH;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGlE;AAID;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IACjE,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED,2DAA2D;AAE3D,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC;AAY/C,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,wBAAwB,CAAC;CACnC;AA8ED,UAAU,YAAY;IACpB,wBAAwB,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnF,sBAAsB,EAAE,CACtB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;KAAE,KAC/C,cAAc,CAAC,UAAU,CAAC,CAAC;CACjC;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAEvD;AAmCD,eAAO,MAAM,mBAAmB,aAAoB,CAAC;AA2YrD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,eAAe,EAClD,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,CAAC,EACZ,OAAO,GAAE,wBAA6B,GACrC,CAAC,CAyCH;AAED,qDAAqD;AACrD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAEpF;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE/E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,eAAe,EACrD,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,EACZ,QAAQ,CAAC,EAAE,wBAAwB,GAClC,CAAC,CAYH"}
|
|
@@ -168,25 +168,18 @@ export declare class RenderError<TCode extends string = string, TData extends Js
|
|
|
168
168
|
status?: number;
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
/** Minimal interface for adapters that support background work. */
|
|
172
|
-
export interface WaitUntilAdapter {
|
|
173
|
-
waitUntil?(promise: Promise<unknown>): void;
|
|
174
|
-
}
|
|
175
171
|
/**
|
|
176
172
|
* Register a promise to be kept alive after the response is sent.
|
|
177
173
|
* Maps to `ctx.waitUntil()` on Cloudflare Workers and similar platforms.
|
|
178
174
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* If neither is available, a warning is logged once and the promise is
|
|
184
|
-
* left to resolve (or reject) without being tracked.
|
|
175
|
+
* The platform adapter installs a per-request waitUntil function via ALS
|
|
176
|
+
* (see waituntil-bridge.ts). If no ALS handler is available, a warning
|
|
177
|
+
* is logged once and the promise is left to resolve (or reject) without
|
|
178
|
+
* being tracked.
|
|
185
179
|
*
|
|
186
180
|
* @param promise - The background work to keep alive.
|
|
187
|
-
* @param adapter - Optional legacy adapter (prefer ALS bridge in production).
|
|
188
181
|
*/
|
|
189
|
-
export declare function waitUntil(promise: Promise<unknown
|
|
182
|
+
export declare function waitUntil(promise: Promise<unknown>): void;
|
|
190
183
|
/**
|
|
191
184
|
* Reset the waitUntil warning state. Exported for testing only.
|
|
192
185
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/server/primitives.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/server/primitives.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,6 +44,13 @@ export declare function isClientReference(component: unknown): boolean;
|
|
|
44
44
|
export declare class ParamCoercionError extends Error {
|
|
45
45
|
constructor(message: string);
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Thrown when a matched route has no page component in its leaf segment.
|
|
49
|
+
* The pipeline catches this and renders the custom 404 page.
|
|
50
|
+
*/
|
|
51
|
+
export declare class NoPageComponentError extends Error {
|
|
52
|
+
constructor(message: string);
|
|
53
|
+
}
|
|
47
54
|
/** Layout entry with component and segment. */
|
|
48
55
|
export interface LayoutComponentEntry {
|
|
49
56
|
component: (...args: unknown[]) => unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA4B9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,YAAY,CAW/E;AAwCD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAM7D;AAID;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAID,+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,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;AA8DD;;;;;;;;;;;;;;;GAeG;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,EACpC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,kBAAkB,CAAC,CA0gB7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CAQ/F;AAID;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,yDAAyD;IACzD,gBAAgB,IAAI,MAAM,CAAC;IAC3B,yEAAyE;IACzE,aAAa,IAAI,mBAAmB,EAAE,CAAC;CACxC;AAED,wBAAgB,2BAA2B,IAAI,qBAAqB,CAkCnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CA8ClE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,KAAK,CAAC;IACtB,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;CAC9B,CAAC,GACD,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA+B/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGzD;AAMD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -24,11 +24,11 @@ export { runWithWorkersCachePurge } from '../workers-cache-bridge.js';
|
|
|
24
24
|
* See design/44-render-at-build-time.md §Build Phase.
|
|
25
25
|
*/
|
|
26
26
|
export declare function __timber_capturePrebuilt(options: import('../prebuilt-builder.js').CaptureOptions): Promise<import('../prebuilt-builder.js').CaptureSummary>;
|
|
27
|
-
declare const _handler: (req: Request) => Promise<Response>;
|
|
28
27
|
/**
|
|
29
28
|
* The pipeline configuration object. Exported so the dev server can set
|
|
30
29
|
* `devPipelineErrorHandler` after import without a module-level singleton.
|
|
31
30
|
*/
|
|
32
31
|
export declare const pipelineConfig: PipelineConfig;
|
|
33
|
-
|
|
32
|
+
declare const _default: (req: Request) => Promise<Response>;
|
|
33
|
+
export default _default;
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/index.ts"],"names":[],"mappings":"AAuBA,OAAO,uCAAuC,CAAC;AAuB/C,OAAO,KAAK,EAAuB,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAuCtF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAE5E;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/index.ts"],"names":[],"mappings":"AAuBA,OAAO,uCAAuC,CAAC;AAuB/C,OAAO,KAAK,EAAuB,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAuCtF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAE5E;AAoZD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAInE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,wBAAwB,EAAE,cAAc,GACvD,OAAO,CAAC,OAAO,wBAAwB,EAAE,cAAc,CAAC,CAE1D;AAyCD;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAmB,CAAC;8BAb1B,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC;AAelD,wBAAyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-route.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/render-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAW1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"render-route.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/render-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAW1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAa/D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,mBAAmB,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,IAAI,EAAE,eAAe,EACrB,YAAY,CAAC,EAAE,mBAAmB,GACjC,OAAO,CAAC,QAAQ,CAAC,CA+MnB"}
|
|
@@ -13,6 +13,28 @@
|
|
|
13
13
|
* See design/19-client-navigation.md §"X-Timber-State-Tree Header"
|
|
14
14
|
* See design/13-security.md §"State tree manipulation"
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* Segment node shape expected by computeSegmentKeys.
|
|
18
|
+
* Matches the relevant fields from ManifestSegmentNode without
|
|
19
|
+
* importing it (avoids circular deps from routing → server).
|
|
20
|
+
*/
|
|
21
|
+
interface SegmentKeyInput {
|
|
22
|
+
urlPath: string;
|
|
23
|
+
segmentName?: string;
|
|
24
|
+
segmentType?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Compute state-tree keys for a segment chain.
|
|
28
|
+
*
|
|
29
|
+
* Non-group segments use their urlPath as-is. Route groups accumulate
|
|
30
|
+
* ancestor group names to produce globally unique keys:
|
|
31
|
+
* app/(a)/(shared)/dashboard → keys: ['/', '/(a)', '/(a)/(shared)', '/dashboard']
|
|
32
|
+
*
|
|
33
|
+
* This is the single source of truth for segment keys — used by the
|
|
34
|
+
* element builder (skip decisions, SegmentOutlet props), segment info
|
|
35
|
+
* (X-Timber-Segments header), and the client cache/state tree.
|
|
36
|
+
*/
|
|
37
|
+
export declare function computeSegmentKeys(segments: SegmentKeyInput[]): string[];
|
|
16
38
|
/**
|
|
17
39
|
* Parse the X-Timber-State-Tree header from a request.
|
|
18
40
|
*
|
|
@@ -36,15 +58,16 @@ export declare function parseClientStateTree(req: Request): Set<string> | null;
|
|
|
36
58
|
*
|
|
37
59
|
* Additional constraints enforced by the caller (buildRouteElement):
|
|
38
60
|
* - Must have a rendered layout below (so SegmentOutlet has content to show)
|
|
39
|
-
* -
|
|
61
|
+
* - Skipped segments must form a contiguous prefix from root
|
|
40
62
|
*
|
|
41
63
|
* Access.ts still runs for skipped segments — this is enforced by the caller
|
|
42
64
|
* which wraps with AccessGate regardless of skip status.
|
|
43
65
|
*
|
|
44
|
-
* @param
|
|
66
|
+
* @param segmentKey - The segment's state-tree key from computeSegmentKeys()
|
|
45
67
|
* @param layoutComponent - The loaded layout component function
|
|
46
68
|
* @param isLeaf - Whether this is the leaf segment (page segment)
|
|
47
69
|
* @param clientSegments - Set of paths from X-Timber-State-Tree, or null
|
|
48
70
|
*/
|
|
49
|
-
export declare function shouldSkipSegment(
|
|
71
|
+
export declare function shouldSkipSegment(segmentKey: string, layoutComponent: ((...args: unknown[]) => unknown) | undefined, isLeaf: boolean, clientSegments: Set<string> | null): boolean;
|
|
72
|
+
export {};
|
|
50
73
|
//# 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;
|
|
1
|
+
{"version":3,"file":"state-tree-diff.d.ts","sourceRoot":"","sources":["../../src/server/state-tree-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;GAIG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAiBxE;AAID;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAcrE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,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,CAYT"}
|
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.163",
|
|
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",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"#routing": {
|
|
46
46
|
"types": "./dist/routing/index.d.ts",
|
|
47
47
|
"default": "./dist/routing/index.js"
|
|
48
|
-
}
|
|
48
|
+
},
|
|
49
|
+
"#server-only-guard": "./src/server/server-only-guard-noop.js"
|
|
49
50
|
},
|
|
50
51
|
"exports": {
|
|
51
52
|
".": {
|
|
@@ -228,11 +228,7 @@ export function cloudflare(options: CloudflareAdapterOptions = {}): TimberPlatfo
|
|
|
228
228
|
async buildOutput(config: TimberConfig, buildDir: string) {
|
|
229
229
|
const outDir = join(buildDir, 'cloudflare');
|
|
230
230
|
|
|
231
|
-
// Clean stale prebuilt artifacts
|
|
232
|
-
// The shared step uses cp (merge, not replace), so old .flight files
|
|
233
|
-
// from removed/renamed components would persist and get picked up by
|
|
234
|
-
// find_additional_modules. Also clean static/prebuilt/ from pre-TIM-1162
|
|
235
|
-
// builds where prebuilt was copied into static assets.
|
|
231
|
+
// Clean stale prebuilt artifacts from prior builds.
|
|
236
232
|
await rm(join(outDir, 'prebuilt'), { recursive: true, force: true }).catch(() => {});
|
|
237
233
|
await rm(join(outDir, 'static', 'prebuilt'), { recursive: true, force: true }).catch(
|
|
238
234
|
() => {}
|
|
@@ -273,17 +269,16 @@ export function cloudflare(options: CloudflareAdapterOptions = {}): TimberPlatfo
|
|
|
273
269
|
hasWorkerHandlers = true;
|
|
274
270
|
}
|
|
275
271
|
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
// manifest.json publicly fetchable, bypassing middleware and access
|
|
280
|
-
// gates. Now payloads are imported as native wrangler Data/Text modules
|
|
281
|
-
// from outDir/prebuilt/ (outside static/), keeping them server-side only.
|
|
272
|
+
// Inline prebuilt flight payloads into the worker JS module (TIM-1162).
|
|
273
|
+
// Data is read from buildDir/prebuilt/ and embedded as literals —
|
|
274
|
+
// no external Text/Data module imports needed.
|
|
282
275
|
const prebuiltData = await readPrebuiltData(buildDir);
|
|
283
276
|
await writeFile(
|
|
284
277
|
join(outDir, '_timber-prebuilt-source.js'),
|
|
285
278
|
generatePrebuiltSourceModule(prebuiltData)
|
|
286
279
|
);
|
|
280
|
+
// Remove the copied prebuilt/ dir — data is inlined, files aren't needed.
|
|
281
|
+
await rm(join(outDir, 'prebuilt'), { recursive: true, force: true }).catch(() => {});
|
|
287
282
|
|
|
288
283
|
// Write the runtime init module — sets process.env.TIMBER_RUNTIME
|
|
289
284
|
// BEFORE the RSC entry evaluates (ESM import order). Without this,
|
|
@@ -446,26 +441,29 @@ ${handlersSpread} async fetch(request, env, ctx) {
|
|
|
446
441
|
`;
|
|
447
442
|
}
|
|
448
443
|
|
|
449
|
-
/** Build-time prebuilt
|
|
444
|
+
/** Build-time prebuilt data read from `.timber/dist/prebuilt/`. */
|
|
450
445
|
export interface PrebuiltModuleData {
|
|
451
|
-
/**
|
|
452
|
-
|
|
446
|
+
/** Raw manifest.json content. */
|
|
447
|
+
manifestJson: string;
|
|
448
|
+
/** Payload file paths and their raw bytes. */
|
|
449
|
+
payloads: Array<{ file: string; bytes: Buffer }>;
|
|
453
450
|
}
|
|
454
451
|
|
|
455
452
|
/**
|
|
456
|
-
* Discover prebuilt flight payload files from the build directory.
|
|
453
|
+
* Discover and read prebuilt flight payload files from the build directory.
|
|
457
454
|
* Returns null when no prebuilt artifacts exist (no cache.component usage).
|
|
458
455
|
*
|
|
459
456
|
* @internal Exported for testing.
|
|
460
457
|
*/
|
|
461
458
|
export async function readPrebuiltData(buildDir: string): Promise<PrebuiltModuleData | null> {
|
|
462
459
|
const prebuiltDir = join(buildDir, 'prebuilt');
|
|
460
|
+
let manifestJson: string;
|
|
463
461
|
try {
|
|
464
|
-
await readFile(join(prebuiltDir, 'manifest.json'));
|
|
462
|
+
manifestJson = await readFile(join(prebuiltDir, 'manifest.json'), 'utf-8');
|
|
465
463
|
} catch {
|
|
466
464
|
return null;
|
|
467
465
|
}
|
|
468
|
-
const
|
|
466
|
+
const payloads: PrebuiltModuleData['payloads'] = [];
|
|
469
467
|
try {
|
|
470
468
|
const componentDirs = await readdir(prebuiltDir, { withFileTypes: true });
|
|
471
469
|
for (const dir of componentDirs) {
|
|
@@ -473,28 +471,25 @@ export async function readPrebuiltData(buildDir: string): Promise<PrebuiltModule
|
|
|
473
471
|
const files = await readdir(join(prebuiltDir, dir.name));
|
|
474
472
|
for (const file of files) {
|
|
475
473
|
if (file.endsWith('.flight')) {
|
|
476
|
-
|
|
474
|
+
const filePath = `${dir.name}/${file}`;
|
|
475
|
+
const bytes = await readFile(join(prebuiltDir, filePath));
|
|
476
|
+
payloads.push({ file: filePath, bytes });
|
|
477
477
|
}
|
|
478
478
|
}
|
|
479
479
|
}
|
|
480
480
|
} catch {
|
|
481
481
|
// No subdirectories — manifest exists but no payloads
|
|
482
482
|
}
|
|
483
|
-
return {
|
|
483
|
+
return { manifestJson, payloads };
|
|
484
484
|
}
|
|
485
485
|
|
|
486
486
|
/**
|
|
487
487
|
* Generate the prebuilt payload source module for Cloudflare Workers.
|
|
488
488
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
* `find_additional_modules: true` with Data/Text rules.
|
|
494
|
-
*
|
|
495
|
-
* This is a separate ESM module so it evaluates before the RSC handler —
|
|
496
|
-
* static imports are hoisted, guaranteeing `globalThis.__TIMBER_PREBUILT_SOURCE__`
|
|
497
|
-
* is set before `createRequestHandler()` reads it.
|
|
489
|
+
* Inlines manifest JSON and flight payload bytes directly into the module
|
|
490
|
+
* so they're part of the worker's JS bundle — no external Text/Data module
|
|
491
|
+
* imports needed. This avoids depending on wrangler's find_additional_modules
|
|
492
|
+
* to discover non-JS files, which doesn't reliably resolve Text/Data imports.
|
|
498
493
|
*
|
|
499
494
|
* @internal Exported for testing.
|
|
500
495
|
*/
|
|
@@ -509,24 +504,23 @@ globalThis.__TIMBER_PREBUILT_SOURCE__ = {
|
|
|
509
504
|
`;
|
|
510
505
|
}
|
|
511
506
|
|
|
512
|
-
const imports: string[] = [];
|
|
513
507
|
const entries: string[] = [];
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
for (let i = 0; i < data.payloadFiles.length; i++) {
|
|
518
|
-
const file = data.payloadFiles[i];
|
|
519
|
-
imports.push(`import _p${i} from './prebuilt/${file}'`);
|
|
520
|
-
entries.push(` ${JSON.stringify(file)}: new Uint8Array(_p${i})`);
|
|
508
|
+
for (const { file, bytes } of data.payloads) {
|
|
509
|
+
const b64 = bytes.toString('base64');
|
|
510
|
+
entries.push(` ${JSON.stringify(file)}: ${JSON.stringify(b64)}`);
|
|
521
511
|
}
|
|
522
512
|
|
|
523
513
|
return `// Generated by @timber-js/app/adapters/cloudflare
|
|
524
|
-
// Prebuilt payload source —
|
|
525
|
-
//
|
|
526
|
-
|
|
527
|
-
${imports.join('\n')}
|
|
514
|
+
// Prebuilt payload source — inlines cache.component flight payloads
|
|
515
|
+
// directly into the worker bundle (TIM-1162).
|
|
516
|
+
const _manifest = ${data.manifestJson.trim()}
|
|
528
517
|
|
|
529
|
-
|
|
518
|
+
function _decode(b64) {
|
|
519
|
+
const bin = atob(b64)
|
|
520
|
+
const buf = new Uint8Array(bin.length)
|
|
521
|
+
for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i)
|
|
522
|
+
return buf
|
|
523
|
+
}
|
|
530
524
|
|
|
531
525
|
const _payloads = {
|
|
532
526
|
${entries.join(',\n')}
|
|
@@ -534,7 +528,10 @@ ${entries.join(',\n')}
|
|
|
534
528
|
|
|
535
529
|
globalThis.__TIMBER_PREBUILT_SOURCE__ = {
|
|
536
530
|
async loadManifest() { return _manifest },
|
|
537
|
-
async readPayload(file) {
|
|
531
|
+
async readPayload(file) {
|
|
532
|
+
const b64 = _payloads[file]
|
|
533
|
+
return b64 ? _decode(b64) : null
|
|
534
|
+
},
|
|
538
535
|
}
|
|
539
536
|
`;
|
|
540
537
|
}
|
|
@@ -694,11 +691,6 @@ export function generateWranglerConfig(
|
|
|
694
691
|
|
|
695
692
|
const flags = options.compatibilityFlags ?? ['nodejs_compat'];
|
|
696
693
|
|
|
697
|
-
const PREBUILT_MODULE_RULES = [
|
|
698
|
-
{ type: 'Text' as const, globs: ['prebuilt/**/*.json'] },
|
|
699
|
-
{ type: 'Data' as const, globs: ['prebuilt/**/*.flight'] },
|
|
700
|
-
];
|
|
701
|
-
|
|
702
694
|
const base: Record<string, unknown> = {
|
|
703
695
|
name: 'timber-app',
|
|
704
696
|
main: '_worker.js',
|
|
@@ -708,7 +700,7 @@ export function generateWranglerConfig(
|
|
|
708
700
|
// esbuild pass to avoid issues with top-level await and module format.
|
|
709
701
|
no_bundle: true,
|
|
710
702
|
find_additional_modules: true,
|
|
711
|
-
rules: [{ type: 'ESModule', globs: ['**/*.js'] }
|
|
703
|
+
rules: [{ type: 'ESModule', globs: ['**/*.js'] }],
|
|
712
704
|
assets: {
|
|
713
705
|
directory: './static',
|
|
714
706
|
binding: 'ASSETS',
|
|
@@ -733,21 +725,7 @@ export function generateWranglerConfig(
|
|
|
733
725
|
// durable_objects.bindings. Deep merge preserves generated keys while
|
|
734
726
|
// letting wrangler override on actual key-level conflicts.
|
|
735
727
|
if (options.wrangler) {
|
|
736
|
-
|
|
737
|
-
// Ensure required prebuilt module rules survive a user `rules` override.
|
|
738
|
-
// Without this, `wrangler: { rules: [...] }` replaces the entire array
|
|
739
|
-
// and drops the Text/Data rules that _timber-prebuilt-source.js needs.
|
|
740
|
-
if (options.wrangler.rules) {
|
|
741
|
-
const userRules = result.rules as Array<Record<string, unknown>>;
|
|
742
|
-
for (const required of PREBUILT_MODULE_RULES) {
|
|
743
|
-
const exists = userRules.some(
|
|
744
|
-
(r) =>
|
|
745
|
-
r.type === required.type && JSON.stringify(r.globs) === JSON.stringify(required.globs)
|
|
746
|
-
);
|
|
747
|
-
if (!exists) userRules.push(required);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
return result;
|
|
728
|
+
return shallowDeepMerge(merged, options.wrangler);
|
|
751
729
|
}
|
|
752
730
|
|
|
753
731
|
return merged;
|
package/src/adapters/nitro.ts
CHANGED
|
@@ -180,8 +180,6 @@ export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter
|
|
|
180
180
|
const preset = options.preset ?? 'node-server';
|
|
181
181
|
const compress = options.compress ?? true;
|
|
182
182
|
const presetConfig = PRESET_CONFIGS[preset];
|
|
183
|
-
const pendingPromises: Promise<unknown>[] = [];
|
|
184
|
-
|
|
185
183
|
return {
|
|
186
184
|
name: `nitro-${preset}`,
|
|
187
185
|
|
|
@@ -238,15 +236,6 @@ export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter
|
|
|
238
236
|
await spawnNitroPreview(command, [scriptPath], join(buildDir, 'nitro'));
|
|
239
237
|
}
|
|
240
238
|
: undefined,
|
|
241
|
-
|
|
242
|
-
waitUntil: presetConfig.supportsWaitUntil
|
|
243
|
-
? (promise: Promise<unknown>) => {
|
|
244
|
-
const tracked = promise.catch((err) => {
|
|
245
|
-
console.error('[timber] waitUntil promise rejected:', err);
|
|
246
|
-
});
|
|
247
|
-
pendingPromises.push(tracked);
|
|
248
|
-
}
|
|
249
|
-
: undefined,
|
|
250
239
|
};
|
|
251
240
|
}
|
|
252
241
|
|
package/src/adapters/types.ts
CHANGED
|
@@ -42,13 +42,6 @@ export interface TimberPlatformAdapter {
|
|
|
42
42
|
*/
|
|
43
43
|
preview?(config: TimberConfig, buildDir: string): Promise<void>;
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
* Register a promise to be kept alive after the response is sent.
|
|
47
|
-
* Maps to platform-specific lifecycle extension (e.g. ctx.waitUntil()
|
|
48
|
-
* on Cloudflare Workers). Undefined if the platform doesn't support it.
|
|
49
|
-
*/
|
|
50
|
-
waitUntil?(promise: Promise<unknown>): void;
|
|
51
|
-
|
|
52
45
|
/**
|
|
53
46
|
* Send 103 Early Hints to the client before the final response.
|
|
54
47
|
*
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChildSegmentContext — delivers child segment content to ChildSegmentOutlet.
|
|
3
|
+
*
|
|
4
|
+
* Each layout receives a stable <ChildSegmentOutlet /> client reference as
|
|
5
|
+
* its `children` prop instead of varying server content. The actual child
|
|
6
|
+
* content (page or inner layout) is provided via this context from a
|
|
7
|
+
* ChildSegmentProvider placed ABOVE the layout in the element tree.
|
|
8
|
+
*
|
|
9
|
+
* This structural separation is what makes layout cache.component hits
|
|
10
|
+
* possible: the cached layout payload contains a deterministic client
|
|
11
|
+
* reference as children, not the varying inner content that changes per
|
|
12
|
+
* route. Same pattern as Next.js LayoutRouter.
|
|
13
|
+
*
|
|
14
|
+
* SINGLETON GUARANTEE: Uses globalThis + Symbol.for — same pattern as
|
|
15
|
+
* SegmentUpdateContext. The RSC client bundler can duplicate this module
|
|
16
|
+
* across chunks; globalThis guarantees a single context instance.
|
|
17
|
+
*
|
|
18
|
+
* See design/45-cache-lifetimes.md §Layout Propagation.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
'use client';
|
|
22
|
+
|
|
23
|
+
import React, { type ReactNode } from 'react';
|
|
24
|
+
|
|
25
|
+
const CTX_KEY = Symbol.for('__timber_child_segment_ctx');
|
|
26
|
+
|
|
27
|
+
function getOrCreateContext(): React.Context<ReactNode> {
|
|
28
|
+
const existing = (globalThis as Record<symbol, unknown>)[CTX_KEY] as
|
|
29
|
+
| React.Context<ReactNode>
|
|
30
|
+
| undefined;
|
|
31
|
+
if (existing !== undefined) return existing;
|
|
32
|
+
if (typeof React.createContext === 'function') {
|
|
33
|
+
const ctx = React.createContext<ReactNode>(null);
|
|
34
|
+
(globalThis as Record<symbol, unknown>)[CTX_KEY] = ctx;
|
|
35
|
+
return ctx;
|
|
36
|
+
}
|
|
37
|
+
return undefined as unknown as React.Context<ReactNode>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const ChildSegmentContext = getOrCreateContext();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChildSegmentOutlet — renders child segment content from context.
|
|
3
|
+
*
|
|
4
|
+
* Passed as `children` to every layout component, replacing the previous
|
|
5
|
+
* pattern of passing rendered server content directly. The layout receives
|
|
6
|
+
* a stable client reference (this component), and the actual child content
|
|
7
|
+
* is delivered via ChildSegmentContext from a provider above the layout.
|
|
8
|
+
*
|
|
9
|
+
* This makes layout cache.component hits possible: the cached layout
|
|
10
|
+
* payload contains this deterministic client reference, not varying
|
|
11
|
+
* server content. On cache hit, the revived payload contains the layout
|
|
12
|
+
* shell + this outlet; the provider above supplies the current request's
|
|
13
|
+
* child content.
|
|
14
|
+
*
|
|
15
|
+
* See design/45-cache-lifetimes.md §Layout Propagation.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
'use client';
|
|
19
|
+
|
|
20
|
+
import { useContext } from 'react';
|
|
21
|
+
import { ChildSegmentContext } from './child-segment-context.js';
|
|
22
|
+
|
|
23
|
+
export function ChildSegmentOutlet() {
|
|
24
|
+
return useContext(ChildSegmentContext);
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChildSegmentProvider — wraps a layout to provide child segment content.
|
|
3
|
+
*
|
|
4
|
+
* Placed above the layout in the element tree so that ChildSegmentOutlet
|
|
5
|
+
* (inside the layout's `children`) can read the actual child content.
|
|
6
|
+
*
|
|
7
|
+
* Tree structure:
|
|
8
|
+
* ChildSegmentProvider(childContent=innerElement)
|
|
9
|
+
* └── Layout(children=<ChildSegmentOutlet />)
|
|
10
|
+
* └── ChildSegmentOutlet → reads context → innerElement
|
|
11
|
+
*
|
|
12
|
+
* See design/45-cache-lifetimes.md §Layout Propagation.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use client';
|
|
16
|
+
|
|
17
|
+
import { createElement, type ReactNode } from 'react';
|
|
18
|
+
import { ChildSegmentContext } from './child-segment-context.js';
|
|
19
|
+
|
|
20
|
+
interface ChildSegmentProviderProps {
|
|
21
|
+
childContent: ReactNode;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function ChildSegmentProvider({ childContent, children }: ChildSegmentProviderProps) {
|
|
26
|
+
return createElement(ChildSegmentContext.Provider, { value: childContent }, children);
|
|
27
|
+
}
|
|
@@ -128,14 +128,13 @@ export function buildSegmentTree(segments: SegmentInfo[]): SegmentNode | undefin
|
|
|
128
128
|
// Need at least a root segment to build a tree
|
|
129
129
|
if (segments.length === 0) return undefined;
|
|
130
130
|
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
// All entries are layout segments — the server filters out layoutless
|
|
132
|
+
// segments (including the page leaf) in buildSegmentInfo. Cache every
|
|
133
|
+
// entry; pages are never sent.
|
|
135
134
|
let root: SegmentNode | undefined;
|
|
136
135
|
let parent: SegmentNode | undefined;
|
|
137
136
|
|
|
138
|
-
for (const info of
|
|
137
|
+
for (const info of segments) {
|
|
139
138
|
const id = info.segmentId ?? info.path;
|
|
140
139
|
const node: SegmentNode = {
|
|
141
140
|
segment: id,
|
package/src/client/use-cookie.ts
CHANGED
|
@@ -117,7 +117,17 @@ export function useCookie(
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
const getSnapshot = (): string | undefined => getCookieValue(name);
|
|
120
|
-
const getServerSnapshot = (): string | undefined =>
|
|
120
|
+
const getServerSnapshot = (): string | undefined => {
|
|
121
|
+
// During SSR, read the ALS-backed request cookies.
|
|
122
|
+
const ssrData = getSsrData();
|
|
123
|
+
if (ssrData) return ssrData.cookies.get(name);
|
|
124
|
+
// During client hydration there is no SSR data (it lives in the server's
|
|
125
|
+
// module graph), but React still calls getServerSnapshot. document.cookie
|
|
126
|
+
// holds the same cookies the server rendered with, so reading it here
|
|
127
|
+
// keeps the hydration render consistent with the server HTML.
|
|
128
|
+
// See design/29-cookies.md §"SSR Hydration".
|
|
129
|
+
return getCookieValue(name);
|
|
130
|
+
};
|
|
121
131
|
|
|
122
132
|
const value = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
123
133
|
|