@timber-js/app 0.2.0-alpha.110 → 0.2.0-alpha.112
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-D6gyxlGQ.js → actions-ILhDUzES.js} +46 -10
- package/dist/_chunks/actions-ILhDUzES.js.map +1 -0
- package/dist/_chunks/{build-output-helper-5TK2Emwp.js → build-output-helper-DhxiT18k.js} +1 -1
- package/dist/_chunks/{build-output-helper-5TK2Emwp.js.map → build-output-helper-DhxiT18k.js.map} +1 -1
- package/dist/_chunks/cli-schema-sync-BhXdbmgS.js +2 -0
- package/dist/_chunks/cli-schema-sync-DFZmnmqG.js +357 -0
- package/dist/_chunks/cli-schema-sync-DFZmnmqG.js.map +1 -0
- package/dist/_chunks/codec-registry-V7ARyeLN.js +21 -0
- package/dist/_chunks/codec-registry-V7ARyeLN.js.map +1 -0
- package/dist/_chunks/{define-Dn98bPbb.js → define-8zQ8Vm7x.js} +3 -3
- package/dist/_chunks/{define-Dn98bPbb.js.map → define-8zQ8Vm7x.js.map} +1 -1
- package/dist/_chunks/{define-BflNsrwD.js → define-a0CCE6Nx.js} +3 -3
- package/dist/_chunks/{define-BflNsrwD.js.map → define-a0CCE6Nx.js.map} +1 -1
- package/dist/_chunks/{format-CYBGxKtc.js → format-CR6v1pWE.js} +1 -1
- package/dist/_chunks/{format-CYBGxKtc.js.map → format-CR6v1pWE.js.map} +1 -1
- package/dist/_chunks/{handler-store-B_df5Npe.js → handler-store-iqnt2ghN.js} +1 -1
- package/dist/_chunks/{handler-store-B_df5Npe.js.map → handler-store-iqnt2ghN.js.map} +1 -1
- package/dist/_chunks/{merge-search-params-Cm_KIWDX.js → merge-search-params-CwxJzBLS.js} +1 -1
- package/dist/_chunks/{merge-search-params-Cm_KIWDX.js.map → merge-search-params-CwxJzBLS.js.map} +1 -1
- package/dist/_chunks/{navigation-root-2ypaZQDx.js → navigation-root-CY3pRMxF.js} +2 -2
- package/dist/_chunks/{navigation-root-2ypaZQDx.js.map → navigation-root-CY3pRMxF.js.map} +1 -1
- package/dist/_chunks/{registry-DB93kT5c.js → registry-Dp_hJL4s.js} +1 -1
- package/dist/_chunks/{registry-DB93kT5c.js.map → registry-Dp_hJL4s.js.map} +1 -1
- package/dist/_chunks/resolve-schema-DO8B0mO9.js +65 -0
- package/dist/_chunks/resolve-schema-DO8B0mO9.js.map +1 -0
- package/dist/_chunks/{router-ref-TkUdmqtM.js → router-ref-sektkr-t.js} +2 -2
- package/dist/_chunks/{router-ref-TkUdmqtM.js.map → router-ref-sektkr-t.js.map} +1 -1
- package/dist/_chunks/scanner-DmfoB7iK.js +336 -0
- package/dist/_chunks/scanner-DmfoB7iK.js.map +1 -0
- package/dist/_chunks/{schema-bridge-C3xl_vfb.js → schema-bridge-eL5vQDSA.js} +1 -1
- package/dist/_chunks/{schema-bridge-C3xl_vfb.js.map → schema-bridge-eL5vQDSA.js.map} +1 -1
- package/dist/_chunks/{segment-context-Dc-GbSTe.js → segment-context-EsfQpS--.js} +1 -1
- package/dist/_chunks/{segment-context-Dc-GbSTe.js.map → segment-context-EsfQpS--.js.map} +1 -1
- package/dist/_chunks/{ssr-data-DzuI0bIV.js → ssr-data-BO5OvEvg.js} +1 -1
- package/dist/_chunks/{ssr-data-DzuI0bIV.js.map → ssr-data-BO5OvEvg.js.map} +1 -1
- package/dist/_chunks/{stale-reload-D6FlD3xn.js → stale-reload-BCPRG0Cv.js} +1 -1
- package/dist/_chunks/{stale-reload-D6FlD3xn.js.map → stale-reload-BCPRG0Cv.js.map} +1 -1
- package/dist/_chunks/tracing-DvKLzCFa.js.map +1 -1
- package/dist/_chunks/{use-query-states-B-cLl8mx.js → use-query-states-D9SBlAfp.js} +2 -2
- package/dist/_chunks/{use-query-states-B-cLl8mx.js.map → use-query-states-D9SBlAfp.js.map} +1 -1
- package/dist/_chunks/{use-segment-params-07V1TIxL.js → use-segment-params-BSt_O2cb.js} +2 -2
- package/dist/_chunks/{use-segment-params-07V1TIxL.js.map → use-segment-params-BSt_O2cb.js.map} +1 -1
- package/dist/_chunks/{validation-DfyuMoK2.js → validation-Bm3Je-09.js} +1 -1
- package/dist/_chunks/{validation-DfyuMoK2.js.map → validation-Bm3Je-09.js.map} +1 -1
- package/dist/_chunks/{walkers-DQn5NNrf.js → walkers-DGTmJT0f.js} +109 -353
- package/dist/_chunks/walkers-DGTmJT0f.js.map +1 -0
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/nitro.js +1 -1
- package/dist/cache/index.js +3 -2
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cli-schema-sync.d.ts +37 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +8 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +34 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/error-boundary.js +5 -3
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/index.js +27 -9
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js +7 -7
- package/dist/client/link.d.ts.map +1 -1
- package/dist/codec.js +1 -1
- package/dist/cookies/index.js +3 -3
- package/dist/dev-tools/browser-logs.d.ts.map +1 -1
- package/dist/dev-tools/error-page.d.ts.map +1 -1
- package/dist/dev-tools/logs.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +1 -1
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -236
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +52 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +33 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +8 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -1
- package/dist/routing/codegen-types.d.ts +5 -0
- package/dist/routing/codegen-types.d.ts.map +1 -1
- package/dist/routing/codegen.d.ts +5 -0
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/index.js +2 -1
- package/dist/routing/link-codegen.d.ts +2 -2
- package/dist/routing/link-codegen.d.ts.map +1 -1
- package/dist/search-params/index.js +3 -3
- package/dist/segment-params/index.js +1 -1
- package/dist/server/als-registry.d.ts +7 -0
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +30 -4
- package/dist/server/internal.js.map +1 -1
- package/dist/server/node-stream-transforms.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +12 -2
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +18 -0
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +17 -3
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +8 -14
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/package.json +11 -6
- package/src/cache/sizeof.ts +3 -1
- package/src/cli-schema-sync.ts +206 -0
- package/src/cli.ts +49 -2
- package/src/client/browser-entry/action-dispatch.ts +15 -5
- package/src/client/browser-entry/index.ts +6 -0
- package/src/client/error-boundary.tsx +2 -2
- package/src/client/link.tsx +25 -1
- package/src/dev-tools/browser-logs.ts +5 -2
- package/src/dev-tools/error-page.ts +3 -6
- package/src/dev-tools/logs.ts +6 -2
- package/src/dev-tools/overlay.ts +18 -5
- package/src/index.ts +5 -0
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +72 -0
- package/src/params/index.ts +11 -0
- package/src/params/resolve-schema.ts +88 -0
- package/src/plugins/dev-server.ts +24 -16
- package/src/plugins/mdx.ts +5 -1
- package/src/plugins/routing.ts +107 -2
- package/src/routing/codegen-shared.ts +11 -0
- package/src/routing/codegen-types.ts +5 -0
- package/src/routing/codegen.ts +129 -21
- package/src/routing/link-codegen.ts +19 -5
- package/src/server/als-registry.ts +7 -0
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/fallback-error.ts +3 -3
- package/src/server/html-injectors.ts +11 -22
- package/src/server/node-stream-transforms.ts +6 -16
- package/src/server/param-coercion.ts +55 -2
- package/src/server/pipeline-phases.ts +8 -0
- package/src/server/pipeline.ts +19 -0
- package/src/server/request-context.ts +58 -3
- package/src/server/rsc-entry/helpers.ts +3 -2
- package/src/server/rsc-entry/index.ts +28 -35
- package/LICENSE +0 -8
- package/dist/_chunks/actions-D6gyxlGQ.js.map +0 -1
- package/dist/_chunks/walkers-DQn5NNrf.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-stream-transforms.d.ts","sourceRoot":"","sources":["../../src/server/node-stream-transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAGL,YAAY,EAOb,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"node-stream-transforms.d.ts","sourceRoot":"","sources":["../../src/server/node-stream-transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAGL,YAAY,EAOb,MAAM,yBAAyB,CAAC;AAMjC,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,4BAAiC,GAAG,SAAS,CA2BjG;AAID;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,SAAS,CAoBzD;AAGD,OAAO,EAAE,YAAY,EAAE,CAAC;AAIxB;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CA2BlE;AAID;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,SAAS,EACjD,OAAO,CAAC,EAAE,yBAAyB,GAClC,SAAS,CA6DX;AAOD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAwBtE;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,OAAO,EACvB,eAAe,EAAE,OAAO,GACvB,SAAS,GAAG,IAAI,CA8BlB"}
|
|
@@ -11,16 +11,26 @@
|
|
|
11
11
|
* on any codec failure; the pipeline catches that and dispatches to the
|
|
12
12
|
* 404 page. See design/07-routing.md §"Where Coercion Runs".
|
|
13
13
|
*/
|
|
14
|
+
import type { Codec } from '../codec.js';
|
|
14
15
|
import type { RouteMatch } from './pipeline.js';
|
|
16
|
+
/**
|
|
17
|
+
* Register the global schema codecs. Called once from the RSC entry
|
|
18
|
+
* at server startup when app/schema.ts provides segment param codecs.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare function setGlobalSchemaCodecs(codecs: Record<string, Codec<unknown>> | null): void;
|
|
15
22
|
/**
|
|
16
23
|
* Run segment param coercion on the matched route's segments.
|
|
17
24
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
25
|
+
* When `globalCodecs` is provided (from app/schema.ts), uses the global
|
|
26
|
+
* codec map keyed by bare param name. Otherwise falls back to loading
|
|
27
|
+
* per-segment params.ts modules.
|
|
28
|
+
*
|
|
20
29
|
* Throws ParamCoercionError if any codec fails (→ 404).
|
|
21
30
|
*
|
|
22
31
|
* This runs BEFORE middleware, so ctx.segmentParams is already typed.
|
|
23
32
|
* See design/07-routing.md §"Where Coercion Runs"
|
|
33
|
+
* See design/41-global-params.md §"Pipeline Integration"
|
|
24
34
|
*/
|
|
25
35
|
export declare function coerceSegmentParams(match: RouteMatch): Promise<void>;
|
|
26
36
|
//# sourceMappingURL=param-coercion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"param-coercion.d.ts","sourceRoot":"","sources":["../../src/server/param-coercion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"param-coercion.d.ts","sourceRoot":"","sources":["../../src/server/param-coercion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAahD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAEzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline-phases.d.ts","sourceRoot":"","sources":["../../src/server/pipeline-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"pipeline-phases.d.ts","sourceRoot":"","sources":["../../src/server/pipeline-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoBH,OAAO,EAA2C,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEpG,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKrF,UAAU,aAAa;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAID;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC,CAavB;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,oBAAoB,EAAE,OAAO,EAC7B,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,YAAY,CAAC,CA6DvB;AAID;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,oBAAoB,EAAE,OAAO,EAC7B,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE,aAAa,GACjD,OAAO,CAAC,YAAY,CAAC,CAkBvB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CA0PnB"}
|
|
@@ -125,6 +125,24 @@ export interface PipelineConfig {
|
|
|
125
125
|
* Undefined in production — zero overhead.
|
|
126
126
|
*/
|
|
127
127
|
onPipelineError?: (error: Error, phase: string) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Dev error handler with RSC debug context — set by the dev server after
|
|
130
|
+
* the RSC entry module is imported. `onPipelineError` resolves debug
|
|
131
|
+
* components from ALS and delegates to this handler.
|
|
132
|
+
*
|
|
133
|
+
* This is a mutable property (not a constructor argument) because the dev
|
|
134
|
+
* server imports the RSC entry module first (which constructs the config),
|
|
135
|
+
* then wires in the overlay handler. Moving the state here (from a
|
|
136
|
+
* module-level `let`) keeps it co-located with the config it belongs to
|
|
137
|
+
* and makes it visible in tests without module-level mutation.
|
|
138
|
+
*
|
|
139
|
+
* Undefined in production — zero overhead.
|
|
140
|
+
*/
|
|
141
|
+
devPipelineErrorHandler?: (error: Error, phase: string, debugComponents?: Array<{
|
|
142
|
+
name: string;
|
|
143
|
+
env: string | null;
|
|
144
|
+
stack: unknown[] | null;
|
|
145
|
+
}>) => void;
|
|
128
146
|
/**
|
|
129
147
|
* Fallback error renderer — called when a catastrophic error escapes the
|
|
130
148
|
* render phase. Produces an HTML Response instead of a bare empty 500.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/server/pipeline.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/server/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,16 +40,30 @@ export declare function getSearchParams(): URLSearchParams;
|
|
|
40
40
|
/**
|
|
41
41
|
* Returns the current request's coerced segment params.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
43
|
+
* The optional `_route` argument exists only for TypeScript narrowing —
|
|
44
|
+
* it does not affect the runtime return value. Pass a route pattern
|
|
45
|
+
* (e.g. `'/[artistSlug]/[year]'`) to narrow the return type to the
|
|
46
|
+
* exact params shape for that route.
|
|
47
|
+
*
|
|
48
|
+
* Without a route argument, returns all coerced params with optional types.
|
|
49
|
+
*
|
|
50
|
+
* See design/41-global-params.md §Function Signatures
|
|
44
51
|
*/
|
|
45
|
-
export declare function getSegmentParams(): Record<string, string | string[]>;
|
|
52
|
+
export declare function getSegmentParams(route?: string): Record<string, string | string[]>;
|
|
46
53
|
/**
|
|
47
|
-
* Set the segment params
|
|
54
|
+
* Set the segment params on the current request context.
|
|
48
55
|
* Called by the pipeline after route matching and param coercion.
|
|
49
56
|
*
|
|
50
57
|
* @internal — framework use only
|
|
51
58
|
*/
|
|
52
59
|
export declare function setSegmentParams(params: Record<string, string | string[]>): void;
|
|
60
|
+
/**
|
|
61
|
+
* Store the matched route pattern (e.g. '/[artistSlug]/[year]') for
|
|
62
|
+
* dev-mode route mismatch validation in getSegmentParams().
|
|
63
|
+
*
|
|
64
|
+
* @internal — framework use only
|
|
65
|
+
*/
|
|
66
|
+
export declare function setMatchedRoutePattern(pattern: string): void;
|
|
53
67
|
/**
|
|
54
68
|
* Returns the raw search string from the current request URL (e.g. "?foo=bar").
|
|
55
69
|
* Synchronous — safe for use in `redirect()` which throws synchronously.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC;AAOhF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAQ7B;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAS5C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,eAAe,CASjD;AAaD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAkClF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAMhF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI5D;AAkBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAG/C;AAID;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,OAAO,EACP,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,MAAM,CAAC,QAAQ,CACnF,CAAC;AAIF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAmBrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK9D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmBhE"}
|
|
@@ -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;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,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;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,+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,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA0B3C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGzD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,OAAO,GACvB,QAAQ,CAOV;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIpD;AAGD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAW1E"}
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
import 'virtual:timber-search-params-registry';
|
|
2
|
-
import {
|
|
3
|
-
/**
|
|
4
|
-
* Set the dev pipeline error handler.
|
|
5
|
-
*
|
|
6
|
-
* Called by the dev server after importing this module to wire pipeline
|
|
7
|
-
* errors into the Vite browser error overlay. No-op in production.
|
|
8
|
-
*
|
|
9
|
-
* The handler receives an optional third argument with RSC debug component
|
|
10
|
-
* info — component names, environments, and stack frames from the Flight
|
|
11
|
-
* debug channel. This is only populated for render-phase errors.
|
|
12
|
-
*/
|
|
13
|
-
export declare function setDevPipelineErrorHandler(handler: (error: Error, phase: string, debugComponents?: DebugComponentEntry[]) => void): void;
|
|
2
|
+
import type { PipelineConfig } from '../pipeline.js';
|
|
14
3
|
/**
|
|
15
4
|
* Set the dev source-map handler.
|
|
16
5
|
*
|
|
@@ -24,6 +13,11 @@ export declare function setDevPipelineErrorHandler(handler: (error: Error, phase
|
|
|
24
13
|
export declare function setDevSourceMapHandler(handler: (error: Error) => void): void;
|
|
25
14
|
export { runWithEarlyHintsSender } from '../early-hints-sender.js';
|
|
26
15
|
export { runWithWaitUntil } from '../waituntil-bridge.js';
|
|
27
|
-
declare const
|
|
28
|
-
|
|
16
|
+
declare const _handler: (req: Request) => Promise<Response>;
|
|
17
|
+
/**
|
|
18
|
+
* The pipeline configuration object. Exported so the dev server can set
|
|
19
|
+
* `devPipelineErrorHandler` after import without a module-level singleton.
|
|
20
|
+
*/
|
|
21
|
+
export declare const pipelineConfig: PipelineConfig;
|
|
22
|
+
export default _handler;
|
|
29
23
|
//# 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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/index.ts"],"names":[],"mappings":"AAuBA,OAAO,uCAAuC,CAAC;AAqB/C,OAAO,KAAK,EAAuB,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAqCtF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAE5E;AA8WD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAInE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,QAAA,MAAiB,QAAQ,qCAGxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAkB,CAAC;AAE9C,eAAe,QAAQ,CAAC"}
|
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.112",
|
|
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",
|
|
@@ -81,6 +81,10 @@
|
|
|
81
81
|
"types": "./dist/segment-params/index.d.ts",
|
|
82
82
|
"import": "./dist/segment-params/index.js"
|
|
83
83
|
},
|
|
84
|
+
"./params": {
|
|
85
|
+
"types": "./dist/params/index.d.ts",
|
|
86
|
+
"import": "./dist/params/index.js"
|
|
87
|
+
},
|
|
84
88
|
"./adapters/cloudflare": {
|
|
85
89
|
"types": "./dist/adapters/cloudflare.d.ts",
|
|
86
90
|
"import": "./dist/adapters/cloudflare.js"
|
|
@@ -110,6 +114,11 @@
|
|
|
110
114
|
"publishConfig": {
|
|
111
115
|
"access": "public"
|
|
112
116
|
},
|
|
117
|
+
"scripts": {
|
|
118
|
+
"build": "vite build --config vite.lib.config.ts && tsc --emitDeclarationOnly --project tsconfig.json --outDir dist",
|
|
119
|
+
"typecheck": "tsgo --noEmit",
|
|
120
|
+
"prepublishOnly": "pnpm run build"
|
|
121
|
+
},
|
|
113
122
|
"dependencies": {
|
|
114
123
|
"@opentelemetry/api": "^1.9.1",
|
|
115
124
|
"@opentelemetry/context-async-hooks": "^2.6.1",
|
|
@@ -153,9 +162,5 @@
|
|
|
153
162
|
},
|
|
154
163
|
"engines": {
|
|
155
164
|
"node": ">=22.12.0"
|
|
156
|
-
},
|
|
157
|
-
"scripts": {
|
|
158
|
-
"build": "vite build --config vite.lib.config.ts && tsc --emitDeclarationOnly --project tsconfig.json --outDir dist",
|
|
159
|
-
"typecheck": "tsgo --noEmit"
|
|
160
165
|
}
|
|
161
|
-
}
|
|
166
|
+
}
|
package/src/cache/sizeof.ts
CHANGED
|
@@ -25,7 +25,9 @@ export function estimateByteSize(value: unknown): number {
|
|
|
25
25
|
if (json === undefined) return 0;
|
|
26
26
|
// Each JS string character is 2 bytes (UTF-16)
|
|
27
27
|
return json.length * 2;
|
|
28
|
-
} catch {
|
|
28
|
+
} catch (e) {
|
|
29
|
+
// Circular reference or non-serializable value
|
|
30
|
+
console.debug('[timber] sizeof estimation failed:', e instanceof Error ? e.message : e);
|
|
29
31
|
return 0;
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `timber schema sync` — scan filesystem for dynamic segments and append
|
|
3
|
+
* missing entries to app/schema.ts with `codec.string` defaults.
|
|
4
|
+
*
|
|
5
|
+
* Only adds, never removes or modifies existing entries.
|
|
6
|
+
*
|
|
7
|
+
* Design doc: design/41-global-params.md §Auto-Scaffolding
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { scanRoutes } from './routing/scanner.js';
|
|
13
|
+
import type { SegmentNode } from './routing/types.js';
|
|
14
|
+
import { resolveAppDir } from './plugin-context.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Collect all unique bracket-keyed dynamic segment names from the route tree.
|
|
18
|
+
* Returns entries like '[artistSlug]', '[...slug]', '[[...topic]]'.
|
|
19
|
+
*/
|
|
20
|
+
export function collectDynamicSegments(appDir: string): string[] {
|
|
21
|
+
const tree = scanRoutes(appDir);
|
|
22
|
+
const segments = new Set<string>();
|
|
23
|
+
walkSegments(tree.root, segments);
|
|
24
|
+
return [...segments].sort();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function walkSegments(node: SegmentNode, segments: Set<string>): void {
|
|
28
|
+
if (node.paramName) {
|
|
29
|
+
// Reconstruct bracket key from segmentName (already has brackets)
|
|
30
|
+
segments.add(node.segmentName);
|
|
31
|
+
}
|
|
32
|
+
for (const child of node.children) {
|
|
33
|
+
walkSegments(child, segments);
|
|
34
|
+
}
|
|
35
|
+
for (const slot of Object.values(node.slots)) {
|
|
36
|
+
walkSegments(slot, segments);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Parse existing bracket keys from an app/schema.ts file.
|
|
42
|
+
* Uses regex to find keys in segmentParams: { '[key]': ... } blocks.
|
|
43
|
+
*/
|
|
44
|
+
export function parseExistingSchemaKeys(content: string): string[] {
|
|
45
|
+
const keys: string[] = [];
|
|
46
|
+
// Match quoted bracket keys like '[artistSlug]', '[...slug]', '[[...topic]]'
|
|
47
|
+
const re = /['"](\[{1,2}(?:\.{3})?\w+\]{1,2})['"]\s*:/g;
|
|
48
|
+
let m: RegExpExecArray | null;
|
|
49
|
+
while ((m = re.exec(content)) !== null) {
|
|
50
|
+
keys.push(m[1]);
|
|
51
|
+
}
|
|
52
|
+
return keys;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Schema file extensions to check. */
|
|
56
|
+
const SCHEMA_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx'];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Find the schema file path if it exists.
|
|
60
|
+
*/
|
|
61
|
+
export function findSchemaFile(appDir: string): string | undefined {
|
|
62
|
+
for (const ext of SCHEMA_EXTENSIONS) {
|
|
63
|
+
const p = join(appDir, `schema${ext}`);
|
|
64
|
+
if (existsSync(p)) return p;
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Generate the content for a new app/schema.ts with the given segment keys.
|
|
71
|
+
*/
|
|
72
|
+
function generateNewSchema(segments: string[]): string {
|
|
73
|
+
const lines: string[] = [];
|
|
74
|
+
lines.push("import { defineSchema, codec } from '@timber-js/app';");
|
|
75
|
+
lines.push('');
|
|
76
|
+
lines.push('export default defineSchema({');
|
|
77
|
+
lines.push(' segmentParams: {');
|
|
78
|
+
for (const seg of segments) {
|
|
79
|
+
lines.push(` '${seg}': codec.string,`);
|
|
80
|
+
}
|
|
81
|
+
lines.push(' },');
|
|
82
|
+
lines.push('});');
|
|
83
|
+
lines.push('');
|
|
84
|
+
return lines.join('\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Append missing segment entries to an existing schema file.
|
|
89
|
+
* Inserts new entries before the closing `}` of segmentParams.
|
|
90
|
+
*/
|
|
91
|
+
function appendToSchema(content: string, newSegments: string[]): string {
|
|
92
|
+
// Find the closing brace of segmentParams object.
|
|
93
|
+
// Strategy: find the last entry in segmentParams block, insert after it.
|
|
94
|
+
// Look for the pattern: segmentParams: { ... }
|
|
95
|
+
// We find the closing `},` or `}` that ends segmentParams.
|
|
96
|
+
|
|
97
|
+
// Find "segmentParams" key position
|
|
98
|
+
const spIndex = content.indexOf('segmentParams');
|
|
99
|
+
if (spIndex === -1) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'[timber] Could not find segmentParams in schema file. ' +
|
|
102
|
+
'Expected a defineSchema({ segmentParams: { ... } }) call.'
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Find the opening brace after segmentParams
|
|
107
|
+
const openBrace = content.indexOf('{', spIndex + 'segmentParams'.length);
|
|
108
|
+
if (openBrace === -1) {
|
|
109
|
+
throw new Error('[timber] Could not find opening brace for segmentParams.');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Count braces to find the matching close
|
|
113
|
+
let depth = 1;
|
|
114
|
+
let i = openBrace + 1;
|
|
115
|
+
while (i < content.length && depth > 0) {
|
|
116
|
+
if (content[i] === '{') depth++;
|
|
117
|
+
else if (content[i] === '}') depth--;
|
|
118
|
+
i++;
|
|
119
|
+
}
|
|
120
|
+
// i now points to just after the closing brace
|
|
121
|
+
const closeBrace = i - 1;
|
|
122
|
+
|
|
123
|
+
// Detect indentation from existing entries
|
|
124
|
+
const existingLine = content.slice(openBrace, closeBrace).match(/^(\s+)['"]\[/m);
|
|
125
|
+
const indent = existingLine ? existingLine[1] : ' ';
|
|
126
|
+
|
|
127
|
+
// Build insertion text
|
|
128
|
+
const insertion = newSegments.map((seg) => `${indent}'${seg}': codec.string,`).join('\n');
|
|
129
|
+
|
|
130
|
+
// Insert before the closing brace
|
|
131
|
+
const before = content.slice(0, closeBrace);
|
|
132
|
+
const after = content.slice(closeBrace);
|
|
133
|
+
|
|
134
|
+
// Add newline if the content before doesn't end with one
|
|
135
|
+
const separator = before.trimEnd().endsWith(',') ? '\n' : '\n';
|
|
136
|
+
|
|
137
|
+
return before + separator + insertion + '\n' + after;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface SchemaSyncResult {
|
|
141
|
+
/** Segments found in the filesystem. */
|
|
142
|
+
filesystemSegments: string[];
|
|
143
|
+
/** Segments already defined in app/schema.ts. */
|
|
144
|
+
existingSegments: string[];
|
|
145
|
+
/** Segments that were added. */
|
|
146
|
+
addedSegments: string[];
|
|
147
|
+
/** Whether a new schema file was created. */
|
|
148
|
+
created: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Run the schema sync: scan filesystem, diff against schema, append missing.
|
|
153
|
+
*/
|
|
154
|
+
export function runSchemaSync(projectRoot: string): SchemaSyncResult {
|
|
155
|
+
const appDir = resolveAppDir(projectRoot);
|
|
156
|
+
|
|
157
|
+
const filesystemSegments = collectDynamicSegments(appDir);
|
|
158
|
+
|
|
159
|
+
if (filesystemSegments.length === 0) {
|
|
160
|
+
return {
|
|
161
|
+
filesystemSegments: [],
|
|
162
|
+
existingSegments: [],
|
|
163
|
+
addedSegments: [],
|
|
164
|
+
created: false,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const schemaPath = findSchemaFile(appDir);
|
|
169
|
+
|
|
170
|
+
if (!schemaPath) {
|
|
171
|
+
// Create new schema file
|
|
172
|
+
const newPath = join(appDir, 'schema.ts');
|
|
173
|
+
writeFileSync(newPath, generateNewSchema(filesystemSegments), 'utf-8');
|
|
174
|
+
return {
|
|
175
|
+
filesystemSegments,
|
|
176
|
+
existingSegments: [],
|
|
177
|
+
addedSegments: filesystemSegments,
|
|
178
|
+
created: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Read existing schema and find missing segments
|
|
183
|
+
const content = readFileSync(schemaPath, 'utf-8');
|
|
184
|
+
const existingSegments = parseExistingSchemaKeys(content);
|
|
185
|
+
const missing = filesystemSegments.filter((seg) => !existingSegments.includes(seg));
|
|
186
|
+
|
|
187
|
+
if (missing.length === 0) {
|
|
188
|
+
return {
|
|
189
|
+
filesystemSegments,
|
|
190
|
+
existingSegments,
|
|
191
|
+
addedSegments: [],
|
|
192
|
+
created: false,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Append missing segments
|
|
197
|
+
const updated = appendToSchema(content, missing);
|
|
198
|
+
writeFileSync(schemaPath, updated, 'utf-8');
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
filesystemSegments,
|
|
202
|
+
existingSegments,
|
|
203
|
+
addedSegments: missing,
|
|
204
|
+
created: false,
|
|
205
|
+
};
|
|
206
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// timber preview — Serve the production build
|
|
12
12
|
// timber check — Validate types + routes without building
|
|
13
13
|
|
|
14
|
-
const COMMANDS = ['dev', 'build', 'preview', 'check'] as const;
|
|
14
|
+
const COMMANDS = ['dev', 'build', 'preview', 'check', 'schema'] as const;
|
|
15
15
|
type Command = (typeof COMMANDS)[number];
|
|
16
16
|
|
|
17
17
|
export interface ParsedArgs {
|
|
@@ -30,7 +30,7 @@ export interface CommandOptions {
|
|
|
30
30
|
export function parseArgs(args: string[]): ParsedArgs {
|
|
31
31
|
if (args.length === 0) {
|
|
32
32
|
throw new Error(
|
|
33
|
-
'No command provided. Usage: timber <dev|build|preview|check> [--config <path>]'
|
|
33
|
+
'No command provided. Usage: timber <dev|build|preview|check|schema> [--config <path>]'
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -184,6 +184,50 @@ export async function runCheck(options: CommandOptions): Promise<void> {
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
// ─── Schema Subcommand ───────────────────────────────────────────────────────
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* `timber schema sync` — scan filesystem for dynamic segments, diff against
|
|
191
|
+
* app/schema.ts, and append missing entries with codec.string default.
|
|
192
|
+
*
|
|
193
|
+
* See design/41-global-params.md §Auto-Scaffolding
|
|
194
|
+
*/
|
|
195
|
+
export async function runSchema(args: string[]): Promise<void> {
|
|
196
|
+
const subcommand = args[0];
|
|
197
|
+
|
|
198
|
+
if (subcommand !== 'sync') {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Unknown schema subcommand: ${subcommand ?? '(none)'}. Usage: timber schema sync`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const { runSchemaSync } = await import('./cli-schema-sync.js');
|
|
205
|
+
const result = runSchemaSync(process.cwd());
|
|
206
|
+
|
|
207
|
+
if (result.filesystemSegments.length === 0) {
|
|
208
|
+
console.log('[timber] No dynamic segments found in app/.');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (result.created) {
|
|
213
|
+
console.log(`[timber] Created app/schema.ts with ${result.addedSegments.length} segment(s):`);
|
|
214
|
+
for (const seg of result.addedSegments) {
|
|
215
|
+
console.log(` + ${seg}: codec.string`);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (result.addedSegments.length === 0) {
|
|
221
|
+
console.log('[timber] Schema is up to date — all segments are registered.');
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
console.log(`[timber] Added ${result.addedSegments.length} segment(s) to app/schema.ts:`);
|
|
226
|
+
for (const seg of result.addedSegments) {
|
|
227
|
+
console.log(` + ${seg}: codec.string`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
187
231
|
// ─── Main Entry Point ────────────────────────────────────────────────────────
|
|
188
232
|
|
|
189
233
|
async function main(): Promise<void> {
|
|
@@ -203,6 +247,9 @@ async function main(): Promise<void> {
|
|
|
203
247
|
case 'check':
|
|
204
248
|
await runCheck(options);
|
|
205
249
|
break;
|
|
250
|
+
case 'schema':
|
|
251
|
+
await runSchema(process.argv.slice(3));
|
|
252
|
+
break;
|
|
206
253
|
}
|
|
207
254
|
}
|
|
208
255
|
|
|
@@ -78,10 +78,14 @@ export function setupServerActions(): void {
|
|
|
78
78
|
try {
|
|
79
79
|
const router = getRouter();
|
|
80
80
|
void router.navigate(wrapper._redirect);
|
|
81
|
-
} catch {
|
|
81
|
+
} catch (e) {
|
|
82
82
|
// Router not yet initialized — fall back to full navigation.
|
|
83
83
|
// Set hard-navigating flag to prevent Navigation API interception
|
|
84
84
|
// and React from rendering during page teardown. See TIM-626.
|
|
85
|
+
console.debug(
|
|
86
|
+
'[timber] action redirect: router not ready, using full navigation',
|
|
87
|
+
e instanceof Error ? e.message : e
|
|
88
|
+
);
|
|
85
89
|
setHardNavigating(true);
|
|
86
90
|
window.location.href = wrapper._redirect;
|
|
87
91
|
}
|
|
@@ -96,8 +100,11 @@ export function setupServerActions(): void {
|
|
|
96
100
|
const router = getRouter();
|
|
97
101
|
const headElements = headElementsJson ? JSON.parse(headElementsJson) : null;
|
|
98
102
|
router.applyRevalidation(wrapper._tree, headElements);
|
|
99
|
-
} catch {
|
|
100
|
-
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.debug(
|
|
105
|
+
'[timber] action revalidation: router not ready',
|
|
106
|
+
e instanceof Error ? e.message : e
|
|
107
|
+
);
|
|
101
108
|
}
|
|
102
109
|
return wrapper._action;
|
|
103
110
|
}
|
|
@@ -107,8 +114,11 @@ export function setupServerActions(): void {
|
|
|
107
114
|
try {
|
|
108
115
|
const router = getRouter();
|
|
109
116
|
void router.refresh();
|
|
110
|
-
} catch {
|
|
111
|
-
|
|
117
|
+
} catch (e) {
|
|
118
|
+
console.debug(
|
|
119
|
+
'[timber] action refresh: router not ready',
|
|
120
|
+
e instanceof Error ? e.message : e
|
|
121
|
+
);
|
|
112
122
|
}
|
|
113
123
|
|
|
114
124
|
return decoded;
|
|
@@ -34,6 +34,12 @@ import config from 'virtual:timber-config';
|
|
|
34
34
|
// render and click handlers. Side-effect-only import.
|
|
35
35
|
// @ts-expect-error — virtual module provided by timber-routing plugin
|
|
36
36
|
import 'virtual:timber-search-params-registry';
|
|
37
|
+
// TIM-932: Populate the codec registry so Link's interpolateParams can
|
|
38
|
+
// use codec.serialize() for URL construction. Side-effect-only import.
|
|
39
|
+
// @ts-expect-error — virtual module provided by timber-routing plugin
|
|
40
|
+
import schemaCodecs from 'virtual:timber-schema';
|
|
41
|
+
import { setLinkCodecs } from '../../params/codec-registry.js';
|
|
42
|
+
if (schemaCodecs) setLinkCodecs(schemaCodecs);
|
|
37
43
|
|
|
38
44
|
import { setClientDeploymentId } from '../rsc-fetch.js';
|
|
39
45
|
import {
|
|
@@ -273,8 +273,8 @@ function parseDigest(error: Error): ParsedDigest | null {
|
|
|
273
273
|
if (parsed && typeof parsed === 'object' && typeof parsed.type === 'string') {
|
|
274
274
|
return parsed as ParsedDigest;
|
|
275
275
|
}
|
|
276
|
-
} catch {
|
|
277
|
-
|
|
276
|
+
} catch (e) {
|
|
277
|
+
console.debug('[timber] error digest is not valid JSON:', e instanceof Error ? e.message : e);
|
|
278
278
|
}
|
|
279
279
|
return null;
|
|
280
280
|
}
|
package/src/client/link.tsx
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
} from './link-pending-store.js';
|
|
43
43
|
import { setNavLinkMetadata } from './nav-link-store.js';
|
|
44
44
|
import { hasNavigationApi } from './navigation-api.js';
|
|
45
|
+
import { getLinkCodec } from '../params/codec-registry.js';
|
|
45
46
|
|
|
46
47
|
// ─── Current Search Params ────────────────────────────────────────
|
|
47
48
|
|
|
@@ -225,6 +226,9 @@ export function parseSegments(pattern: string): UrlSegment[] {
|
|
|
225
226
|
/**
|
|
226
227
|
* Resolve a single classified segment into its string representation.
|
|
227
228
|
* Returns null for optional catch-all with no value (filtered out before join).
|
|
229
|
+
*
|
|
230
|
+
* When schema codecs are registered (via virtual:timber-schema), uses
|
|
231
|
+
* codec.serialize() for URL construction instead of plain String().
|
|
228
232
|
*/
|
|
229
233
|
function resolveSegment(
|
|
230
234
|
seg: UrlSegment,
|
|
@@ -240,6 +244,13 @@ function resolveSegment(
|
|
|
240
244
|
if (value === undefined || (Array.isArray(value) && value.length === 0)) {
|
|
241
245
|
return null;
|
|
242
246
|
}
|
|
247
|
+
const codec = getLinkCodec(`[[...${seg.name}]]`);
|
|
248
|
+
if (codec) {
|
|
249
|
+
const serialized = codec.serialize(value);
|
|
250
|
+
if (!serialized) return null;
|
|
251
|
+
// Codec returns a path string (may contain '/') — encode each segment
|
|
252
|
+
return serialized.split('/').map(encodeURIComponent).join('/');
|
|
253
|
+
}
|
|
243
254
|
const segments = Array.isArray(value) ? value : [value];
|
|
244
255
|
return segments.map(encodeURIComponent).join('/');
|
|
245
256
|
}
|
|
@@ -251,6 +262,17 @@ function resolveSegment(
|
|
|
251
262
|
`<Link> missing required catch-all param "${seg.name}" for pattern "${pattern}".`
|
|
252
263
|
);
|
|
253
264
|
}
|
|
265
|
+
const codec = getLinkCodec(`[...${seg.name}]`);
|
|
266
|
+
if (codec) {
|
|
267
|
+
const serialized = codec.serialize(value);
|
|
268
|
+
if (!serialized) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`<Link> catch-all param "${seg.name}" codec returned null for pattern "${pattern}".`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
// Codec returns a path string (may contain '/') — encode each segment
|
|
274
|
+
return serialized.split('/').map(encodeURIComponent).join('/');
|
|
275
|
+
}
|
|
254
276
|
const segments = Array.isArray(value) ? value : [value];
|
|
255
277
|
if (segments.length === 0) {
|
|
256
278
|
throw new Error(
|
|
@@ -270,7 +292,9 @@ function resolveSegment(
|
|
|
270
292
|
`<Link> param "${seg.name}" expected a string but received an array for pattern "${pattern}".`
|
|
271
293
|
);
|
|
272
294
|
}
|
|
273
|
-
|
|
295
|
+
const codec = getLinkCodec(`[${seg.name}]`);
|
|
296
|
+
const str = codec ? (codec.serialize(value) ?? String(value)) : String(value);
|
|
297
|
+
return encodeURIComponent(str);
|
|
274
298
|
}
|
|
275
299
|
}
|
|
276
300
|
}
|