@benjavicente/router-core 1.168.9 → 1.169.2

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 (169) hide show
  1. package/dist/cjs/Matches.cjs +1 -1
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/config.cjs +1 -1
  4. package/dist/cjs/config.cjs.map +1 -1
  5. package/dist/cjs/defer.cjs +1 -1
  6. package/dist/cjs/defer.cjs.map +1 -1
  7. package/dist/cjs/hash-scroll.cjs +1 -1
  8. package/dist/cjs/hash-scroll.cjs.map +1 -1
  9. package/dist/cjs/index.cjs +4 -0
  10. package/dist/cjs/index.d.cts +3 -3
  11. package/dist/cjs/isServer/client.cjs +1 -1
  12. package/dist/cjs/isServer/client.cjs.map +1 -1
  13. package/dist/cjs/isServer/development.cjs +1 -1
  14. package/dist/cjs/isServer/development.cjs.map +1 -1
  15. package/dist/cjs/isServer/server.cjs +1 -1
  16. package/dist/cjs/isServer/server.cjs.map +1 -1
  17. package/dist/cjs/link.cjs +1 -1
  18. package/dist/cjs/link.cjs.map +1 -1
  19. package/dist/cjs/load-matches.cjs +26 -26
  20. package/dist/cjs/load-matches.cjs.map +1 -1
  21. package/dist/cjs/manifest.cjs +31 -0
  22. package/dist/cjs/manifest.cjs.map +1 -1
  23. package/dist/cjs/manifest.d.cts +8 -0
  24. package/dist/cjs/new-process-route-tree.cjs +55 -67
  25. package/dist/cjs/new-process-route-tree.cjs.map +1 -1
  26. package/dist/cjs/new-process-route-tree.d.cts +4 -26
  27. package/dist/cjs/not-found.cjs +1 -1
  28. package/dist/cjs/not-found.cjs.map +1 -1
  29. package/dist/cjs/path.cjs +1 -22
  30. package/dist/cjs/path.cjs.map +1 -1
  31. package/dist/cjs/root.cjs +1 -1
  32. package/dist/cjs/root.cjs.map +1 -1
  33. package/dist/cjs/route.cjs.map +1 -1
  34. package/dist/cjs/route.d.cts +6 -34
  35. package/dist/cjs/router.cjs +94 -80
  36. package/dist/cjs/router.cjs.map +1 -1
  37. package/dist/cjs/router.d.cts +6 -5
  38. package/dist/cjs/scroll-restoration-script/server.cjs +1 -1
  39. package/dist/cjs/scroll-restoration-script/server.cjs.map +1 -1
  40. package/dist/cjs/scroll-restoration.cjs +7 -7
  41. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  42. package/dist/cjs/searchParams.cjs +2 -2
  43. package/dist/cjs/searchParams.cjs.map +1 -1
  44. package/dist/cjs/ssr/constants.cjs +2 -2
  45. package/dist/cjs/ssr/constants.cjs.map +1 -1
  46. package/dist/cjs/ssr/createRequestHandler.cjs +2 -2
  47. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  48. package/dist/cjs/ssr/serializer/RawStream.cjs +50 -41
  49. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -1
  50. package/dist/cjs/ssr/serializer/RawStream.d.cts +12 -4
  51. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +1 -1
  52. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -1
  53. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.d.cts +2 -2
  54. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +1 -1
  55. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -1
  56. package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -1
  57. package/dist/cjs/ssr/serializer/transformer.cjs +16 -14
  58. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  59. package/dist/cjs/ssr/serializer/transformer.d.cts +24 -23
  60. package/dist/cjs/ssr/ssr-client.cjs +9 -9
  61. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  62. package/dist/cjs/ssr/ssr-server.cjs +110 -22
  63. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  64. package/dist/cjs/ssr/ssr-server.d.cts +4 -2
  65. package/dist/cjs/ssr/transformStreamWithRouter.cjs +10 -7
  66. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  67. package/dist/cjs/stores.cjs +57 -57
  68. package/dist/cjs/stores.cjs.map +1 -1
  69. package/dist/cjs/stores.d.cts +16 -16
  70. package/dist/cjs/utils.cjs +12 -7
  71. package/dist/cjs/utils.cjs.map +1 -1
  72. package/dist/cjs/utils.d.cts +1 -0
  73. package/dist/esm/Matches.js +1 -1
  74. package/dist/esm/Matches.js.map +1 -1
  75. package/dist/esm/config.js +1 -1
  76. package/dist/esm/config.js.map +1 -1
  77. package/dist/esm/defer.js +1 -1
  78. package/dist/esm/defer.js.map +1 -1
  79. package/dist/esm/hash-scroll.js +1 -1
  80. package/dist/esm/hash-scroll.js.map +1 -1
  81. package/dist/esm/index.d.ts +3 -3
  82. package/dist/esm/index.js +3 -3
  83. package/dist/esm/isServer/client.js +1 -1
  84. package/dist/esm/isServer/client.js.map +1 -1
  85. package/dist/esm/isServer/development.js +1 -1
  86. package/dist/esm/isServer/development.js.map +1 -1
  87. package/dist/esm/isServer/server.js +1 -1
  88. package/dist/esm/isServer/server.js.map +1 -1
  89. package/dist/esm/link.js +1 -1
  90. package/dist/esm/link.js.map +1 -1
  91. package/dist/esm/load-matches.js +26 -26
  92. package/dist/esm/load-matches.js.map +1 -1
  93. package/dist/esm/manifest.d.ts +8 -0
  94. package/dist/esm/manifest.js +28 -1
  95. package/dist/esm/manifest.js.map +1 -1
  96. package/dist/esm/new-process-route-tree.d.ts +4 -26
  97. package/dist/esm/new-process-route-tree.js +55 -68
  98. package/dist/esm/new-process-route-tree.js.map +1 -1
  99. package/dist/esm/not-found.js +1 -1
  100. package/dist/esm/not-found.js.map +1 -1
  101. package/dist/esm/path.js +1 -22
  102. package/dist/esm/path.js.map +1 -1
  103. package/dist/esm/root.js +1 -1
  104. package/dist/esm/root.js.map +1 -1
  105. package/dist/esm/route.d.ts +6 -34
  106. package/dist/esm/route.js.map +1 -1
  107. package/dist/esm/router.d.ts +6 -5
  108. package/dist/esm/router.js +96 -82
  109. package/dist/esm/router.js.map +1 -1
  110. package/dist/esm/scroll-restoration-script/server.js +1 -1
  111. package/dist/esm/scroll-restoration-script/server.js.map +1 -1
  112. package/dist/esm/scroll-restoration.js +7 -7
  113. package/dist/esm/scroll-restoration.js.map +1 -1
  114. package/dist/esm/searchParams.js +2 -2
  115. package/dist/esm/searchParams.js.map +1 -1
  116. package/dist/esm/ssr/constants.js +2 -2
  117. package/dist/esm/ssr/constants.js.map +1 -1
  118. package/dist/esm/ssr/createRequestHandler.js +2 -2
  119. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  120. package/dist/esm/ssr/serializer/RawStream.d.ts +12 -4
  121. package/dist/esm/ssr/serializer/RawStream.js +50 -41
  122. package/dist/esm/ssr/serializer/RawStream.js.map +1 -1
  123. package/dist/esm/ssr/serializer/ShallowErrorPlugin.d.ts +2 -2
  124. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +1 -1
  125. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -1
  126. package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -1
  127. package/dist/esm/ssr/serializer/seroval-plugins.js +1 -1
  128. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -1
  129. package/dist/esm/ssr/serializer/transformer.d.ts +24 -23
  130. package/dist/esm/ssr/serializer/transformer.js +16 -14
  131. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  132. package/dist/esm/ssr/ssr-client.js +9 -9
  133. package/dist/esm/ssr/ssr-client.js.map +1 -1
  134. package/dist/esm/ssr/ssr-server.d.ts +4 -2
  135. package/dist/esm/ssr/ssr-server.js +110 -22
  136. package/dist/esm/ssr/ssr-server.js.map +1 -1
  137. package/dist/esm/ssr/transformStreamWithRouter.js +10 -7
  138. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  139. package/dist/esm/stores.d.ts +16 -16
  140. package/dist/esm/stores.js +58 -58
  141. package/dist/esm/stores.js.map +1 -1
  142. package/dist/esm/utils.d.ts +1 -0
  143. package/dist/esm/utils.js +12 -8
  144. package/dist/esm/utils.js.map +1 -1
  145. package/package.json +4 -8
  146. package/skills/router-core/auth-and-guards/SKILL.md +41 -0
  147. package/skills/router-core/ssr/SKILL.md +59 -5
  148. package/skills/router-core/type-safety/SKILL.md +37 -42
  149. package/src/hash-scroll.ts +1 -1
  150. package/src/index.ts +9 -2
  151. package/src/load-matches.ts +14 -15
  152. package/src/manifest.ts +46 -0
  153. package/src/new-process-route-tree.ts +93 -106
  154. package/src/not-found.ts +1 -1
  155. package/src/path.ts +1 -27
  156. package/src/route.ts +10 -36
  157. package/src/router.ts +151 -140
  158. package/src/scroll-restoration.ts +1 -1
  159. package/src/ssr/createRequestHandler.ts +4 -5
  160. package/src/ssr/serializer/RawStream.ts +65 -56
  161. package/src/ssr/serializer/ShallowErrorPlugin.ts +2 -2
  162. package/src/ssr/serializer/seroval-plugins.ts +2 -1
  163. package/src/ssr/serializer/transformer.ts +71 -76
  164. package/src/ssr/ssr-client.ts +8 -12
  165. package/src/ssr/ssr-server.ts +170 -14
  166. package/src/ssr/transformStreamWithRouter.ts +3 -0
  167. package/src/stores.ts +86 -86
  168. package/src/utils.ts +7 -0
  169. package/bin/intent.js +0 -25
@@ -3,7 +3,7 @@
3
3
  * this plugin serializes only the `message` part of an Error
4
4
  * this helps with serializing e.g. a ZodError which has functions attached that cannot be serialized
5
5
  */
6
- var ShallowErrorPlugin = /* @__PURE__ */ (0, require("seroval").createPlugin)({
6
+ const ShallowErrorPlugin = /* @__PURE__ */ (0, require("seroval").createPlugin)({
7
7
  tag: "$TSR/Error",
8
8
  test(value) {
9
9
  return value instanceof Error;
@@ -1 +1 @@
1
- {"version":3,"file":"ShallowErrorPlugin.cjs","names":[],"sources":["../../../../src/ssr/serializer/ShallowErrorPlugin.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport type { SerovalNode } from 'seroval'\n\nexport interface ErrorNode {\n message: SerovalNode\n}\n\n/**\n * this plugin serializes only the `message` part of an Error\n * this helps with serializing e.g. a ZodError which has functions attached that cannot be serialized\n */\nexport const ShallowErrorPlugin = /* @__PURE__ */ createPlugin<\n Error,\n ErrorNode\n>({\n tag: '$TSR/Error',\n test(value) {\n return value instanceof Error\n },\n parse: {\n sync(value, ctx) {\n return {\n message: ctx.parse(value.message),\n }\n },\n async async(value, ctx) {\n return {\n message: await ctx.parse(value.message),\n }\n },\n stream(value, ctx) {\n return {\n message: ctx.parse(value.message),\n }\n },\n },\n serialize(node, ctx) {\n return 'new Error(' + ctx.serialize(node.message) + ')'\n },\n deserialize(node, ctx) {\n return new Error(ctx.deserialize(node.message))\n },\n})\n"],"mappings":";;;;;AAWA,IAAa,qBAAqC,iBAAA,sBAAA,cAGhD;CACA,KAAK;CACL,KAAK,OAAO;AACV,SAAO,iBAAiB;;CAE1B,OAAO;EACL,KAAK,OAAO,KAAK;AACf,UAAO,EACL,SAAS,IAAI,MAAM,MAAM,QAAQ,EAClC;;EAEH,MAAM,MAAM,OAAO,KAAK;AACtB,UAAO,EACL,SAAS,MAAM,IAAI,MAAM,MAAM,QAAQ,EACxC;;EAEH,OAAO,OAAO,KAAK;AACjB,UAAO,EACL,SAAS,IAAI,MAAM,MAAM,QAAQ,EAClC;;EAEJ;CACD,UAAU,MAAM,KAAK;AACnB,SAAO,eAAe,IAAI,UAAU,KAAK,QAAQ,GAAG;;CAEtD,YAAY,MAAM,KAAK;AACrB,SAAO,IAAI,MAAM,IAAI,YAAY,KAAK,QAAQ,CAAC;;CAElD,CAAC"}
1
+ {"version":3,"file":"ShallowErrorPlugin.cjs","names":[],"sources":["../../../../src/ssr/serializer/ShallowErrorPlugin.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport type { PluginInfo, SerovalNode } from 'seroval'\n\nexport interface ErrorNode extends PluginInfo {\n message: SerovalNode\n}\n\n/**\n * this plugin serializes only the `message` part of an Error\n * this helps with serializing e.g. a ZodError which has functions attached that cannot be serialized\n */\nexport const ShallowErrorPlugin = /* @__PURE__ */ createPlugin<\n Error,\n ErrorNode\n>({\n tag: '$TSR/Error',\n test(value) {\n return value instanceof Error\n },\n parse: {\n sync(value, ctx) {\n return {\n message: ctx.parse(value.message),\n }\n },\n async async(value, ctx) {\n return {\n message: await ctx.parse(value.message),\n }\n },\n stream(value, ctx) {\n return {\n message: ctx.parse(value.message),\n }\n },\n },\n serialize(node, ctx) {\n return 'new Error(' + ctx.serialize(node.message) + ')'\n },\n deserialize(node, ctx) {\n return new Error(ctx.deserialize(node.message))\n },\n})\n"],"mappings":";;;;;AAWA,MAAa,qBAAqC,iBAAA,sBAAA,cAGhD;CACA,KAAK;CACL,KAAK,OAAO;AACV,SAAO,iBAAiB;;CAE1B,OAAO;EACL,KAAK,OAAO,KAAK;AACf,UAAO,EACL,SAAS,IAAI,MAAM,MAAM,QAAQ,EAClC;;EAEH,MAAM,MAAM,OAAO,KAAK;AACtB,UAAO,EACL,SAAS,MAAM,IAAI,MAAM,MAAM,QAAQ,EACxC;;EAEH,OAAO,OAAO,KAAK;AACjB,UAAO,EACL,SAAS,IAAI,MAAM,MAAM,QAAQ,EAClC;;EAEJ;CACD,UAAU,MAAM,KAAK;AACnB,SAAO,eAAe,IAAI,UAAU,KAAK,QAAQ,GAAG;;CAEtD,YAAY,MAAM,KAAK;AACrB,SAAO,IAAI,MAAM,IAAI,YAAY,KAAK,QAAQ,CAAC;;CAElD,CAAC"}
@@ -1,5 +1,5 @@
1
- import { SerovalNode } from 'seroval';
2
- export interface ErrorNode {
1
+ import { PluginInfo, SerovalNode } from 'seroval';
2
+ export interface ErrorNode extends PluginInfo {
3
3
  message: SerovalNode;
4
4
  }
5
5
  /**
@@ -2,7 +2,7 @@ const require_ShallowErrorPlugin = require("./ShallowErrorPlugin.cjs");
2
2
  const require_RawStream = require("./RawStream.cjs");
3
3
  let seroval_plugins_web = require("seroval-plugins/web");
4
4
  //#region src/ssr/serializer/seroval-plugins.ts
5
- var defaultSerovalPlugins = [
5
+ const defaultSerovalPlugins = [
6
6
  require_ShallowErrorPlugin.ShallowErrorPlugin,
7
7
  require_RawStream.RawStreamSSRPlugin,
8
8
  seroval_plugins_web.ReadableStreamPlugin
@@ -1 +1 @@
1
- {"version":3,"file":"seroval-plugins.cjs","names":[],"sources":["../../../../src/ssr/serializer/seroval-plugins.ts"],"sourcesContent":["import { ReadableStreamPlugin } from 'seroval-plugins/web'\nimport { ShallowErrorPlugin } from './ShallowErrorPlugin'\nimport { RawStreamSSRPlugin } from './RawStream'\nimport type { Plugin } from 'seroval'\n\nexport const defaultSerovalPlugins = [\n ShallowErrorPlugin as Plugin<Error, any>,\n // RawStreamSSRPlugin must come before ReadableStreamPlugin to match first\n RawStreamSSRPlugin,\n // ReadableStreamNode is not exported by seroval\n ReadableStreamPlugin as Plugin<ReadableStream, any>,\n]\n"],"mappings":";;;;AAKA,IAAa,wBAAwB;CACnC,2BAAA;CAEA,kBAAA;CAEA,oBAAA;CACD"}
1
+ {"version":3,"file":"seroval-plugins.cjs","names":[],"sources":["../../../../src/ssr/serializer/seroval-plugins.ts"],"sourcesContent":["import { ReadableStreamPlugin } from 'seroval-plugins/web'\nimport { ShallowErrorPlugin } from './ShallowErrorPlugin'\nimport { RawStreamSSRPlugin } from './RawStream'\nimport type { RawStream } from './RawStream'\nimport type { Plugin } from 'seroval'\n\nexport const defaultSerovalPlugins = [\n ShallowErrorPlugin as Plugin<Error, any>,\n // RawStreamSSRPlugin must come before ReadableStreamPlugin to match first\n RawStreamSSRPlugin as Plugin<RawStream, any>,\n // ReadableStreamNode is not exported by seroval\n ReadableStreamPlugin as Plugin<ReadableStream, any>,\n]\n"],"mappings":";;;;AAMA,MAAa,wBAAwB;CACnC,2BAAA;CAEA,kBAAA;CAEA,oBAAA;CACD"}
@@ -1,2 +1,3 @@
1
+ import { RawStream } from './RawStream.cjs';
1
2
  import { Plugin } from 'seroval';
2
- export declare const defaultSerovalPlugins: (Plugin<any, any> | Plugin<Error, any> | Plugin<ReadableStream<any>, any>)[];
3
+ export declare const defaultSerovalPlugins: (Plugin<Error, any> | Plugin<RawStream, any> | Plugin<ReadableStream<any>, any>)[];
@@ -9,39 +9,41 @@ function createSerializationAdapter(opts) {
9
9
  return opts;
10
10
  }
11
11
  /** Create a Seroval plugin for server-side serialization only. */
12
+ /* @__NO_SIDE_EFFECTS__ */
12
13
  function makeSsrSerovalPlugin(serializationAdapter, options) {
13
- return (0, seroval.createPlugin)({
14
+ return /* @__PURE__ */ (0, seroval.createPlugin)({
14
15
  tag: "$TSR/t/" + serializationAdapter.key,
15
16
  test: serializationAdapter.test,
16
- parse: { stream(value, ctx) {
17
- return ctx.parse(serializationAdapter.toSerializable(value));
17
+ parse: { stream(value, ctx, _data) {
18
+ return { v: ctx.parse(serializationAdapter.toSerializable(value)) };
18
19
  } },
19
- serialize(node, ctx) {
20
+ serialize(node, ctx, _data) {
20
21
  options.didRun = true;
21
- return require_constants.GLOBAL_TSR + ".t.get(\"" + serializationAdapter.key + "\")(" + ctx.serialize(node) + ")";
22
+ return require_constants.GLOBAL_TSR + ".t.get(\"" + serializationAdapter.key + "\")(" + ctx.serialize(node.v) + ")";
22
23
  },
23
24
  deserialize: void 0
24
25
  });
25
26
  }
26
27
  /** Create a Seroval plugin for client/server symmetric (de)serialization. */
28
+ /* @__NO_SIDE_EFFECTS__ */
27
29
  function makeSerovalPlugin(serializationAdapter) {
28
- return (0, seroval.createPlugin)({
30
+ return /* @__PURE__ */ (0, seroval.createPlugin)({
29
31
  tag: "$TSR/t/" + serializationAdapter.key,
30
32
  test: serializationAdapter.test,
31
33
  parse: {
32
- sync(value, ctx) {
33
- return ctx.parse(serializationAdapter.toSerializable(value));
34
+ sync(value, ctx, _data) {
35
+ return { v: ctx.parse(serializationAdapter.toSerializable(value)) };
34
36
  },
35
- async async(value, ctx) {
36
- return await ctx.parse(serializationAdapter.toSerializable(value));
37
+ async async(value, ctx, _data) {
38
+ return { v: await ctx.parse(serializationAdapter.toSerializable(value)) };
37
39
  },
38
- stream(value, ctx) {
39
- return ctx.parse(serializationAdapter.toSerializable(value));
40
+ stream(value, ctx, _data) {
41
+ return { v: ctx.parse(serializationAdapter.toSerializable(value)) };
40
42
  }
41
43
  },
42
44
  serialize: void 0,
43
- deserialize(node, ctx) {
44
- return serializationAdapter.fromSerializable(ctx.deserialize(node));
45
+ deserialize(node, ctx, _data) {
46
+ return serializationAdapter.fromSerializable(ctx.deserialize(node.v));
45
47
  }
46
48
  });
47
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.cjs","names":[],"sources":["../../../../src/ssr/serializer/transformer.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport { GLOBAL_TSR } from '../constants'\nimport type { Plugin, SerovalNode } from 'seroval'\nimport type {\n RegisteredConfigType,\n RegisteredSsr,\n SSROption,\n} from '../../router'\nimport type { LooseReturnType } from '../../utils'\nimport type { AnyRoute, ResolveAllSSR } from '../../route'\nimport type { RawStream } from './RawStream'\n\ndeclare const TSR_SERIALIZABLE: unique symbol\nexport type TSR_SERIALIZABLE = typeof TSR_SERIALIZABLE\n\nexport type TsrSerializable = { [TSR_SERIALIZABLE]: true }\nexport interface DefaultSerializable {\n number: number\n string: string\n boolean: boolean\n null: null\n undefined: undefined\n bigint: bigint\n Date: Date\n Uint8Array: Uint8Array\n RawStream: RawStream\n TsrSerializable: TsrSerializable\n}\n\nexport interface SerializableExtensions extends DefaultSerializable {}\n\nexport type Serializable = SerializableExtensions[keyof SerializableExtensions]\n\nexport type UnionizeSerializationAdaptersInput<\n TAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> = TAdapters[number]['~types']['input']\n\n/**\n * Create a strongly-typed serialization adapter for SSR hydration.\n * Use to register custom types with the router serializer.\n */\nexport function createSerializationAdapter<\n TInput = unknown,\n TOutput = unknown,\n const TExtendsAdapters extends\n | ReadonlyArray<AnySerializationAdapter>\n | never = never,\n>(\n opts: CreateSerializationAdapterOptions<TInput, TOutput, TExtendsAdapters>,\n): SerializationAdapter<TInput, TOutput, TExtendsAdapters> {\n return opts as unknown as SerializationAdapter<\n TInput,\n TOutput,\n TExtendsAdapters\n >\n}\n\nexport interface CreateSerializationAdapterOptions<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter> | never,\n> {\n key: string\n extends?: TExtendsAdapters\n test: (value: unknown) => value is TInput\n toSerializable: (\n value: TInput,\n ) => ValidateSerializable<\n TOutput,\n Serializable | UnionizeSerializationAdaptersInput<TExtendsAdapters>\n >\n fromSerializable: (value: TOutput) => TInput\n}\n\nexport type ValidateSerializable<T, TSerializable> =\n T extends ReadonlyArray<unknown>\n ? ResolveArrayShape<T, TSerializable, 'input'>\n : T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : T extends Promise<any>\n ? ValidateSerializablePromise<T, TSerializable>\n : T extends ReadableStream<any>\n ? ValidateReadableStream<T, TSerializable>\n : T extends Set<any>\n ? ValidateSerializableSet<T, TSerializable>\n : T extends Map<any, any>\n ? ValidateSerializableMap<T, TSerializable>\n : T extends AsyncGenerator<any, any>\n ? ValidateSerializableAsyncGenerator<T, TSerializable>\n : {\n [K in keyof T]: ValidateSerializable<T[K], TSerializable>\n }\n\nexport type ValidateSerializableAsyncGenerator<T, TSerializable> =\n T extends AsyncGenerator<infer T, infer TReturn, infer TNext>\n ? AsyncGenerator<\n ValidateSerializable<T, TSerializable>,\n ValidateSerializable<TReturn, TSerializable>,\n TNext\n >\n : never\n\nexport type ValidateSerializablePromise<T, TSerializable> =\n T extends Promise<infer TAwaited>\n ? Promise<ValidateSerializable<TAwaited, TSerializable>>\n : never\n\nexport type ValidateReadableStream<T, TSerializable> =\n T extends ReadableStream<infer TStreamed>\n ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>>\n : never\n\nexport type ValidateSerializableSet<T, TSerializable> =\n T extends Set<infer TItem>\n ? Set<ValidateSerializable<TItem, TSerializable>>\n : never\n\nexport type ValidateSerializableMap<T, TSerializable> =\n T extends Map<infer TKey, infer TValue>\n ? Map<\n ValidateSerializable<TKey, TSerializable>,\n ValidateSerializable<TValue, TSerializable>\n >\n : never\n\nexport type RegisteredReadableStream =\n unknown extends SerializerExtensions['ReadableStream']\n ? never\n : SerializerExtensions['ReadableStream']\n\nexport interface DefaultSerializerExtensions {\n ReadableStream: unknown\n}\n\nexport interface SerializerExtensions extends DefaultSerializerExtensions {}\n\nexport interface SerializationAdapter<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> {\n '~types': SerializationAdapterTypes<TInput, TOutput, TExtendsAdapters>\n key: string\n extends?: TExtendsAdapters\n test: (value: unknown) => value is TInput\n toSerializable: (value: TInput) => TOutput\n fromSerializable: (value: TOutput) => TInput\n}\n\nexport interface SerializationAdapterTypes<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> {\n input: TInput | UnionizeSerializationAdaptersInput<TExtendsAdapters>\n output: TOutput\n extends: TExtendsAdapters\n}\n\nexport type AnySerializationAdapter = SerializationAdapter<any, any, any>\n\n/** Create a Seroval plugin for server-side serialization only. */\nexport function makeSsrSerovalPlugin(\n serializationAdapter: AnySerializationAdapter,\n options: { didRun: boolean },\n): Plugin<any, SerovalNode> {\n return createPlugin<any, SerovalNode>({\n tag: '$TSR/t/' + serializationAdapter.key,\n test: serializationAdapter.test,\n parse: {\n stream(value, ctx) {\n return ctx.parse(serializationAdapter.toSerializable(value))\n },\n },\n serialize(node, ctx) {\n options.didRun = true\n return (\n GLOBAL_TSR +\n '.t.get(\"' +\n serializationAdapter.key +\n '\")(' +\n ctx.serialize(node) +\n ')'\n )\n },\n // we never deserialize on the server during SSR\n deserialize: undefined as never,\n })\n}\n\n/** Create a Seroval plugin for client/server symmetric (de)serialization. */\nexport function makeSerovalPlugin(\n serializationAdapter: AnySerializationAdapter,\n): Plugin<any, SerovalNode> {\n return createPlugin<any, SerovalNode>({\n tag: '$TSR/t/' + serializationAdapter.key,\n test: serializationAdapter.test,\n parse: {\n sync(value, ctx) {\n return ctx.parse(serializationAdapter.toSerializable(value))\n },\n async async(value, ctx) {\n return await ctx.parse(serializationAdapter.toSerializable(value))\n },\n stream(value, ctx) {\n return ctx.parse(serializationAdapter.toSerializable(value))\n },\n },\n // we don't generate JS code outside of SSR (for now)\n serialize: undefined as never,\n deserialize(node, ctx) {\n return serializationAdapter.fromSerializable(ctx.deserialize(node))\n },\n })\n}\n\nexport type ValidateSerializableInput<TRegister, T> = ValidateSerializable<\n T,\n RegisteredSerializableInput<TRegister>\n>\n\nexport type RegisteredSerializableInput<TRegister> =\n | (unknown extends RegisteredSerializationAdapters<TRegister>\n ? never\n : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter>\n ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input']\n : never)\n | Serializable\n\nexport type RegisteredSerializationAdapters<TRegister> = RegisteredConfigType<\n TRegister,\n 'serializationAdapters'\n>\n\nexport type ValidateSerializableInputResult<TRegister, T> =\n ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>\n\nexport type ValidateSerializableResult<T, TSerializable> =\n T extends ReadonlyArray<unknown>\n ? ResolveArrayShape<T, TSerializable, 'result'>\n : T extends TSerializable\n ? T\n : unknown extends SerializerExtensions['ReadableStream']\n ? { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }\n : T extends SerializerExtensions['ReadableStream']\n ? ReadableStream\n : { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }\n\nexport type RegisteredSSROption<TRegister> =\n unknown extends RegisteredConfigType<TRegister, 'defaultSsr'>\n ? SSROption\n : RegisteredConfigType<TRegister, 'defaultSsr'>\n\nexport type ValidateSerializableLifecycleResult<\n TRegister,\n TParentRoute extends AnyRoute,\n TSSR,\n TFn,\n> =\n false extends RegisteredSsr<TRegister>\n ? any\n : ValidateSerializableLifecycleResultSSR<\n TRegister,\n TParentRoute,\n TSSR,\n TFn\n > extends infer TInput\n ? TInput\n : never\n\nexport type ValidateSerializableLifecycleResultSSR<\n TRegister,\n TParentRoute extends AnyRoute,\n TSSR,\n TFn,\n> =\n ResolveAllSSR<TParentRoute, TSSR> extends false\n ? any\n : RegisteredSSROption<TRegister> extends false\n ? any\n : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>\n\ntype ResolveArrayShape<\n T extends ReadonlyArray<unknown>,\n TSerializable,\n TMode extends 'input' | 'result',\n> = number extends T['length']\n ? T extends Array<infer U>\n ? Array<ArrayModeResult<TMode, U, TSerializable>>\n : ReadonlyArray<ArrayModeResult<TMode, T[number], TSerializable>>\n : ResolveTupleShape<T, TSerializable, TMode>\n\ntype ResolveTupleShape<\n T extends ReadonlyArray<unknown>,\n TSerializable,\n TMode extends 'input' | 'result',\n> = T extends readonly [infer THead, ...infer TTail]\n ? readonly [\n ArrayModeResult<TMode, THead, TSerializable>,\n ...ResolveTupleShape<Readonly<TTail>, TSerializable, TMode>,\n ]\n : T\n\ntype ArrayModeResult<\n TMode extends 'input' | 'result',\n TValue,\n TSerializable,\n> = TMode extends 'input'\n ? ValidateSerializable<TValue, TSerializable>\n : ValidateSerializableResult<TValue, TSerializable>\n"],"mappings":";;;;;;;AAyCA,SAAgB,2BAOd,MACyD;AACzD,QAAO;;;AAkHT,SAAgB,qBACd,sBACA,SAC0B;AAC1B,SAAA,GAAA,QAAA,cAAsC;EACpC,KAAK,YAAY,qBAAqB;EACtC,MAAM,qBAAqB;EAC3B,OAAO,EACL,OAAO,OAAO,KAAK;AACjB,UAAO,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC;KAE/D;EACD,UAAU,MAAM,KAAK;AACnB,WAAQ,SAAS;AACjB,UACE,kBAAA,aACA,cACA,qBAAqB,MACrB,SACA,IAAI,UAAU,KAAK,GACnB;;EAIJ,aAAa,KAAA;EACd,CAAC;;;AAIJ,SAAgB,kBACd,sBAC0B;AAC1B,SAAA,GAAA,QAAA,cAAsC;EACpC,KAAK,YAAY,qBAAqB;EACtC,MAAM,qBAAqB;EAC3B,OAAO;GACL,KAAK,OAAO,KAAK;AACf,WAAO,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC;;GAE9D,MAAM,MAAM,OAAO,KAAK;AACtB,WAAO,MAAM,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC;;GAEpE,OAAO,OAAO,KAAK;AACjB,WAAO,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC;;GAE/D;EAED,WAAW,KAAA;EACX,YAAY,MAAM,KAAK;AACrB,UAAO,qBAAqB,iBAAiB,IAAI,YAAY,KAAK,CAAC;;EAEtE,CAAC"}
1
+ {"version":3,"file":"transformer.cjs","names":[],"sources":["../../../../src/ssr/serializer/transformer.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport { GLOBAL_TSR } from '../constants'\nimport type { Plugin, PluginInfo, SerovalNode } from 'seroval'\nimport type {\n RegisteredConfigType,\n RegisteredSsr,\n SSROption,\n} from '../../router'\nimport type { LooseReturnType } from '../../utils'\nimport type { AnyRoute, ResolveAllSSR } from '../../route'\nimport type { RawStream } from './RawStream'\n\ndeclare const TSR_SERIALIZABLE: unique symbol\nexport type TSR_SERIALIZABLE = typeof TSR_SERIALIZABLE\n\nexport type TsrSerializable = { [TSR_SERIALIZABLE]: true }\n\nexport interface DefaultSerializable {\n number: number\n string: string\n boolean: boolean\n null: null\n undefined: undefined\n bigint: bigint\n Date: Date\n Uint8Array: Uint8Array\n RawStream: RawStream\n TsrSerializable: TsrSerializable\n void: void\n}\n\nexport interface SerializableExtensions extends DefaultSerializable {}\n\nexport type Serializable = SerializableExtensions[keyof SerializableExtensions]\n\nexport type UnionizeSerializationAdaptersInput<\n TAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> = TAdapters[number]['~types']['input']\n\n/**\n * Create a strongly-typed serialization adapter for SSR hydration.\n * Use to register custom types with the router serializer.\n */\nexport function createSerializationAdapter<\n TInput = unknown,\n TOutput = unknown,\n const TExtendsAdapters extends\n | ReadonlyArray<AnySerializationAdapter>\n | never = never,\n>(\n opts: CreateSerializationAdapterOptions<TInput, TOutput, TExtendsAdapters>,\n): SerializationAdapter<TInput, TOutput, TExtendsAdapters> {\n return opts as unknown as SerializationAdapter<\n TInput,\n TOutput,\n TExtendsAdapters\n >\n}\n\nexport interface CreateSerializationAdapterOptions<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter> | never,\n> {\n key: string\n extends?: TExtendsAdapters\n test: (value: unknown) => value is TInput\n toSerializable: (\n value: TInput,\n ) => ValidateSerializable<\n TOutput,\n Serializable | UnionizeSerializationAdaptersInput<TExtendsAdapters>\n >\n fromSerializable: (value: TOutput) => TInput\n}\n\nexport type ValidateSerializable<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? SerializationError<'Function may not be serializable'>\n : T extends RegisteredReadableStream\n ? SerializationError<'JSX is not be serializable'>\n : T extends ReadonlyArray<any>\n ? ValidateSerializableArray<T, TSerializable>\n : T extends Promise<any>\n ? ValidateSerializablePromise<T, TSerializable>\n : T extends ReadableStream<any>\n ? ValidateReadableStream<T, TSerializable>\n : T extends Set<any>\n ? ValidateSerializableSet<T, TSerializable>\n : T extends Map<any, any>\n ? ValidateSerializableMap<T, TSerializable>\n : T extends AsyncGenerator<any, any>\n ? ValidateSerializableAsyncGenerator<T, TSerializable>\n : T extends object\n ? ValidateSerializableMapped<T, TSerializable>\n : SerializationError<'Type may not be serializable'>\n\nexport type ValidateSerializableAsyncGenerator<T, TSerializable> =\n T extends AsyncGenerator<infer T, infer TReturn, infer TNext>\n ? AsyncGenerator<\n ValidateSerializable<T, TSerializable>,\n ValidateSerializable<TReturn, TSerializable>,\n TNext\n >\n : never\n\nexport type ValidateSerializablePromise<T, TSerializable> =\n T extends Promise<infer TAwaited>\n ? Promise<ValidateSerializable<TAwaited, TSerializable>>\n : never\n\nexport type ValidateReadableStream<T, TSerializable> =\n T extends ReadableStream<infer TStreamed>\n ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>>\n : never\n\nexport type ValidateSerializableSet<T, TSerializable> =\n T extends Set<infer TItem>\n ? Set<ValidateSerializable<TItem, TSerializable>>\n : never\n\nexport type ValidateSerializableMap<T, TSerializable> =\n T extends Map<infer TKey, infer TValue>\n ? Map<\n ValidateSerializable<TKey, TSerializable>,\n ValidateSerializable<TValue, TSerializable>\n >\n : never\n\nexport type ValidateSerializableArray<T, TSerializable> = T extends readonly [\n any,\n ...Array<any>,\n]\n ? ValidateSerializableMapped<T, TSerializable>\n : T extends Array<infer U>\n ? Array<ValidateSerializable<U, TSerializable>>\n : T extends ReadonlyArray<infer U>\n ? ReadonlyArray<ValidateSerializable<U, TSerializable>>\n : never\n\nexport type ValidateSerializableMapped<T, TSerializable> = {\n [K in keyof T]: ValidateSerializable<T[K], TSerializable>\n}\n\nconst SERIALIZATION_ERROR = Symbol.for('TSR_SERIALIZATION_ERROR')\n\nexport interface SerializationError<in out TMessage extends string> {\n [SERIALIZATION_ERROR]: TMessage\n}\n\nexport interface SerializationAdapter<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> {\n '~types': SerializationAdapterTypes<TInput, TOutput, TExtendsAdapters>\n key: string\n extends?: TExtendsAdapters\n test: (value: unknown) => value is TInput\n toSerializable: (value: TInput) => TOutput\n fromSerializable: (value: TOutput) => TInput\n}\n\nexport interface SerializationAdapterTypes<\n TInput,\n TOutput,\n TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,\n> {\n input: TInput | UnionizeSerializationAdaptersInput<TExtendsAdapters>\n output: TOutput\n extends: TExtendsAdapters\n}\n\nexport type AnySerializationAdapter = SerializationAdapter<any, any, any>\n\nexport interface AdapterNode extends PluginInfo {\n v: SerovalNode\n}\n\n/** Create a Seroval plugin for server-side serialization only. */\n/* @__NO_SIDE_EFFECTS__ */\nexport function makeSsrSerovalPlugin(\n serializationAdapter: AnySerializationAdapter,\n options: { didRun: boolean },\n): Plugin<any, AdapterNode> {\n return /* @__PURE__ */ createPlugin<any, AdapterNode>({\n tag: '$TSR/t/' + serializationAdapter.key,\n test: serializationAdapter.test,\n parse: {\n stream(value, ctx, _data) {\n return {\n v: ctx.parse(serializationAdapter.toSerializable(value)),\n }\n },\n },\n serialize(node, ctx, _data) {\n options.didRun = true\n return (\n GLOBAL_TSR +\n '.t.get(\"' +\n serializationAdapter.key +\n '\")(' +\n ctx.serialize(node.v) +\n ')'\n )\n },\n // we never deserialize on the server during SSR\n deserialize: undefined as never,\n })\n}\n\n/** Create a Seroval plugin for client/server symmetric (de)serialization. */\n/* @__NO_SIDE_EFFECTS__ */\nexport function makeSerovalPlugin(\n serializationAdapter: AnySerializationAdapter,\n): Plugin<any, AdapterNode> {\n return /* @__PURE__ */ createPlugin<any, AdapterNode>({\n tag: '$TSR/t/' + serializationAdapter.key,\n test: serializationAdapter.test,\n parse: {\n sync(value, ctx, _data) {\n return {\n v: ctx.parse(serializationAdapter.toSerializable(value)),\n }\n },\n async async(value, ctx, _data) {\n return {\n v: await ctx.parse(serializationAdapter.toSerializable(value)),\n }\n },\n stream(value, ctx, _data) {\n return {\n v: ctx.parse(serializationAdapter.toSerializable(value)),\n }\n },\n },\n // we don't generate JS code outside of SSR (for now)\n serialize: undefined as never,\n deserialize(node, ctx, _data) {\n return serializationAdapter.fromSerializable(ctx.deserialize(node.v))\n },\n })\n}\n\nexport type ValidateSerializableInput<TRegister, T> = ValidateSerializable<\n T,\n RegisteredSerializableInput<TRegister>\n>\n\nexport type RegisteredSerializableInput<TRegister> =\n | (unknown extends RegisteredSerializationAdapters<TRegister>\n ? never\n : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter>\n ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input']\n : never)\n | Serializable\n\nexport type RegisteredSerializationAdapters<TRegister> = RegisteredConfigType<\n TRegister,\n 'serializationAdapters'\n>\n\nexport type RegisteredSSROption<TRegister> =\n unknown extends RegisteredConfigType<TRegister, 'defaultSsr'>\n ? SSROption\n : RegisteredConfigType<TRegister, 'defaultSsr'>\n\nexport type ValidateSerializableLifecycleResult<\n TRegister,\n TParentRoute extends AnyRoute,\n TSSR,\n TFn,\n> =\n false extends RegisteredSsr<TRegister>\n ? any\n : ValidateSerializableLifecycleResultSSR<\n TRegister,\n TParentRoute,\n TSSR,\n TFn\n > extends infer TInput\n ? TInput\n : never\n\nexport type ValidateSerializableLifecycleResultSSR<\n TRegister,\n TParentRoute extends AnyRoute,\n TSSR,\n TFn,\n> =\n ResolveAllSSR<TParentRoute, TSSR> extends false\n ? any\n : RegisteredSSROption<TRegister> extends false\n ? any\n : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>\n\nexport type RegisteredReadableStream =\n unknown extends SerializerExtensions['ReadableStream']\n ? never\n : SerializerExtensions['ReadableStream']\n\nexport interface DefaultSerializerExtensions {\n ReadableStream: unknown\n}\n\nexport interface SerializerExtensions extends DefaultSerializerExtensions {}\n"],"mappings":";;;;;;;AA2CA,SAAgB,2BAOd,MACyD;AACzD,QAAO;;;;AAkIT,SAAgB,qBACd,sBACA,SAC0B;AAC1B,QAAuB,iBAAA,GAAA,QAAA,cAA+B;EACpD,KAAK,YAAY,qBAAqB;EACtC,MAAM,qBAAqB;EAC3B,OAAO,EACL,OAAO,OAAO,KAAK,OAAO;AACxB,UAAO,EACL,GAAG,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC,EACzD;KAEJ;EACD,UAAU,MAAM,KAAK,OAAO;AAC1B,WAAQ,SAAS;AACjB,UACE,kBAAA,aACA,cACA,qBAAqB,MACrB,SACA,IAAI,UAAU,KAAK,EAAE,GACrB;;EAIJ,aAAa,KAAA;EACd,CAAC;;;;AAKJ,SAAgB,kBACd,sBAC0B;AAC1B,QAAuB,iBAAA,GAAA,QAAA,cAA+B;EACpD,KAAK,YAAY,qBAAqB;EACtC,MAAM,qBAAqB;EAC3B,OAAO;GACL,KAAK,OAAO,KAAK,OAAO;AACtB,WAAO,EACL,GAAG,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC,EACzD;;GAEH,MAAM,MAAM,OAAO,KAAK,OAAO;AAC7B,WAAO,EACL,GAAG,MAAM,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC,EAC/D;;GAEH,OAAO,OAAO,KAAK,OAAO;AACxB,WAAO,EACL,GAAG,IAAI,MAAM,qBAAqB,eAAe,MAAM,CAAC,EACzD;;GAEJ;EAED,WAAW,KAAA;EACX,YAAY,MAAM,KAAK,OAAO;AAC5B,UAAO,qBAAqB,iBAAiB,IAAI,YAAY,KAAK,EAAE,CAAC;;EAExE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Plugin, SerovalNode } from 'seroval';
1
+ import { Plugin, PluginInfo, SerovalNode } from 'seroval';
2
2
  import { RegisteredConfigType, RegisteredSsr, SSROption } from '../../router.cjs';
3
3
  import { LooseReturnType } from '../../utils.cjs';
4
4
  import { AnyRoute, ResolveAllSSR } from '../../route.cjs';
@@ -19,6 +19,7 @@ export interface DefaultSerializable {
19
19
  Uint8Array: Uint8Array;
20
20
  RawStream: RawStream;
21
21
  TsrSerializable: TsrSerializable;
22
+ void: void;
22
23
  }
23
24
  export interface SerializableExtensions extends DefaultSerializable {
24
25
  }
@@ -36,19 +37,22 @@ export interface CreateSerializationAdapterOptions<TInput, TOutput, TExtendsAdap
36
37
  toSerializable: (value: TInput) => ValidateSerializable<TOutput, Serializable | UnionizeSerializationAdaptersInput<TExtendsAdapters>>;
37
38
  fromSerializable: (value: TOutput) => TInput;
38
39
  }
39
- export type ValidateSerializable<T, TSerializable> = T extends ReadonlyArray<unknown> ? ResolveArrayShape<T, TSerializable, 'input'> : T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : T extends Promise<any> ? ValidateSerializablePromise<T, TSerializable> : T extends ReadableStream<any> ? ValidateReadableStream<T, TSerializable> : T extends Set<any> ? ValidateSerializableSet<T, TSerializable> : T extends Map<any, any> ? ValidateSerializableMap<T, TSerializable> : T extends AsyncGenerator<any, any> ? ValidateSerializableAsyncGenerator<T, TSerializable> : {
40
- [K in keyof T]: ValidateSerializable<T[K], TSerializable>;
41
- };
40
+ export type ValidateSerializable<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? SerializationError<'Function may not be serializable'> : T extends RegisteredReadableStream ? SerializationError<'JSX is not be serializable'> : T extends ReadonlyArray<any> ? ValidateSerializableArray<T, TSerializable> : T extends Promise<any> ? ValidateSerializablePromise<T, TSerializable> : T extends ReadableStream<any> ? ValidateReadableStream<T, TSerializable> : T extends Set<any> ? ValidateSerializableSet<T, TSerializable> : T extends Map<any, any> ? ValidateSerializableMap<T, TSerializable> : T extends AsyncGenerator<any, any> ? ValidateSerializableAsyncGenerator<T, TSerializable> : T extends object ? ValidateSerializableMapped<T, TSerializable> : SerializationError<'Type may not be serializable'>;
42
41
  export type ValidateSerializableAsyncGenerator<T, TSerializable> = T extends AsyncGenerator<infer T, infer TReturn, infer TNext> ? AsyncGenerator<ValidateSerializable<T, TSerializable>, ValidateSerializable<TReturn, TSerializable>, TNext> : never;
43
42
  export type ValidateSerializablePromise<T, TSerializable> = T extends Promise<infer TAwaited> ? Promise<ValidateSerializable<TAwaited, TSerializable>> : never;
44
43
  export type ValidateReadableStream<T, TSerializable> = T extends ReadableStream<infer TStreamed> ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>> : never;
45
44
  export type ValidateSerializableSet<T, TSerializable> = T extends Set<infer TItem> ? Set<ValidateSerializable<TItem, TSerializable>> : never;
46
45
  export type ValidateSerializableMap<T, TSerializable> = T extends Map<infer TKey, infer TValue> ? Map<ValidateSerializable<TKey, TSerializable>, ValidateSerializable<TValue, TSerializable>> : never;
47
- export type RegisteredReadableStream = unknown extends SerializerExtensions['ReadableStream'] ? never : SerializerExtensions['ReadableStream'];
48
- export interface DefaultSerializerExtensions {
49
- ReadableStream: unknown;
50
- }
51
- export interface SerializerExtensions extends DefaultSerializerExtensions {
46
+ export type ValidateSerializableArray<T, TSerializable> = T extends readonly [
47
+ any,
48
+ ...Array<any>
49
+ ] ? ValidateSerializableMapped<T, TSerializable> : T extends Array<infer U> ? Array<ValidateSerializable<U, TSerializable>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<ValidateSerializable<U, TSerializable>> : never;
50
+ export type ValidateSerializableMapped<T, TSerializable> = {
51
+ [K in keyof T]: ValidateSerializable<T[K], TSerializable>;
52
+ };
53
+ declare const SERIALIZATION_ERROR: unique symbol;
54
+ export interface SerializationError<in out TMessage extends string> {
55
+ [SERIALIZATION_ERROR]: TMessage;
52
56
  }
53
57
  export interface SerializationAdapter<TInput, TOutput, TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>> {
54
58
  '~types': SerializationAdapterTypes<TInput, TOutput, TExtendsAdapters>;
@@ -64,28 +68,25 @@ export interface SerializationAdapterTypes<TInput, TOutput, TExtendsAdapters ext
64
68
  extends: TExtendsAdapters;
65
69
  }
66
70
  export type AnySerializationAdapter = SerializationAdapter<any, any, any>;
71
+ export interface AdapterNode extends PluginInfo {
72
+ v: SerovalNode;
73
+ }
67
74
  /** Create a Seroval plugin for server-side serialization only. */
68
75
  export declare function makeSsrSerovalPlugin(serializationAdapter: AnySerializationAdapter, options: {
69
76
  didRun: boolean;
70
- }): Plugin<any, SerovalNode>;
77
+ }): Plugin<any, AdapterNode>;
71
78
  /** Create a Seroval plugin for client/server symmetric (de)serialization. */
72
- export declare function makeSerovalPlugin(serializationAdapter: AnySerializationAdapter): Plugin<any, SerovalNode>;
79
+ export declare function makeSerovalPlugin(serializationAdapter: AnySerializationAdapter): Plugin<any, AdapterNode>;
73
80
  export type ValidateSerializableInput<TRegister, T> = ValidateSerializable<T, RegisteredSerializableInput<TRegister>>;
74
81
  export type RegisteredSerializableInput<TRegister> = (unknown extends RegisteredSerializationAdapters<TRegister> ? never : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter> ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input'] : never) | Serializable;
75
82
  export type RegisteredSerializationAdapters<TRegister> = RegisteredConfigType<TRegister, 'serializationAdapters'>;
76
- export type ValidateSerializableInputResult<TRegister, T> = ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>;
77
- export type ValidateSerializableResult<T, TSerializable> = T extends ReadonlyArray<unknown> ? ResolveArrayShape<T, TSerializable, 'result'> : T extends TSerializable ? T : unknown extends SerializerExtensions['ReadableStream'] ? {
78
- [K in keyof T]: ValidateSerializableResult<T[K], TSerializable>;
79
- } : T extends SerializerExtensions['ReadableStream'] ? ReadableStream : {
80
- [K in keyof T]: ValidateSerializableResult<T[K], TSerializable>;
81
- };
82
83
  export type RegisteredSSROption<TRegister> = unknown extends RegisteredConfigType<TRegister, 'defaultSsr'> ? SSROption : RegisteredConfigType<TRegister, 'defaultSsr'>;
83
84
  export type ValidateSerializableLifecycleResult<TRegister, TParentRoute extends AnyRoute, TSSR, TFn> = false extends RegisteredSsr<TRegister> ? any : ValidateSerializableLifecycleResultSSR<TRegister, TParentRoute, TSSR, TFn> extends infer TInput ? TInput : never;
84
85
  export type ValidateSerializableLifecycleResultSSR<TRegister, TParentRoute extends AnyRoute, TSSR, TFn> = ResolveAllSSR<TParentRoute, TSSR> extends false ? any : RegisteredSSROption<TRegister> extends false ? any : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>;
85
- type ResolveArrayShape<T extends ReadonlyArray<unknown>, TSerializable, TMode extends 'input' | 'result'> = number extends T['length'] ? T extends Array<infer U> ? Array<ArrayModeResult<TMode, U, TSerializable>> : ReadonlyArray<ArrayModeResult<TMode, T[number], TSerializable>> : ResolveTupleShape<T, TSerializable, TMode>;
86
- type ResolveTupleShape<T extends ReadonlyArray<unknown>, TSerializable, TMode extends 'input' | 'result'> = T extends readonly [infer THead, ...infer TTail] ? readonly [
87
- ArrayModeResult<TMode, THead, TSerializable>,
88
- ...ResolveTupleShape<Readonly<TTail>, TSerializable, TMode>
89
- ] : T;
90
- type ArrayModeResult<TMode extends 'input' | 'result', TValue, TSerializable> = TMode extends 'input' ? ValidateSerializable<TValue, TSerializable> : ValidateSerializableResult<TValue, TSerializable>;
86
+ export type RegisteredReadableStream = unknown extends SerializerExtensions['ReadableStream'] ? never : SerializerExtensions['ReadableStream'];
87
+ export interface DefaultSerializerExtensions {
88
+ ReadableStream: unknown;
89
+ }
90
+ export interface SerializerExtensions extends DefaultSerializerExtensions {
91
+ }
91
92
  export {};
@@ -41,7 +41,7 @@ async function hydrate(router) {
41
41
  router.ssr = { manifest };
42
42
  const nonce = document.querySelector("meta[property=\"csp-nonce\"]")?.content;
43
43
  router.options.ssr = { nonce };
44
- const matches = router.matchRoutes(router.stores.location.state);
44
+ const matches = router.matchRoutes(router.stores.location.get());
45
45
  const routeChunkPromise = Promise.all(matches.map((match) => router.loadRouteChunk(router.looseRoutesById[match.routeId])));
46
46
  function setMatchForcePending(match) {
47
47
  const pendingMinMs = router.looseRoutesById[match.routeId].options.pendingMinMs ?? router.options.defaultPendingMinMs;
@@ -84,10 +84,10 @@ async function hydrate(router) {
84
84
  }
85
85
  }
86
86
  });
87
- router.stores.setActiveMatches(matches);
87
+ router.stores.setMatches(matches);
88
88
  await router.options.hydrate?.(dehydratedData);
89
- const activeMatches = router.stores.activeMatchesSnapshot.state;
90
- const location = router.stores.location.state;
89
+ const activeMatches = router.stores.matches.get();
90
+ const location = router.stores.location.get();
91
91
  await Promise.all(activeMatches.map(async (match) => {
92
92
  try {
93
93
  const route = router.looseRoutesById[match.routeId];
@@ -146,7 +146,7 @@ async function hydrate(router) {
146
146
  matches.forEach((match) => {
147
147
  match._nonReactive.dehydrated = void 0;
148
148
  });
149
- router.stores.resolvedLocation.setState(() => router.stores.location.state);
149
+ router.stores.resolvedLocation.set(router.stores.location.get());
150
150
  return routeChunkPromise;
151
151
  }
152
152
  const loadPromise = Promise.resolve().then(() => router.load()).catch((err) => {
@@ -163,10 +163,10 @@ async function hydrate(router) {
163
163
  match._nonReactive.displayPendingPromise = loadPromise;
164
164
  loadPromise.then(() => {
165
165
  router.batch(() => {
166
- if (router.stores.status.state === "pending") router.batch(() => {
167
- router.stores.status.setState(() => "idle");
168
- router.stores.resolvedLocation.setState(() => router.stores.location.state);
169
- });
166
+ if (router.stores.status.get() === "pending") {
167
+ router.stores.status.set("idle");
168
+ router.stores.resolvedLocation.set(router.stores.location.get());
169
+ }
170
170
  router.updateMatch(match.id, (prev) => ({
171
171
  ...prev,
172
172
  _displayPending: void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-client.cjs","names":[],"sources":["../../../src/ssr/ssr-client.ts"],"sourcesContent":["import { invariant } from '../invariant'\nimport { isNotFound } from '../not-found'\nimport { createControlledPromise } from '../utils'\nimport { hydrateSsrMatchId } from './ssr-match-id'\nimport type { GLOBAL_SEROVAL, GLOBAL_TSR } from './constants'\nimport type { DehydratedMatch, TsrSsrGlobal } from './types'\nimport type { AnyRouteMatch } from '../Matches'\nimport type { AnyRouter } from '../router'\nimport type { RouteContextOptions } from '../route'\nimport type { AnySerializationAdapter } from './serializer/transformer'\n\ndeclare global {\n interface Window {\n [GLOBAL_TSR]?: TsrSsrGlobal\n [GLOBAL_SEROVAL]?: any\n }\n}\n\nfunction hydrateMatch(\n match: AnyRouteMatch,\n deyhydratedMatch: DehydratedMatch,\n): void {\n match.id = deyhydratedMatch.i\n match.__beforeLoadContext = deyhydratedMatch.b\n match.loaderData = deyhydratedMatch.l\n match.status = deyhydratedMatch.s\n match.ssr = deyhydratedMatch.ssr\n match.updatedAt = deyhydratedMatch.u\n match.error = deyhydratedMatch.e\n // Only hydrate global-not-found when a defined value is present in the\n // dehydrated payload. If omitted, preserve the value computed from the\n // current client location (important for SPA fallback HTML served at unknown\n // URLs, where dehydrated matches may come from `/` but client matching marks\n // root as globalNotFound).\n if (deyhydratedMatch.g !== undefined) {\n match.globalNotFound = deyhydratedMatch.g\n }\n}\n\nexport async function hydrate(router: AnyRouter): Promise<any> {\n if (!window.$_TSR) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!',\n )\n }\n\n invariant()\n }\n\n const serializationAdapters = router.options.serializationAdapters as\n | Array<AnySerializationAdapter>\n | undefined\n\n if (serializationAdapters?.length) {\n const fromSerializableMap = new Map()\n serializationAdapters.forEach((adapter) => {\n fromSerializableMap.set(adapter.key, adapter.fromSerializable)\n })\n window.$_TSR.t = fromSerializableMap\n window.$_TSR.buffer.forEach((script) => script())\n }\n window.$_TSR.initialized = true\n\n if (!window.$_TSR.router) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',\n )\n }\n\n invariant()\n }\n\n const dehydratedRouter = window.$_TSR.router\n dehydratedRouter.matches.forEach((dehydratedMatch) => {\n dehydratedMatch.i = hydrateSsrMatchId(dehydratedMatch.i)\n })\n if (dehydratedRouter.lastMatchId) {\n dehydratedRouter.lastMatchId = hydrateSsrMatchId(\n dehydratedRouter.lastMatchId,\n )\n }\n const { manifest, dehydratedData, lastMatchId } = dehydratedRouter\n\n router.ssr = {\n manifest,\n }\n const meta = document.querySelector('meta[property=\"csp-nonce\"]') as\n | HTMLMetaElement\n | undefined\n const nonce = meta?.content\n router.options.ssr = {\n nonce,\n }\n\n // Hydrate the router state\n const matches = router.matchRoutes(router.stores.location.state)\n\n // kick off loading the route chunks\n const routeChunkPromise = Promise.all(\n matches.map((match) =>\n router.loadRouteChunk(router.looseRoutesById[match.routeId]!),\n ),\n )\n\n function setMatchForcePending(match: AnyRouteMatch) {\n // usually the minPendingPromise is created in the Match component if a pending match is rendered\n // however, this might be too late if the match synchronously resolves\n const route = router.looseRoutesById[match.routeId]!\n const pendingMinMs =\n route.options.pendingMinMs ?? router.options.defaultPendingMinMs\n if (pendingMinMs) {\n const minPendingPromise = createControlledPromise<void>()\n match._nonReactive.minPendingPromise = minPendingPromise\n match._forcePending = true\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n router.updateMatch(match.id, (prev) => {\n prev._nonReactive.minPendingPromise = undefined\n return {\n ...prev,\n _forcePending: undefined,\n }\n })\n }, pendingMinMs)\n }\n }\n\n function setRouteSsr(match: AnyRouteMatch) {\n const route = router.looseRoutesById[match.routeId]\n if (route) {\n route.options.ssr = match.ssr\n }\n }\n // Right after hydration and before the first render, we need to rehydrate each match\n // First step is to reyhdrate loaderData and __beforeLoadContext\n let firstNonSsrMatchIndex: number | undefined = undefined\n matches.forEach((match) => {\n const dehydratedMatch = dehydratedRouter.matches.find(\n (d) => d.i === match.id,\n )\n if (!dehydratedMatch) {\n match._nonReactive.dehydrated = false\n match.ssr = false\n setRouteSsr(match)\n return\n }\n\n hydrateMatch(match, dehydratedMatch)\n setRouteSsr(match)\n\n match._nonReactive.dehydrated = match.ssr !== false\n\n if (match.ssr === 'data-only' || match.ssr === false) {\n if (firstNonSsrMatchIndex === undefined) {\n firstNonSsrMatchIndex = match.index\n setMatchForcePending(match)\n }\n }\n })\n\n router.stores.setActiveMatches(matches)\n\n // Allow the user to handle custom hydration data\n await router.options.hydrate?.(dehydratedData)\n\n // now that all necessary data is hydrated:\n // 1) fully reconstruct the route context\n // 2) execute `head()` and `scripts()` for each match\n const activeMatches = router.stores.activeMatchesSnapshot.state\n const location = router.stores.location.state\n await Promise.all(\n activeMatches.map(async (match) => {\n try {\n const route = router.looseRoutesById[match.routeId]!\n\n const parentMatch = activeMatches[match.index - 1]\n const parentContext = parentMatch?.context ?? router.options.context\n\n // `context()` was already executed by `matchRoutes`, however route context was not yet fully reconstructed\n // so run it again and merge route context\n if (route.options.context) {\n const contextFnContext: RouteContextOptions<any, any, any, any, any> =\n {\n deps: match.loaderDeps,\n params: match.params,\n context: parentContext ?? {},\n location,\n navigate: (opts: any) =>\n router.navigate({\n ...opts,\n _fromLocation: location,\n }),\n buildLocation: router.buildLocation,\n cause: match.cause,\n abortController: match.abortController,\n preload: false,\n matches,\n routeId: route.id,\n }\n match.__routeContext =\n route.options.context(contextFnContext) ?? undefined\n }\n\n match.context = {\n ...parentContext,\n ...match.__routeContext,\n ...match.__beforeLoadContext,\n }\n\n const assetContext = {\n ssr: router.options.ssr,\n matches: activeMatches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n const headFnContent = await route.options.head?.(assetContext)\n\n const scripts = await route.options.scripts?.(assetContext)\n\n match.meta = headFnContent?.meta\n match.links = headFnContent?.links\n match.headScripts = headFnContent?.scripts\n match.styles = headFnContent?.styles\n match.scripts = scripts\n } catch (err) {\n if (isNotFound(err)) {\n match.error = { isNotFound: true }\n console.error(\n `NotFound error during hydration for routeId: ${match.routeId}`,\n err,\n )\n } else {\n match.error = err as any\n console.error(\n `Error during hydration for route ${match.routeId}:`,\n err,\n )\n throw err\n }\n }\n }),\n )\n\n const isSpaMode = matches[matches.length - 1]!.id !== lastMatchId\n const hasSsrFalseMatches = matches.some((m) => m.ssr === false)\n // all matches have data from the server and we are not in SPA mode so we don't need to kick of router.load()\n if (!hasSsrFalseMatches && !isSpaMode) {\n matches.forEach((match) => {\n // remove the dehydrated flag since we won't run router.load() which would remove it\n match._nonReactive.dehydrated = undefined\n })\n // Mark the current location as resolved so that later load cycles\n // (e.g. preloads, invalidations) don't mistakenly detect a href change\n // (resolvedLocation defaults to undefined and router.load() is skipped\n // in the normal SSR hydration path).\n router.stores.resolvedLocation.setState(() => router.stores.location.state)\n return routeChunkPromise\n }\n\n // schedule router.load() to run after the next tick so we can store the promise in the match before loading starts\n const loadPromise = Promise.resolve()\n .then(() => router.load())\n .catch((err) => {\n console.error('Error during router hydration:', err)\n })\n\n // in SPA mode we need to keep the first match below the root route pending until router.load() is finished\n // this will prevent that other pending components are rendered but hydration is not blocked\n if (isSpaMode) {\n const match = matches[1]\n if (!match) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find a match below the root match in SPA mode.',\n )\n }\n\n invariant()\n }\n setMatchForcePending(match)\n\n match._displayPending = true\n match._nonReactive.displayPendingPromise = loadPromise\n\n loadPromise.then(() => {\n router.batch(() => {\n // ensure router is not in status 'pending' anymore\n // this usually happens in Transitioner but if loading synchronously resolves,\n // Transitioner won't be rendered while loading so it cannot track the change from loading:true to loading:false\n if (router.stores.status.state === 'pending') {\n router.batch(() => {\n router.stores.status.setState(() => 'idle')\n router.stores.resolvedLocation.setState(\n () => router.stores.location.state,\n )\n })\n }\n // hide the pending component once the load is finished\n router.updateMatch(match.id, (prev) => ({\n ...prev,\n _displayPending: undefined,\n displayPendingPromise: undefined,\n }))\n })\n })\n }\n return routeChunkPromise\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ssr-client.cjs","names":[],"sources":["../../../src/ssr/ssr-client.ts"],"sourcesContent":["import { invariant } from '../invariant'\nimport { isNotFound } from '../not-found'\nimport { createControlledPromise } from '../utils'\nimport { hydrateSsrMatchId } from './ssr-match-id'\nimport type { GLOBAL_SEROVAL, GLOBAL_TSR } from './constants'\nimport type { DehydratedMatch, TsrSsrGlobal } from './types'\nimport type { AnyRouteMatch } from '../Matches'\nimport type { AnyRouter } from '../router'\nimport type { RouteContextOptions } from '../route'\nimport type { AnySerializationAdapter } from './serializer/transformer'\n\ndeclare global {\n interface Window {\n [GLOBAL_TSR]?: TsrSsrGlobal\n [GLOBAL_SEROVAL]?: any\n }\n}\n\nfunction hydrateMatch(\n match: AnyRouteMatch,\n deyhydratedMatch: DehydratedMatch,\n): void {\n match.id = deyhydratedMatch.i\n match.__beforeLoadContext = deyhydratedMatch.b\n match.loaderData = deyhydratedMatch.l\n match.status = deyhydratedMatch.s\n match.ssr = deyhydratedMatch.ssr\n match.updatedAt = deyhydratedMatch.u\n match.error = deyhydratedMatch.e\n // Only hydrate global-not-found when a defined value is present in the\n // dehydrated payload. If omitted, preserve the value computed from the\n // current client location (important for SPA fallback HTML served at unknown\n // URLs, where dehydrated matches may come from `/` but client matching marks\n // root as globalNotFound).\n if (deyhydratedMatch.g !== undefined) {\n match.globalNotFound = deyhydratedMatch.g\n }\n}\n\nexport async function hydrate(router: AnyRouter): Promise<any> {\n if (!window.$_TSR) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!',\n )\n }\n\n invariant()\n }\n\n const serializationAdapters = router.options.serializationAdapters as\n | Array<AnySerializationAdapter>\n | undefined\n\n if (serializationAdapters?.length) {\n const fromSerializableMap = new Map()\n serializationAdapters.forEach((adapter) => {\n fromSerializableMap.set(adapter.key, adapter.fromSerializable)\n })\n window.$_TSR.t = fromSerializableMap\n window.$_TSR.buffer.forEach((script) => script())\n }\n window.$_TSR.initialized = true\n\n if (!window.$_TSR.router) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',\n )\n }\n\n invariant()\n }\n\n const dehydratedRouter = window.$_TSR.router\n dehydratedRouter.matches.forEach((dehydratedMatch) => {\n dehydratedMatch.i = hydrateSsrMatchId(dehydratedMatch.i)\n })\n if (dehydratedRouter.lastMatchId) {\n dehydratedRouter.lastMatchId = hydrateSsrMatchId(\n dehydratedRouter.lastMatchId,\n )\n }\n const { manifest, dehydratedData, lastMatchId } = dehydratedRouter\n\n router.ssr = {\n manifest,\n }\n const meta = document.querySelector('meta[property=\"csp-nonce\"]') as\n | HTMLMetaElement\n | undefined\n const nonce = meta?.content\n router.options.ssr = {\n nonce,\n }\n\n // Hydrate the router state\n const matches = router.matchRoutes(router.stores.location.get())\n\n // kick off loading the route chunks\n const routeChunkPromise = Promise.all(\n matches.map((match) =>\n router.loadRouteChunk(router.looseRoutesById[match.routeId]!),\n ),\n )\n\n function setMatchForcePending(match: AnyRouteMatch) {\n // usually the minPendingPromise is created in the Match component if a pending match is rendered\n // however, this might be too late if the match synchronously resolves\n const route = router.looseRoutesById[match.routeId]!\n const pendingMinMs =\n route.options.pendingMinMs ?? router.options.defaultPendingMinMs\n if (pendingMinMs) {\n const minPendingPromise = createControlledPromise<void>()\n match._nonReactive.minPendingPromise = minPendingPromise\n match._forcePending = true\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n router.updateMatch(match.id, (prev) => {\n prev._nonReactive.minPendingPromise = undefined\n return {\n ...prev,\n _forcePending: undefined,\n }\n })\n }, pendingMinMs)\n }\n }\n\n function setRouteSsr(match: AnyRouteMatch) {\n const route = router.looseRoutesById[match.routeId]\n if (route) {\n route.options.ssr = match.ssr\n }\n }\n // Right after hydration and before the first render, we need to rehydrate each match\n // First step is to reyhdrate loaderData and __beforeLoadContext\n let firstNonSsrMatchIndex: number | undefined = undefined\n matches.forEach((match) => {\n const dehydratedMatch = dehydratedRouter.matches.find(\n (d) => d.i === match.id,\n )\n if (!dehydratedMatch) {\n match._nonReactive.dehydrated = false\n match.ssr = false\n setRouteSsr(match)\n return\n }\n\n hydrateMatch(match, dehydratedMatch)\n setRouteSsr(match)\n\n match._nonReactive.dehydrated = match.ssr !== false\n\n if (match.ssr === 'data-only' || match.ssr === false) {\n if (firstNonSsrMatchIndex === undefined) {\n firstNonSsrMatchIndex = match.index\n setMatchForcePending(match)\n }\n }\n })\n\n router.stores.setMatches(matches)\n\n // Allow the user to handle custom hydration data\n await router.options.hydrate?.(dehydratedData)\n\n // now that all necessary data is hydrated:\n // 1) fully reconstruct the route context\n // 2) execute `head()` and `scripts()` for each match\n const activeMatches = router.stores.matches.get()\n const location = router.stores.location.get()\n await Promise.all(\n activeMatches.map(async (match) => {\n try {\n const route = router.looseRoutesById[match.routeId]!\n\n const parentMatch = activeMatches[match.index - 1]\n const parentContext = parentMatch?.context ?? router.options.context\n\n // `context()` was already executed by `matchRoutes`, however route context was not yet fully reconstructed\n // so run it again and merge route context\n if (route.options.context) {\n const contextFnContext: RouteContextOptions<any, any, any, any, any> =\n {\n deps: match.loaderDeps,\n params: match.params,\n context: parentContext ?? {},\n location,\n navigate: (opts: any) =>\n router.navigate({\n ...opts,\n _fromLocation: location,\n }),\n buildLocation: router.buildLocation,\n cause: match.cause,\n abortController: match.abortController,\n preload: false,\n matches,\n routeId: route.id,\n }\n match.__routeContext =\n route.options.context(contextFnContext) ?? undefined\n }\n\n match.context = {\n ...parentContext,\n ...match.__routeContext,\n ...match.__beforeLoadContext,\n }\n\n const assetContext = {\n ssr: router.options.ssr,\n matches: activeMatches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n const headFnContent = await route.options.head?.(assetContext)\n\n const scripts = await route.options.scripts?.(assetContext)\n\n match.meta = headFnContent?.meta\n match.links = headFnContent?.links\n match.headScripts = headFnContent?.scripts\n match.styles = headFnContent?.styles\n match.scripts = scripts\n } catch (err) {\n if (isNotFound(err)) {\n match.error = { isNotFound: true }\n console.error(\n `NotFound error during hydration for routeId: ${match.routeId}`,\n err,\n )\n } else {\n match.error = err as any\n console.error(\n `Error during hydration for route ${match.routeId}:`,\n err,\n )\n throw err\n }\n }\n }),\n )\n\n const isSpaMode = matches[matches.length - 1]!.id !== lastMatchId\n const hasSsrFalseMatches = matches.some((m) => m.ssr === false)\n // all matches have data from the server and we are not in SPA mode so we don't need to kick of router.load()\n if (!hasSsrFalseMatches && !isSpaMode) {\n matches.forEach((match) => {\n // remove the dehydrated flag since we won't run router.load() which would remove it\n match._nonReactive.dehydrated = undefined\n })\n // Mark the current location as resolved so that later load cycles\n // (e.g. preloads, invalidations) don't mistakenly detect a href change\n // (resolvedLocation defaults to undefined and router.load() is skipped\n // in the normal SSR hydration path).\n router.stores.resolvedLocation.set(router.stores.location.get())\n return routeChunkPromise\n }\n\n // schedule router.load() to run after the next tick so we can store the promise in the match before loading starts\n const loadPromise = Promise.resolve()\n .then(() => router.load())\n .catch((err) => {\n console.error('Error during router hydration:', err)\n })\n\n // in SPA mode we need to keep the first match below the root route pending until router.load() is finished\n // this will prevent that other pending components are rendered but hydration is not blocked\n if (isSpaMode) {\n const match = matches[1]\n if (!match) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Invariant failed: Expected to find a match below the root match in SPA mode.',\n )\n }\n\n invariant()\n }\n setMatchForcePending(match)\n\n match._displayPending = true\n match._nonReactive.displayPendingPromise = loadPromise\n\n loadPromise.then(() => {\n router.batch(() => {\n // ensure router is not in status 'pending' anymore\n // this usually happens in Transitioner but if loading synchronously resolves,\n // Transitioner won't be rendered while loading so it cannot track the change from loading:true to loading:false\n if (router.stores.status.get() === 'pending') {\n router.stores.status.set('idle')\n router.stores.resolvedLocation.set(router.stores.location.get())\n }\n // hide the pending component once the load is finished\n router.updateMatch(match.id, (prev) => ({\n ...prev,\n _displayPending: undefined,\n displayPendingPromise: undefined,\n }))\n })\n })\n }\n return routeChunkPromise\n}\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  const require_utils = require("../utils.cjs");
2
2
  const require_invariant = require("../invariant.cjs");
3
3
  const require_lru_cache = require("../lru-cache.cjs");
4
+ const require_root = require("../root.cjs");
5
+ const require_manifest = require("../manifest.cjs");
4
6
  const require_constants = require("./constants.cjs");
5
7
  const require_transformer = require("./serializer/transformer.cjs");
6
8
  const require_seroval_plugins = require("./serializer/seroval-plugins.cjs");
@@ -8,10 +10,10 @@ const require_ssr_match_id = require("./ssr-match-id.cjs");
8
10
  const require_tsrScript = require("./tsrScript.cjs");
9
11
  let seroval = require("seroval");
10
12
  //#region src/ssr/ssr-server.ts
11
- var SCOPE_ID = "tsr";
12
- var TSR_PREFIX = require_constants.GLOBAL_TSR + ".router=";
13
- var P_PREFIX = require_constants.GLOBAL_TSR + ".p(()=>";
14
- var P_SUFFIX = ")";
13
+ const SCOPE_ID = "tsr";
14
+ const TSR_PREFIX = require_constants.GLOBAL_TSR + ".router=";
15
+ const P_PREFIX = require_constants.GLOBAL_TSR + ".p(()=>";
16
+ const P_SUFFIX = ")";
15
17
  function dehydrateMatch(match) {
16
18
  const dehydratedMatch = {
17
19
  i: require_ssr_match_id.dehydrateSsrMatchId(match.id),
@@ -27,7 +29,7 @@ function dehydrateMatch(match) {
27
29
  if (match.globalNotFound) dehydratedMatch.g = true;
28
30
  return dehydratedMatch;
29
31
  }
30
- var INITIAL_SCRIPTS = [(0, seroval.getCrossReferenceHeader)(SCOPE_ID), require_tsrScript.default];
32
+ const INITIAL_SCRIPTS = [(0, seroval.getCrossReferenceHeader)(SCOPE_ID), require_tsrScript.default];
31
33
  var ScriptBuffer = class {
32
34
  constructor(router) {
33
35
  this._scriptBarrierLifted = false;
@@ -91,9 +93,10 @@ var ScriptBuffer = class {
91
93
  this.router = void 0;
92
94
  }
93
95
  };
94
- var isProd = process.env.NODE_ENV === "production";
95
- var MANIFEST_CACHE_SIZE = 100;
96
- var manifestCaches = /* @__PURE__ */ new WeakMap();
96
+ const isProd = process.env.NODE_ENV === "production";
97
+ const MANIFEST_CACHE_SIZE = 100;
98
+ const manifestCaches = /* @__PURE__ */ new WeakMap();
99
+ const inlineCssCaches = /* @__PURE__ */ new WeakMap();
97
100
  function getManifestCache(manifest) {
98
101
  const cache = manifestCaches.get(manifest);
99
102
  if (cache) return cache;
@@ -101,8 +104,85 @@ function getManifestCache(manifest) {
101
104
  manifestCaches.set(manifest, newCache);
102
105
  return newCache;
103
106
  }
104
- function attachRouterServerSsrUtils({ router, manifest }) {
105
- router.ssr = { manifest };
107
+ function getInlineCssCache(manifest) {
108
+ const cache = inlineCssCaches.get(manifest);
109
+ if (cache) return cache;
110
+ const newCache = require_lru_cache.createLRUCache(MANIFEST_CACHE_SIZE);
111
+ inlineCssCaches.set(manifest, newCache);
112
+ return newCache;
113
+ }
114
+ function getInlineCssHrefsForMatches(manifest, matches) {
115
+ const styles = manifest?.inlineCss?.styles;
116
+ if (!styles) return [];
117
+ const seen = /* @__PURE__ */ new Set();
118
+ const hrefs = [];
119
+ for (const match of matches) {
120
+ const assets = manifest?.routes[match.routeId]?.assets ?? [];
121
+ for (const asset of assets) {
122
+ const href = require_manifest.getStylesheetHref(asset);
123
+ if (!href || seen.has(href) || styles[href] === void 0) continue;
124
+ seen.add(href);
125
+ hrefs.push(href);
126
+ }
127
+ }
128
+ return hrefs;
129
+ }
130
+ function getInlineCssForHrefs(manifest, hrefs) {
131
+ const styles = manifest.inlineCss?.styles;
132
+ if (!styles || hrefs.length === 0) return void 0;
133
+ const cacheKey = hrefs.join("\0");
134
+ if (isProd) {
135
+ const cached = getInlineCssCache(manifest).get(cacheKey);
136
+ if (cached !== void 0) return cached;
137
+ }
138
+ const css = hrefs.map((href) => styles[href]).join("");
139
+ if (isProd) getInlineCssCache(manifest).set(cacheKey, css);
140
+ return css;
141
+ }
142
+ function getInlineCssAssetForMatches(manifest, matches) {
143
+ if (!manifest?.inlineCss) return void 0;
144
+ const css = getInlineCssForHrefs(manifest, getInlineCssHrefsForMatches(manifest, matches));
145
+ return css === void 0 ? void 0 : require_manifest.createInlineCssStyleAsset(css);
146
+ }
147
+ function stripInlinedStylesheetAssets(manifest, routes, matches) {
148
+ if (!manifest.inlineCss) return routes;
149
+ const nextRoutes = {};
150
+ for (const [routeId, route] of Object.entries(routes)) {
151
+ const assets = route.assets?.filter((asset) => !require_manifest.isInlinableStylesheet(manifest, asset));
152
+ const nextRoute = { ...route };
153
+ if (assets) if (assets.length > 0) nextRoute.assets = assets;
154
+ else delete nextRoute.assets;
155
+ nextRoutes[routeId] = nextRoute;
156
+ }
157
+ if (getInlineCssAssetForMatches(manifest, matches)) {
158
+ const rootRoute = nextRoutes["__root__"] ?? {};
159
+ nextRoutes[require_root.rootRouteId] = {
160
+ ...rootRoute,
161
+ assets: [require_manifest.createInlineCssPlaceholderAsset(), ...rootRoute.assets ?? []]
162
+ };
163
+ }
164
+ return nextRoutes;
165
+ }
166
+ function attachRouterServerSsrUtils({ router, manifest, getRequestAssets, includeUnmatchedRouteAssets = true }) {
167
+ router.ssr = { get manifest() {
168
+ const requestAssets = getRequestAssets?.();
169
+ const inlineCssAsset = getInlineCssAssetForMatches(manifest, router.stores.matches.get());
170
+ if (!requestAssets?.length && !inlineCssAsset) return manifest;
171
+ return {
172
+ ...manifest,
173
+ routes: {
174
+ ...manifest?.routes,
175
+ [require_root.rootRouteId]: {
176
+ ...manifest?.routes?.[require_root.rootRouteId],
177
+ assets: [
178
+ ...requestAssets ?? [],
179
+ ...inlineCssAsset ? [inlineCssAsset] : [],
180
+ ...manifest?.routes?.["__root__"]?.assets ?? []
181
+ ]
182
+ }
183
+ }
184
+ };
185
+ } };
106
186
  let _dehydrated = false;
107
187
  let _serializationFinished = false;
108
188
  const renderFinishedListeners = [];
@@ -120,18 +200,18 @@ function attachRouterServerSsrUtils({ router, manifest }) {
120
200
  const html = `<script${router.options.ssr?.nonce ? ` nonce='${router.options.ssr.nonce}'` : ""}>${script}<\/script>`;
121
201
  router.serverSsr.injectHtml(html);
122
202
  },
123
- dehydrate: async () => {
203
+ dehydrate: async (opts) => {
124
204
  if (_dehydrated) {
125
205
  if (process.env.NODE_ENV !== "production") throw new Error("Invariant failed: router is already dehydrated!");
126
206
  require_invariant.invariant();
127
207
  }
128
- let matchesToDehydrate = router.stores.activeMatchesSnapshot.state;
208
+ let matchesToDehydrate = router.stores.matches.get();
129
209
  if (router.isShell()) matchesToDehydrate = matchesToDehydrate.slice(0, 1);
130
210
  const matches = matchesToDehydrate.map(dehydrateMatch);
131
211
  let manifestToDehydrate = void 0;
132
212
  if (manifest) {
133
213
  const currentRouteIdsList = matchesToDehydrate.map((m) => m.routeId);
134
- const manifestCacheKey = currentRouteIdsList.join("\0");
214
+ const manifestCacheKey = `${currentRouteIdsList.join("\0")}\0includeUnmatchedRouteAssets=${includeUnmatchedRouteAssets}`;
135
215
  let filteredRoutes;
136
216
  if (isProd) filteredRoutes = getManifestCache(manifest).get(manifestCacheKey);
137
217
  if (!filteredRoutes) {
@@ -140,12 +220,19 @@ function attachRouterServerSsrUtils({ router, manifest }) {
140
220
  for (const routeId in manifest.routes) {
141
221
  const routeManifest = manifest.routes[routeId];
142
222
  if (currentRouteIds.has(routeId)) nextFilteredRoutes[routeId] = routeManifest;
143
- else if (routeManifest.assets && routeManifest.assets.length > 0) nextFilteredRoutes[routeId] = { assets: routeManifest.assets };
223
+ else if (includeUnmatchedRouteAssets && routeManifest.assets && routeManifest.assets.length > 0) nextFilteredRoutes[routeId] = { assets: routeManifest.assets };
144
224
  }
145
- if (isProd) getManifestCache(manifest).set(manifestCacheKey, nextFilteredRoutes);
146
- filteredRoutes = nextFilteredRoutes;
225
+ filteredRoutes = stripInlinedStylesheetAssets(manifest, nextFilteredRoutes, matchesToDehydrate);
226
+ if (isProd) getManifestCache(manifest).set(manifestCacheKey, filteredRoutes);
227
+ }
228
+ manifestToDehydrate = { routes: { ...filteredRoutes } };
229
+ if (opts?.requestAssets?.length) {
230
+ const existingRoot = manifestToDehydrate.routes[require_root.rootRouteId];
231
+ manifestToDehydrate.routes[require_root.rootRouteId] = {
232
+ ...existingRoot,
233
+ assets: [...opts.requestAssets, ...existingRoot?.assets ?? []]
234
+ };
147
235
  }
148
- manifestToDehydrate = { routes: filteredRoutes };
149
236
  }
150
237
  const dehydratedRouter = {
151
238
  manifest: manifestToDehydrate,
@@ -158,7 +245,7 @@ function attachRouterServerSsrUtils({ router, manifest }) {
158
245
  _dehydrated = true;
159
246
  const trackPlugins = { didRun: false };
160
247
  const serializationAdapters = router.options.serializationAdapters;
161
- const plugins = serializationAdapters ? serializationAdapters.map((t) => require_transformer.makeSsrSerovalPlugin(t, trackPlugins)).concat(require_seroval_plugins.defaultSerovalPlugins) : require_seroval_plugins.defaultSerovalPlugins;
248
+ const plugins = serializationAdapters ? serializationAdapters.map((t) => /* @__PURE__ */ require_transformer.makeSsrSerovalPlugin(t, trackPlugins)).concat(require_seroval_plugins.defaultSerovalPlugins) : require_seroval_plugins.defaultSerovalPlugins;
162
249
  const signalSerializationComplete = () => {
163
250
  _serializationFinished = true;
164
251
  try {
@@ -179,15 +266,16 @@ function attachRouterServerSsrUtils({ router, manifest }) {
179
266
  if (trackPlugins.didRun) serialized = P_PREFIX + serialized + P_SUFFIX;
180
267
  scriptBuffer.enqueue(serialized);
181
268
  },
269
+ onError: (err) => {
270
+ console.error("Serialization error:", err);
271
+ if (err && err.stack) console.error(err.stack);
272
+ signalSerializationComplete();
273
+ },
182
274
  scopeId: SCOPE_ID,
183
275
  onDone: () => {
184
276
  scriptBuffer.enqueue(require_constants.GLOBAL_TSR + ".e()");
185
277
  scriptBuffer.flush();
186
278
  signalSerializationComplete();
187
- },
188
- onError: (err) => {
189
- console.error("Serialization error:", err);
190
- signalSerializationComplete();
191
279
  }
192
280
  });
193
281
  },