@timber-js/app 0.2.0-alpha.117 → 0.2.0-alpha.119

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.
Files changed (89) hide show
  1. package/dist/_chunks/{actions-Cw-7NfJJ.js → actions-DLijOcMe.js} +6 -6
  2. package/dist/_chunks/{actions-Cw-7NfJJ.js.map → actions-DLijOcMe.js.map} +1 -1
  3. package/dist/_chunks/{build-output-helper-DhxiT18k.js → build-output-helper-B226qcTe.js} +1 -1
  4. package/dist/_chunks/{build-output-helper-DhxiT18k.js.map → build-output-helper-B226qcTe.js.map} +1 -1
  5. package/dist/_chunks/{codec-registry-V7ARyeLN.js → codec-registry-TNqK8N99.js} +1 -1
  6. package/dist/_chunks/{codec-registry-V7ARyeLN.js.map → codec-registry-TNqK8N99.js.map} +1 -1
  7. package/dist/_chunks/{define-8zQ8Vm7x.js → define-BY_dwMyV.js} +3 -3
  8. package/dist/_chunks/{define-8zQ8Vm7x.js.map → define-BY_dwMyV.js.map} +1 -1
  9. package/dist/_chunks/{define-zQX6e1tN.js → define-BlFkzZFs.js} +3 -3
  10. package/dist/_chunks/{define-zQX6e1tN.js.map → define-BlFkzZFs.js.map} +1 -1
  11. package/dist/_chunks/define-schema-CfEb8LSg.js +31 -0
  12. package/dist/_chunks/define-schema-CfEb8LSg.js.map +1 -0
  13. package/dist/_chunks/{handler-store-iqnt2ghN.js → handler-store-bIAstrxQ.js} +1 -1
  14. package/dist/_chunks/{handler-store-iqnt2ghN.js.map → handler-store-bIAstrxQ.js.map} +1 -1
  15. package/dist/_chunks/{merge-search-params-CwxJzBLS.js → merge-search-params-Cm1j99HC.js} +1 -1
  16. package/dist/_chunks/{merge-search-params-CwxJzBLS.js.map → merge-search-params-Cm1j99HC.js.map} +1 -1
  17. package/dist/_chunks/{navigation-root-DKsJ5Di7.js → navigation-root-CPKTmf-y.js} +2 -2
  18. package/dist/_chunks/{navigation-root-DKsJ5Di7.js.map → navigation-root-CPKTmf-y.js.map} +1 -1
  19. package/dist/_chunks/{registry-Dp_hJL4s.js → registry-D6-TmNLM.js} +1 -1
  20. package/dist/_chunks/{registry-Dp_hJL4s.js.map → registry-D6-TmNLM.js.map} +1 -1
  21. package/dist/_chunks/{resolve-schema-23Mc8aLi.js → resolve-schema-BxtenpoR.js} +2 -2
  22. package/dist/_chunks/{resolve-schema-23Mc8aLi.js.map → resolve-schema-BxtenpoR.js.map} +1 -1
  23. package/dist/_chunks/{router-ref-sektkr-t.js → router-ref-115GHAhP.js} +2 -2
  24. package/dist/_chunks/{router-ref-sektkr-t.js.map → router-ref-115GHAhP.js.map} +1 -1
  25. package/dist/_chunks/{schema-bridge-eL5vQDSA.js → schema-bridge-o0SwFtXW.js} +1 -1
  26. package/dist/_chunks/{schema-bridge-eL5vQDSA.js.map → schema-bridge-o0SwFtXW.js.map} +1 -1
  27. package/dist/_chunks/{segment-context-Bg0pFbLT.js → segment-context-BnxoPSFQ.js} +1 -1
  28. package/dist/_chunks/{segment-context-Bg0pFbLT.js.map → segment-context-BnxoPSFQ.js.map} +1 -1
  29. package/dist/_chunks/{ssr-data-BO5OvEvg.js → ssr-data-BP5-JJTi.js} +1 -1
  30. package/dist/_chunks/{ssr-data-BO5OvEvg.js.map → ssr-data-BP5-JJTi.js.map} +1 -1
  31. package/dist/_chunks/{stale-reload-BCPRG0Cv.js → stale-reload-DZ_GjtPz.js} +1 -1
  32. package/dist/_chunks/{stale-reload-BCPRG0Cv.js.map → stale-reload-DZ_GjtPz.js.map} +1 -1
  33. package/dist/_chunks/{use-query-states-D9SBlAfp.js → use-query-states-C0tklghY.js} +2 -2
  34. package/dist/_chunks/{use-query-states-D9SBlAfp.js.map → use-query-states-C0tklghY.js.map} +1 -1
  35. package/dist/_chunks/{use-segment-params-CskiK-59.js → use-segment-params-6W0l-wqA.js} +2 -2
  36. package/dist/_chunks/{use-segment-params-CskiK-59.js.map → use-segment-params-6W0l-wqA.js.map} +1 -1
  37. package/dist/_chunks/{validation-Bm3Je-09.js → validation-AfEFM5ze.js} +1 -1
  38. package/dist/_chunks/{validation-Bm3Je-09.js.map → validation-AfEFM5ze.js.map} +1 -1
  39. package/dist/adapters/cloudflare.js +1 -1
  40. package/dist/adapters/nitro.js +1 -1
  41. package/dist/cache/index.js +1 -1
  42. package/dist/client/error-boundary.js +2 -2
  43. package/dist/client/index.js +9 -9
  44. package/dist/client/internal.js +7 -7
  45. package/dist/codec.d.ts +19 -1
  46. package/dist/codec.d.ts.map +1 -1
  47. package/dist/codec.js +46 -2
  48. package/dist/codec.js.map +1 -0
  49. package/dist/cookies/index.js +3 -3
  50. package/dist/fonts/virtual-modules.d.ts +0 -9
  51. package/dist/fonts/virtual-modules.d.ts.map +1 -1
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +12 -3
  55. package/dist/index.js.map +1 -1
  56. package/dist/params/index.js +3 -32
  57. package/dist/plugins/fonts.d.ts.map +1 -1
  58. package/dist/search-params/index.js +3 -3
  59. package/dist/segment-params/index.js +1 -1
  60. package/dist/server/html-injector-core.d.ts +2 -1
  61. package/dist/server/html-injector-core.d.ts.map +1 -1
  62. package/dist/server/html-injectors.d.ts +1 -1
  63. package/dist/server/html-injectors.d.ts.map +1 -1
  64. package/dist/server/index.d.ts +1 -0
  65. package/dist/server/index.d.ts.map +1 -1
  66. package/dist/server/index.js +2 -2
  67. package/dist/server/internal.js +3 -3
  68. package/dist/server/node-stream-transforms.d.ts +2 -0
  69. package/dist/server/node-stream-transforms.d.ts.map +1 -1
  70. package/dist/server/rsc-entry/rsc-stream.d.ts +3 -0
  71. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  72. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  73. package/dist/server/ssr-entry.d.ts +7 -0
  74. package/dist/server/ssr-entry.d.ts.map +1 -1
  75. package/package.json +7 -6
  76. package/src/cli.ts +0 -0
  77. package/src/codec.ts +55 -3
  78. package/src/fonts/virtual-modules.ts +8 -2
  79. package/src/index.ts +5 -2
  80. package/src/plugins/fonts.ts +2 -0
  81. package/src/server/html-injector-core.ts +15 -1
  82. package/src/server/html-injectors.ts +6 -4
  83. package/src/server/index.ts +2 -3
  84. package/src/server/node-stream-transforms.ts +3 -1
  85. package/src/server/rsc-entry/rsc-stream.ts +4 -0
  86. package/src/server/rsc-entry/ssr-renderer.ts +16 -0
  87. package/src/server/ssr-entry.ts +15 -1
  88. package/LICENSE +0 -8
  89. package/dist/params/index.js.map +0 -1
@@ -1,33 +1,4 @@
1
- import { n as toBracketKey, t as resolveSchemaCodecs } from "../_chunks/resolve-schema-23Mc8aLi.js";
2
- import { n as setLinkCodecs, t as getLinkCodec } from "../_chunks/codec-registry-V7ARyeLN.js";
3
- //#region src/params/define-schema.ts
4
- /**
5
- * Define the global segment param schema.
6
- *
7
- * Each key uses the bracket syntax from the filesystem (`[id]`, `[...slug]`,
8
- * `[[...slug]]`) mapped to a codec. This makes the relationship between
9
- * filesystem segments and codecs visually obvious.
10
- *
11
- * A dynamic segment with no key here defaults to `string` at codegen time.
12
- *
13
- * ```ts
14
- * // app/schema.ts
15
- * import { defineSchema, codec } from '@timber-js/app';
16
- * import { z } from 'zod';
17
- *
18
- * export default defineSchema({
19
- * segmentParams: {
20
- * '[artistSlug]': codec.string,
21
- * '[year]': codec.integer,
22
- * '[id]': z.coerce.number().int(),
23
- * },
24
- * });
25
- * ```
26
- */
27
- function defineSchema(config) {
28
- return config;
29
- }
30
- //#endregion
1
+ import { t as defineSchema } from "../_chunks/define-schema-CfEb8LSg.js";
2
+ import { n as toBracketKey, t as resolveSchemaCodecs } from "../_chunks/resolve-schema-BxtenpoR.js";
3
+ import { n as setLinkCodecs, t as getLinkCodec } from "../_chunks/codec-registry-TNqK8N99.js";
31
4
  export { defineSchema, getLinkCodec, resolveSchemaCodecs, setLinkCodecs, toBracketKey };
32
-
33
- //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0B1D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAElF;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA4KtD"}
1
+ {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0B1D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAElF;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA8KtD"}
@@ -1,6 +1,6 @@
1
- import { n as registerSearchParams, t as getSearchParamsDefinition } from "../_chunks/registry-Dp_hJL4s.js";
2
- import { i as isStandardSchema, n as fromSchema, r as isCodec } from "../_chunks/schema-bridge-eL5vQDSA.js";
3
- import { n as defineSearchParams } from "../_chunks/define-8zQ8Vm7x.js";
1
+ import { i as isStandardSchema, n as fromSchema, r as isCodec } from "../_chunks/schema-bridge-o0SwFtXW.js";
2
+ import { n as registerSearchParams, t as getSearchParamsDefinition } from "../_chunks/registry-D6-TmNLM.js";
3
+ import { n as defineSearchParams } from "../_chunks/define-BY_dwMyV.js";
4
4
  //#region src/search-params/wrappers.ts
5
5
  /**
6
6
  * Wrap a nullable codec with a default value. When the inner codec returns
@@ -1,2 +1,2 @@
1
- import { r as defineSegmentParams } from "../_chunks/define-zQX6e1tN.js";
1
+ import { r as defineSegmentParams } from "../_chunks/define-BlFkzZFs.js";
2
2
  export { defineSegmentParams };
@@ -182,9 +182,10 @@ export declare class FlightInjectorCore {
182
182
  readonly pending: Uint8Array[];
183
183
  private readonly rscReader;
184
184
  private readonly timeoutMs;
185
+ private readonly errorSignal?;
185
186
  private readonly decoder;
186
187
  private pullPromise;
187
- constructor(rscStream: ReadableStream<Uint8Array>, renderTimeoutMs?: number);
188
+ constructor(rscStream: ReadableStream<Uint8Array>, renderTimeoutMs?: number, errorSignal?: AbortSignal);
188
189
  /** Tell the machine the first HTML chunk has arrived. Idempotent-ish: caller checks. */
189
190
  notifyFirstChunk(): void;
190
191
  /** Tell the machine HTML output is finished — pull loop will stop yielding. */
@@ -1 +1 @@
1
- {"version":3,"file":"html-injector-core.d.ts","sourceRoot":"","sources":["../../src/server/html-injector-core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html-injector-core.d.ts","sourceRoot":"","sources":["../../src/server/html-injector-core.ts"],"names":[],"mappings":"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"}
@@ -94,7 +94,7 @@ export declare function createInlinedRscStream(rscStream: ReadableStream<Uint8Ar
94
94
  * completion is signaled by the `DOMContentLoaded` event on the client
95
95
  * side — no custom done flag needed.
96
96
  */
97
- export declare function injectRscPayload(htmlStream: ReadableStream<Uint8Array>, rscStream: ReadableStream<Uint8Array> | undefined, renderTimeoutMs?: number): ReadableStream<Uint8Array>;
97
+ export declare function injectRscPayload(htmlStream: ReadableStream<Uint8Array>, rscStream: ReadableStream<Uint8Array> | undefined, renderTimeoutMs?: number, errorSignal?: AbortSignal): ReadableStream<Uint8Array>;
98
98
  /**
99
99
  * Client bootstrap configuration returned by buildClientScripts.
100
100
  *
@@ -1 +1 @@
1
- {"version":3,"file":"html-injectors.d.ts","sourceRoot":"","sources":["../../src/server/html-injectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAmBH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,wBAA6B,GACrC,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CA8BzC;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CAiBhF;AAuCD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,QAAQ,EAAE,MAAM,GACf,cAAc,CAAC,UAAU,CAAC,CAE5B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,WAAW,EAAE,MAAM,GAClB,cAAc,CAAC,UAAU,CAAC,CAE5B;AAID;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,eAAe,CAAC,EAAE,MAAM,GACvB,cAAc,CAAC,UAAU,CAAC,CA6B5B;AAuED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,SAAS,EACjD,eAAe,CAAC,EAAE,MAAM,GACvB,cAAc,CAAC,UAAU,CAAC,CAS5B;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB;AAqBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,GAAG,EAAE,OAAO,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;CAC7D,GAAG,qBAAqB,CA8DxB"}
1
+ {"version":3,"file":"html-injectors.d.ts","sourceRoot":"","sources":["../../src/server/html-injectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAmBH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,wBAA6B,GACrC,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CA8BzC;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CAiBhF;AAuCD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,QAAQ,EAAE,MAAM,GACf,cAAc,CAAC,UAAU,CAAC,CAE5B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,WAAW,EAAE,MAAM,GAClB,cAAc,CAAC,UAAU,CAAC,CAE5B;AAID;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,eAAe,CAAC,EAAE,MAAM,GACvB,cAAc,CAAC,UAAU,CAAC,CA6B5B;AAwED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,SAAS,EACjD,eAAe,CAAC,EAAE,MAAM,EACxB,WAAW,CAAC,EAAE,WAAW,GACxB,cAAc,CAAC,UAAU,CAAC,CAS5B;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB;AAqBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,GAAG,EAAE,OAAO,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;CAC7D,GAAG,qBAAqB,CA8DxB"}
@@ -10,6 +10,7 @@ export { deny, redirect, redirectExternal, RedirectType, waitUntil, type DenyOpt
10
10
  export type { RenderErrorDigest, WaitUntilAdapter } from './primitives';
11
11
  export { createActionClient, ActionError, validated } from './action-client';
12
12
  export type { ActionResult, ActionFn, ActionBuilder, ActionBuilderWithSchema, ActionContext, ActionMiddleware, ActionSchema, ValidationErrors, } from './action-client';
13
+ export { coerce, parseFormData } from './form-data';
13
14
  export { getFormFlash } from './form-flash';
14
15
  export type { FormFlashData } from './form-flash';
15
16
  export { revalidatePath, revalidateTag } from './actions';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAMA,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAKxF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGxF,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAItB,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKxE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI1D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAI1E,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAMA,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAKxF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGxF,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAItB,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKxE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI1D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAI1E,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-DvKLzCFa.js";
2
2
  import { t as formatSize } from "../_chunks/format-CR6v1pWE.js";
3
- import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-Cw-7NfJJ.js";
3
+ import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, o as coerce, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-DLijOcMe.js";
4
4
  //#region src/server/sensitive-fields.ts
5
5
  /**
6
6
  * Sensitive field stripping — removes password/token/CVV-style fields
@@ -445,6 +445,6 @@ function getFormFlash() {
445
445
  return formFlashAls.getStore() ?? null;
446
446
  }
447
447
  //#endregion
448
- export { ActionError, RedirectType, addSpanEvent, createActionClient, deny, getCookieJar, getFormFlash, getHeaders, getSegmentParams, getSpanId, getTraceId, redirect, redirectExternal, revalidatePath, revalidateTag, validated, waitUntil, withSpan };
448
+ export { ActionError, RedirectType, addSpanEvent, coerce, createActionClient, deny, getCookieJar, getFormFlash, getHeaders, getSegmentParams, getSpanId, getTraceId, parseFormData, redirect, redirectExternal, revalidatePath, revalidateTag, validated, waitUntil, withSpan };
449
449
 
450
450
  //# sourceMappingURL=index.js.map
@@ -3,10 +3,10 @@ import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as wa
3
3
  import { n as classifyUrlSegment } from "../_chunks/segment-classify-CnfLLvir.js";
4
4
  import { i as getMetadataRouteServePath, n as classifyMetadataRoute, r as getMetadataRouteAutoLink, t as METADATA_ROUTE_CONVENTIONS } from "../_chunks/metadata-routes-Cjmvi3rQ.js";
5
5
  import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-DDmK5skc.js";
6
- import { C as setMatchedSegmentPath, E as getCookie, O as getSetCookieHeaders, S as runWithRequestContext, T as setSegmentParams, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setMutableCookieContext, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-Cw-7NfJJ.js";
6
+ import { C as setMatchedSegmentPath, E as getCookie, O as getSetCookieHeaders, S as runWithRequestContext, T as setSegmentParams, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setMutableCookieContext, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-DLijOcMe.js";
7
7
  import "../client/error-boundary.js";
8
- import { n as toBracketKey } from "../_chunks/resolve-schema-23Mc8aLi.js";
9
- import "../_chunks/segment-context-Bg0pFbLT.js";
8
+ import { n as toBracketKey } from "../_chunks/resolve-schema-BxtenpoR.js";
9
+ import "../_chunks/segment-context-BnxoPSFQ.js";
10
10
  import { readFile } from "node:fs/promises";
11
11
  import { createElement } from "react";
12
12
  //#region src/server/server-timing.ts
@@ -68,6 +68,8 @@ export interface NodeFlightInjectorOptions {
68
68
  * Default: 30000 (30s).
69
69
  */
70
70
  renderTimeoutMs?: number;
71
+ /** Signal that fires when an unhandled RSC error is detected. */
72
+ errorSignal?: AbortSignal;
71
73
  }
72
74
  /**
73
75
  * Node.js `Transform` that merges RSC script tags into the HTML stream.
@@ -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;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"}
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;IACzB,iEAAiE;IACjE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;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"}
@@ -40,6 +40,9 @@ export interface RenderSignals {
40
40
  lastUnhandledError: unknown | null;
41
41
  /** Callback fired when a redirect or deny signal is captured in onError. */
42
42
  onSignal?: () => void;
43
+ /** Callback fired when an unhandled error (non-signal) is captured. Used
44
+ * to halt Flight data injection into the inline stream. */
45
+ onUnhandledError?: () => void;
43
46
  }
44
47
  export interface RscStreamResult {
45
48
  rscStream: ReadableStream<Uint8Array> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"rsc-stream.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AAItB;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAClD,OAAO,EAAE,aAAa,CAAC;IACvB,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,mBAAmB,EAAE,CAAC;CAClD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,eAAe,CA4J1F"}
1
+ {"version":3,"file":"rsc-stream.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AAItB;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;gEAC4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAClD,OAAO,EAAE,aAAa,CAAC;IACvB,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,mBAAmB,EAAE,CAAC;CAClD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,eAAe,CA6J1F"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAW/D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAarD;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,CAAC;AAEhF,UAAU,gBAAgB;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiRjF"}
1
+ {"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAW/D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAarD;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,CAAC;AAEhF,UAAU,gBAAgB;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiSjF"}
@@ -76,6 +76,13 @@ export interface NavContext {
76
76
  /** Whether the Node.js native stream path was used */
77
77
  nodeStreams: boolean;
78
78
  };
79
+ /**
80
+ * Signal that fires when an unhandled RSC error is detected.
81
+ * The Flight injector checks this before writing each script tag —
82
+ * when aborted, it stops injecting Flight data to prevent corrupted
83
+ * chunks from crashing the client's Flight decoder.
84
+ */
85
+ _errorSignal?: AbortSignal;
79
86
  }
80
87
  /**
81
88
  * Handle SSR: decode an RSC stream and render it to hydration-ready HTML.
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,uCAAuC,CAAC;AA2E/C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC;;;0DAGsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;iFAE6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4DACwD;IACxD,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE;QACZ,gFAAgF;QAChF,QAAQ,EAAE,MAAM,CAAC;QACjB,uDAAuD;QACvD,OAAO,EAAE,MAAM,CAAC;QAChB,gEAAgE;QAChE,MAAM,EAAE,MAAM,CAAC;QACf,wEAAwE;QACxE,UAAU,EAAE,MAAM,CAAC;QACnB,+CAA+C;QAC/C,OAAO,EAAE,MAAM,CAAC;QAChB,sDAAsD;QACtD,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,QAAQ,CAAC,CAuLnB;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,uCAAuC,CAAC;AA2E/C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC;;;0DAGsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;iFAE6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4DACwD;IACxD,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE;QACZ,gFAAgF;QAChF,QAAQ,EAAE,MAAM,CAAC;QACjB,uDAAuD;QACvD,OAAO,EAAE,MAAM,CAAC;QAChB,gEAAgE;QAChE,MAAM,EAAE,MAAM,CAAC;QACf,wEAAwE;QACxE,UAAU,EAAE,MAAM,CAAC;QACnB,+CAA+C;QAC/C,OAAO,EAAE,MAAM,CAAC;QAChB,sDAAsD;QACtD,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IAEF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,QAAQ,CAAC,CA6LnB;AAED,eAAe,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timber-js/app",
3
- "version": "0.2.0-alpha.117",
3
+ "version": "0.2.0-alpha.119",
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",
@@ -114,6 +114,11 @@
114
114
  "publishConfig": {
115
115
  "access": "public"
116
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
+ },
117
122
  "dependencies": {
118
123
  "@opentelemetry/api": "^1.9.1",
119
124
  "@opentelemetry/context-async-hooks": "^2.6.1",
@@ -157,9 +162,5 @@
157
162
  },
158
163
  "engines": {
159
164
  "node": ">=22.12.0"
160
- },
161
- "scripts": {
162
- "build": "vite build --config vite.lib.config.ts && tsc --emitDeclarationOnly --project tsconfig.json --outDir dist",
163
- "typecheck": "tsgo --noEmit"
164
165
  }
165
- }
166
+ }
package/src/cli.ts CHANGED
File without changes
package/src/codec.ts CHANGED
@@ -39,7 +39,59 @@ export type JsonSerializable =
39
39
 
40
40
  // ─── Standard Schema bridge ──────────────────────────────────────────────
41
41
 
42
- // fromSchema is internal — defineSearchParams and defineCookie auto-detect
43
- // Standard Schema objects. Users should pass raw schemas directly.
44
- export { fromArraySchema, validateSync, isStandardSchema, isCodec } from './schema-bridge.js';
42
+ export {
43
+ fromSchema,
44
+ fromArraySchema,
45
+ validateSync,
46
+ isStandardSchema,
47
+ isCodec,
48
+ } from './schema-bridge.js';
45
49
  export type { StandardSchemaV1, StandardSchemaResult } from './schema-bridge.js';
50
+
51
+ // ─── Built-in segment param codecs ───────────────────────────────────────
52
+
53
+ export const codec = {
54
+ string: {
55
+ parse(value: string | string[] | undefined): string {
56
+ return Array.isArray(value) ? value.join('/') : (value ?? '');
57
+ },
58
+ serialize(value: string): string | null {
59
+ return value;
60
+ },
61
+ } satisfies Codec<string>,
62
+
63
+ integer: {
64
+ parse(value: string | string[] | undefined): number {
65
+ const str = Array.isArray(value) ? value[0] : value;
66
+ const n = Number(str);
67
+ if (!Number.isInteger(n)) throw new Error(`Expected integer, got '${str}'`);
68
+ return n;
69
+ },
70
+ serialize(value: number): string | null {
71
+ return String(value);
72
+ },
73
+ } satisfies Codec<number>,
74
+
75
+ slug: {
76
+ parse(value: string | string[] | undefined): string {
77
+ const str = Array.isArray(value) ? value[0] : value;
78
+ if (!str || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str)) {
79
+ throw new Error(`Invalid slug: '${str}'`);
80
+ }
81
+ return str;
82
+ },
83
+ serialize(value: string): string | null {
84
+ return value;
85
+ },
86
+ } satisfies Codec<string>,
87
+
88
+ stringArray: {
89
+ parse(value: string | string[] | undefined): string[] {
90
+ if (Array.isArray(value)) return value;
91
+ return value ? [value] : [];
92
+ },
93
+ serialize(value: string[]): string | null {
94
+ return value.join('/');
95
+ },
96
+ } satisfies Codec<string[]>,
97
+ } as const;
@@ -59,6 +59,12 @@ export const RESOLVED_FONT_CSS_PREFIX = '\0' + VIRTUAL_FONT_CSS_PREFIX;
59
59
  * Scoped to a single `FontPipeline` instance to avoid cross-plugin-
60
60
  * instance collisions during multi-build pipelines.
61
61
  */
62
+ function stripIdDecorations(id: string): string {
63
+ const bare = id.startsWith('\0') ? id.slice(1) : id;
64
+ const qIdx = bare.indexOf('?');
65
+ return qIdx === -1 ? bare : bare.slice(0, qIdx);
66
+ }
67
+
62
68
  export class VirtualFontCssIdMap {
63
69
  private readonly map = new Map<string, string>();
64
70
 
@@ -75,7 +81,7 @@ export class VirtualFontCssIdMap {
75
81
 
76
82
  /** Decode the importer from a resolved (or unresolved) virtual css id. */
77
83
  importerFor(id: string): string | undefined {
78
- const body = id.startsWith('\0') ? id.slice(1) : id;
84
+ const body = stripIdDecorations(id);
79
85
  if (!body.startsWith(VIRTUAL_FONT_CSS_PREFIX)) return undefined;
80
86
  if (!body.endsWith(VIRTUAL_FONT_CSS_SUFFIX)) return undefined;
81
87
  const hash = body.slice(
@@ -87,7 +93,7 @@ export class VirtualFontCssIdMap {
87
93
 
88
94
  /** True if `id` is any form of the virtual font css module. */
89
95
  matches(id: string): boolean {
90
- const body = id.startsWith('\0') ? id.slice(1) : id;
96
+ const body = stripIdDecorations(id);
91
97
  return body.startsWith(VIRTUAL_FONT_CSS_PREFIX) && body.endsWith(VIRTUAL_FONT_CSS_SUFFIX);
92
98
  }
93
99
 
package/src/index.ts CHANGED
@@ -51,11 +51,14 @@ import {
51
51
 
52
52
  export type { TimberUserConfig } from './config-types.js';
53
53
 
54
- // Global segment param schema types — re-exported from root for convenience.
55
- // The value export `defineSchema` lives at '@timber-js/app/params' (canonical).
54
+ // Global segment param schema — re-exported from root for convenience.
56
55
  // See design/41-global-params.md.
56
+ export { defineSchema } from './params/define-schema.js';
57
57
  export type { InferCodecType, SchemaConfig } from './params/define-schema.js';
58
58
 
59
+ // Built-in codecs for segment params.
60
+ export { codec } from './codec.js';
61
+
59
62
  // Metadata route handler types — re-exported so user-authored metadata
60
63
  // route files (sitemap.ts, robots.ts, manifest.ts, icon.tsx, etc.) can
61
64
  // import them from the package root without reaching into ./server.
@@ -97,6 +97,8 @@ export function timberFonts(ctx: PluginContext): Plugin {
97
97
  */
98
98
  resolveId(id: string) {
99
99
  let cleanId = id.startsWith('\0') ? id.slice(1) : id;
100
+ const qIdx = cleanId.indexOf('?');
101
+ if (qIdx !== -1) cleanId = cleanId.slice(0, qIdx);
100
102
  if (cleanId.startsWith(ctx.root)) {
101
103
  const stripped = cleanId.slice(ctx.root.length);
102
104
  if (stripped.startsWith('/') || stripped.startsWith('\\')) {
@@ -299,12 +299,18 @@ export class FlightInjectorCore {
299
299
 
300
300
  private readonly rscReader: ReadableStreamDefaultReader<Uint8Array>;
301
301
  private readonly timeoutMs: number;
302
+ private readonly errorSignal?: AbortSignal;
302
303
  private readonly decoder = new TextDecoder('utf-8', { fatal: true });
303
304
  private pullPromise: Promise<void> | null = null;
304
305
 
305
- constructor(rscStream: ReadableStream<Uint8Array>, renderTimeoutMs?: number) {
306
+ constructor(
307
+ rscStream: ReadableStream<Uint8Array>,
308
+ renderTimeoutMs?: number,
309
+ errorSignal?: AbortSignal
310
+ ) {
306
311
  this.rscReader = rscStream.getReader();
307
312
  this.timeoutMs = renderTimeoutMs ?? 30_000;
313
+ this.errorSignal = errorSignal;
308
314
  this.machine = createMachine<FlightInjectionState, FlightInjectionEvent>({
309
315
  initial: { phase: 'init' },
310
316
  transitions: flightInjectionTransitions,
@@ -377,6 +383,14 @@ export class FlightInjectorCore {
377
383
  return;
378
384
  }
379
385
 
386
+ // If an unhandled RSC error was detected, stop injecting Flight
387
+ // data. Continue reading (to prevent tee buffer divergence) but
388
+ // discard the chunks so corrupted data never reaches the client.
389
+ // See TIM-938.
390
+ if (this.errorSignal?.aborted) {
391
+ continue;
392
+ }
393
+
380
394
  const decoded = this.decoder.decode(value, { stream: true });
381
395
  this.pending.push(encoder.encode(flightChunkScript(decoded)));
382
396
 
@@ -250,9 +250,10 @@ export function createInlinedRscStream(
250
250
  */
251
251
  function createFlightInjectionTransform(
252
252
  rscStream: ReadableStream<Uint8Array>,
253
- renderTimeoutMs?: number
253
+ renderTimeoutMs?: number,
254
+ errorSignal?: AbortSignal
254
255
  ): TransformStream<Uint8Array, Uint8Array> {
255
- const core = new FlightInjectorCore(rscStream, renderTimeoutMs);
256
+ const core = new FlightInjectorCore(rscStream, renderTimeoutMs, errorSignal);
256
257
  // Controller reference — set on first transform() call so the pull
257
258
  // loop can drain pending scripts between HTML chunks (after yielding).
258
259
  let _controller: TransformStreamDefaultController<Uint8Array> | null = null;
@@ -322,7 +323,8 @@ function createFlightInjectionTransform(
322
323
  export function injectRscPayload(
323
324
  htmlStream: ReadableStream<Uint8Array>,
324
325
  rscStream: ReadableStream<Uint8Array> | undefined,
325
- renderTimeoutMs?: number
326
+ renderTimeoutMs?: number,
327
+ errorSignal?: AbortSignal
326
328
  ): ReadableStream<Uint8Array> {
327
329
  if (!rscStream) return htmlStream;
328
330
  // Pass the raw RSC stream directly to the flight injection transform.
@@ -330,7 +332,7 @@ export function injectRscPayload(
330
332
  // <script> via flightChunkScript itself — do NOT pre-wrap with
331
333
  // createInlinedRscStream here, that would double-wrap.
332
334
  return htmlStream
333
- .pipeThrough(createFlightInjectionTransform(rscStream, renderTimeoutMs))
335
+ .pipeThrough(createFlightInjectionTransform(rscStream, renderTimeoutMs, errorSignal))
334
336
  .pipeThrough(createMoveSuffixStream());
335
337
  }
336
338
 
@@ -50,9 +50,8 @@ export type {
50
50
  ValidationErrors,
51
51
  } from './action-client';
52
52
 
53
- // FormData Preprocessing — internal only, not part of public API.
54
- // Schema libraries (Zod z.coerce.*, Valibot v.transform(), ArkType morphs)
55
- // handle form coercion. Kept for action-client/action-handler internals.
53
+ // FormData Preprocessing
54
+ export { coerce, parseFormData } from './form-data';
56
55
 
57
56
  // Form Flash (no-JS error round-trip)
58
57
  export { getFormFlash } from './form-flash';
@@ -172,6 +172,8 @@ export interface NodeFlightInjectorOptions {
172
172
  * Default: 30000 (30s).
173
173
  */
174
174
  renderTimeoutMs?: number;
175
+ /** Signal that fires when an unhandled RSC error is detected. */
176
+ errorSignal?: AbortSignal;
175
177
  }
176
178
 
177
179
  /**
@@ -204,7 +206,7 @@ export function createNodeFlightInjector(
204
206
  });
205
207
  }
206
208
 
207
- const core = new FlightInjectorCore(rscStream, options?.renderTimeoutMs);
209
+ const core = new FlightInjectorCore(rscStream, options?.renderTimeoutMs, options?.errorSignal);
208
210
 
209
211
  const drain = (): void => {
210
212
  while (core.pending.length > 0) transform.push(Buffer.from(core.pending.shift()!));
@@ -53,6 +53,9 @@ export interface RenderSignals {
53
53
  lastUnhandledError: unknown | null;
54
54
  /** Callback fired when a redirect or deny signal is captured in onError. */
55
55
  onSignal?: () => void;
56
+ /** Callback fired when an unhandled error (non-signal) is captured. Used
57
+ * to halt Flight data injection into the inline stream. */
58
+ onUnhandledError?: () => void;
56
59
  }
57
60
 
58
61
  export interface RscStreamResult {
@@ -165,6 +168,7 @@ export function renderRscStream(element: React.ReactElement, req: Request): RscS
165
168
  // if SSR fails (SsrStreamError). This is NOT used for page-level
166
169
  // error detection — only as a fallback when SSR actually fails.
167
170
  signals.lastUnhandledError = error;
171
+ signals.onUnhandledError?.();
168
172
 
169
173
  // Return a digest so React emits a per-row error in the Flight
170
174
  // stream instead of leaving the lazy reference unresolved.
@@ -124,6 +124,14 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
124
124
  [ssrStream, inlineStream] = teeWithErrorPropagation(rscStream);
125
125
  }
126
126
 
127
+ // Wire an AbortController so the Flight injector stops writing <script>
128
+ // tags when an unhandled RSC error is detected. Without this, React's
129
+ // Flight encoder may write model data for a chunk that already received
130
+ // an error row, causing the client's Flight decoder to crash with
131
+ // "enqueueModel is not a function". See TIM-938.
132
+ const errorAbort = new AbortController();
133
+ signals.onUnhandledError = () => errorAbort.abort();
134
+
127
135
  // Embed segment metadata in HTML for initial hydration.
128
136
  // The client reads this to populate its segment cache before the
129
137
  // first navigation, enabling state tree diffing from the start.
@@ -159,6 +167,7 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
159
167
  deferSuspenseFor: deferSuspenseFor > 0 ? deferSuspenseFor : undefined,
160
168
  signal: req.signal,
161
169
  cookies: getCookiesForSsr(),
170
+ _errorSignal: errorAbort.signal,
162
171
  };
163
172
 
164
173
  // Helper: check if render-phase signals were captured and return the
@@ -280,6 +289,7 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
280
289
  // Connection abort — the client disconnected (page refresh, navigation
281
290
  // away). No response needed; return empty 499 (client closed request).
282
291
  if (isAbortError(ssrError) || req.signal?.aborted) {
292
+ inlineStream?.cancel().catch(() => {});
283
293
  return new Response(null, { status: 499 });
284
294
  }
285
295
 
@@ -302,6 +312,12 @@ export async function renderSsrResponse(opts: SsrRenderOptions): Promise<Respons
302
312
  ssrError instanceof SsrStreamError ||
303
313
  (ssrError instanceof Error && ssrError.name === 'SsrStreamError');
304
314
  if (isSsrStreamError) {
315
+ // Cancel the teed inline stream — SSR failed so this response will
316
+ // be replaced by renderErrorPage which creates its own clean streams.
317
+ // Without explicit cancellation the orphaned tee branch keeps the
318
+ // RSC source stream alive, preventing garbage collection.
319
+ inlineStream?.cancel().catch(() => {});
320
+
305
321
  if (signals.redirectSignal) {
306
322
  return buildRedirectResponse(req, signals.redirectSignal, responseHeaders);
307
323
  }
@@ -157,6 +157,14 @@ export interface NavContext {
157
157
  /** Whether the Node.js native stream path was used */
158
158
  nodeStreams: boolean;
159
159
  };
160
+
161
+ /**
162
+ * Signal that fires when an unhandled RSC error is detected.
163
+ * The Flight injector checks this before writing each script tag —
164
+ * when aborted, it stops injecting Flight data to prevent corrupted
165
+ * chunks from crashing the client's Flight decoder.
166
+ */
167
+ _errorSignal?: AbortSignal;
160
168
  }
161
169
 
162
170
  /**
@@ -291,6 +299,7 @@ export async function handleSsr(
291
299
  const headInjector = createNodeHeadInjector(navContext.headHtml);
292
300
  const flightInjector = createNodeFlightInjector(navContext.rscStream, {
293
301
  renderTimeoutMs,
302
+ errorSignal: navContext._errorSignal,
294
303
  });
295
304
  const moveSuffix = createNodeMoveSuffixTransform();
296
305
 
@@ -350,7 +359,12 @@ export async function handleSsr(
350
359
  // structure (TIM-527).
351
360
  let outputStream = htmlStream.pipeThrough(createBufferedTransformStream());
352
361
  outputStream = injectHead(outputStream, navContext.headHtml);
353
- outputStream = injectRscPayload(outputStream, navContext.rscStream, renderTimeoutMs);
362
+ outputStream = injectRscPayload(
363
+ outputStream,
364
+ navContext.rscStream,
365
+ renderTimeoutMs,
366
+ navContext._errorSignal
367
+ );
354
368
  const _pipelineEnd = performance.now();
355
369
 
356
370
  navContext._ssrTimings = {
package/LICENSE DELETED
@@ -1,8 +0,0 @@
1
- DONTFUCKINGUSE LICENSE
2
-
3
- Copyright (c) 2025 Daniel Saewitz
4
-
5
- This software may not be used, copied, modified, merged, published,
6
- distributed, sublicensed, or sold by anyone other than the copyright holder.
7
-
8
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/params/define-schema.ts"],"sourcesContent":["/**\n * defineSchema — global segment param schema definition.\n *\n * Identity function at runtime; the type information is what matters.\n * The Vite plugin reads the schema at build time for codegen, and\n * the pipeline reads it at runtime for coercion.\n *\n * Design doc: design/41-global-params.md\n */\n\nimport type { Codec } from '../codec.js';\nimport type { StandardSchemaV1 } from '../schema-bridge.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Infer the output type from a Codec, StandardSchemaV1, or nuqs parser.\n *\n * Used by codegen to reference schema types without hardcoding:\n * `InferCodecType<typeof schema.segmentParams['[year]']>`\n */\nexport type InferCodecType<V> =\n V extends Codec<infer T>\n ? T\n : V extends StandardSchemaV1<infer T>\n ? T\n : V extends { parseServerSide: (value: string) => infer T }\n ? T\n : string;\n\n/** Acceptable codec value for segment params: a Codec or Standard Schema. */\ntype SegmentParamCodec = Codec<unknown> | StandardSchemaV1<unknown>;\n\n/** Configuration object for defineSchema. */\nexport interface SchemaConfig<S extends Record<string, SegmentParamCodec>> {\n segmentParams: S;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Define the global segment param schema.\n *\n * Each key uses the bracket syntax from the filesystem (`[id]`, `[...slug]`,\n * `[[...slug]]`) mapped to a codec. This makes the relationship between\n * filesystem segments and codecs visually obvious.\n *\n * A dynamic segment with no key here defaults to `string` at codegen time.\n *\n * ```ts\n * // app/schema.ts\n * import { defineSchema, codec } from '@timber-js/app';\n * import { z } from 'zod';\n *\n * export default defineSchema({\n * segmentParams: {\n * '[artistSlug]': codec.string,\n * '[year]': codec.integer,\n * '[id]': z.coerce.number().int(),\n * },\n * });\n * ```\n */\nexport function defineSchema<S extends Record<string, SegmentParamCodec>>(\n config: SchemaConfig<S>\n): SchemaConfig<S> {\n return config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAmEA,SAAgB,aACd,QACiB;AACjB,QAAO"}