@tanstack/router-core 1.132.0-alpha.4 → 1.132.0-alpha.8

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 (54) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +2 -2
  3. package/dist/cjs/config.cjs +10 -0
  4. package/dist/cjs/config.cjs.map +1 -0
  5. package/dist/cjs/config.d.cts +17 -0
  6. package/dist/cjs/fileRoute.d.cts +3 -2
  7. package/dist/cjs/index.cjs +2 -0
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/index.d.cts +3 -2
  10. package/dist/cjs/load-matches.cjs.map +1 -1
  11. package/dist/cjs/route.cjs.map +1 -1
  12. package/dist/cjs/route.d.cts +42 -37
  13. package/dist/cjs/router.cjs +25 -26
  14. package/dist/cjs/router.cjs.map +1 -1
  15. package/dist/cjs/router.d.cts +19 -13
  16. package/dist/cjs/ssr/serializer/transformer.cjs +14 -12
  17. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  18. package/dist/cjs/ssr/serializer/transformer.d.cts +53 -15
  19. package/dist/cjs/ssr/server.d.cts +5 -0
  20. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  21. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  22. package/dist/esm/Matches.d.ts +2 -2
  23. package/dist/esm/Matches.js.map +1 -1
  24. package/dist/esm/config.d.ts +17 -0
  25. package/dist/esm/config.js +10 -0
  26. package/dist/esm/config.js.map +1 -0
  27. package/dist/esm/fileRoute.d.ts +3 -2
  28. package/dist/esm/index.d.ts +3 -2
  29. package/dist/esm/index.js +2 -0
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/load-matches.js.map +1 -1
  32. package/dist/esm/route.d.ts +42 -37
  33. package/dist/esm/route.js.map +1 -1
  34. package/dist/esm/router.d.ts +19 -13
  35. package/dist/esm/router.js +25 -26
  36. package/dist/esm/router.js.map +1 -1
  37. package/dist/esm/ssr/serializer/transformer.d.ts +53 -15
  38. package/dist/esm/ssr/serializer/transformer.js +14 -12
  39. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  40. package/dist/esm/ssr/server.d.ts +5 -0
  41. package/dist/esm/ssr/ssr-client.js.map +1 -1
  42. package/dist/esm/ssr/ssr-server.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/Matches.ts +2 -2
  45. package/src/config.ts +42 -0
  46. package/src/fileRoute.ts +15 -3
  47. package/src/index.ts +13 -1
  48. package/src/load-matches.ts +2 -2
  49. package/src/route.ts +136 -33
  50. package/src/router.ts +59 -64
  51. package/src/ssr/serializer/transformer.ts +168 -31
  52. package/src/ssr/server.ts +6 -0
  53. package/src/ssr/ssr-client.ts +2 -2
  54. package/src/ssr/ssr-server.ts +2 -2
@@ -13,6 +13,8 @@ import { BuildLocationFn, CommitLocationOptions, NavigateFn } from './RouterProv
13
13
  import { Manifest } from './manifest.cjs';
14
14
  import { AnySchema } from './validators.cjs';
15
15
  import { NavigateOptions, ResolveRelativePath, ToOptions } from './link.cjs';
16
+ import { AnySerializationAdapter } from './ssr/serializer/transformer.cjs';
17
+ import { AnyRouterConfig } from './config.cjs';
16
18
  export type ControllablePromise<T = any> = Promise<T> & {
17
19
  resolve: (value: T) => void;
18
20
  reject: (value?: any) => void;
@@ -20,6 +22,8 @@ export type ControllablePromise<T = any> = Promise<T> & {
20
22
  export type InjectedHtmlEntry = Promise<string>;
21
23
  export interface DefaultRegister {
22
24
  router: AnyRouter;
25
+ config: AnyRouterConfig;
26
+ ssr: SSROption;
23
27
  }
24
28
  export interface Register extends DefaultRegister {
25
29
  }
@@ -29,7 +33,8 @@ export interface DefaultRouterOptionsExtensions {
29
33
  }
30
34
  export interface RouterOptionsExtensions extends DefaultRouterOptionsExtensions {
31
35
  }
32
- export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>, TTransformerConfig = any> extends RouterOptionsExtensions {
36
+ export type SSROption = boolean | 'data-only';
37
+ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>> extends RouterOptionsExtensions {
33
38
  /**
34
39
  * The history object that will be used to manage the browser history.
35
40
  *
@@ -262,7 +267,7 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
262
267
  *
263
268
  * @default true
264
269
  */
265
- defaultSsr?: boolean | 'data-only';
270
+ defaultSsr?: SSROption;
266
271
  search?: {
267
272
  /**
268
273
  * Configures how unknown search params (= not returned by any `validateSearch`) are treated.
@@ -322,7 +327,7 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
322
327
  * @default false
323
328
  */
324
329
  disableGlobalCatchBoundary?: boolean;
325
- serializationAdapters?: TTransformerConfig;
330
+ serializationAdapters?: ReadonlyArray<AnySerializationAdapter>;
326
331
  }
327
332
  export interface RouterState<in out TRouteTree extends AnyRoute = AnyRoute, in out TRouteMatch = MakeRouteMatchUnion> {
328
333
  status: 'pending' | 'idle';
@@ -403,16 +408,16 @@ export type RouterContextOptions<TRouteTree extends AnyRoute> = AnyContext exten
403
408
  } : {
404
409
  context: InferRouterContext<TRouteTree>;
405
410
  };
406
- export type RouterConstructorOptions<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory, TDehydrated extends Record<string, any>, TTransformerConfig> = Omit<RouterOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>, 'context'> & RouterContextOptions<TRouteTree>;
411
+ export type RouterConstructorOptions<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory, TDehydrated extends Record<string, any>> = Omit<RouterOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>, 'context'> & RouterContextOptions<TRouteTree>;
407
412
  export type PreloadRouteFn<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory> = <TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string | undefined = undefined, TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''>(opts: NavigateOptions<RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory>, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<Array<AnyRouteMatch> | undefined>;
408
413
  export type MatchRouteFn<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory> = <TFrom extends RoutePaths<TRouteTree> = '/', TTo extends string | undefined = undefined, TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory>, TFrom, TTo>, opts?: MatchRouteOptions) => false | RouteById<TRouteTree, TResolved>['types']['allParams'];
409
- export type UpdateFn<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory, TDehydrated extends Record<string, any>, TTransformerConfig extends any> = (newOptions: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>) => void;
414
+ export type UpdateFn<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDefaultStructuralSharingOption extends boolean, TRouterHistory extends RouterHistory, TDehydrated extends Record<string, any>> = (newOptions: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>) => void;
410
415
  export type InvalidateFn<TRouter extends AnyRouter> = (opts?: {
411
416
  filter?: (d: MakeRouteMatchUnion<TRouter>) => boolean;
412
417
  sync?: boolean;
413
418
  forcePending?: boolean;
414
419
  }) => Promise<void>;
415
- export type ParseLocationFn<TRouteTree extends AnyRoute> = (previousLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>, locationToParse?: HistoryLocation) => ParsedLocation<FullSearchSchema<TRouteTree>>;
420
+ export type ParseLocationFn<TRouteTree extends AnyRoute> = (locationToParse: HistoryLocation, previousLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>) => ParsedLocation<FullSearchSchema<TRouteTree>>;
416
421
  export type GetMatchRoutesFn = (pathname: string, routePathname: string | undefined) => {
417
422
  matchedRoutes: Array<AnyRoute>;
418
423
  routeParams: Record<string, string>;
@@ -449,8 +454,8 @@ export interface ServerSsr {
449
454
  onRenderFinished: (listener: () => void) => void;
450
455
  dehydrate: () => Promise<void>;
451
456
  }
452
- export type AnyRouterWithContext<TContext> = RouterCore<AnyRouteWithContext<TContext>, any, any, any, any, any>;
453
- export type AnyRouter = RouterCore<any, any, any, any, any, any>;
457
+ export type AnyRouterWithContext<TContext> = RouterCore<AnyRouteWithContext<TContext>, any, any, any, any>;
458
+ export type AnyRouter = RouterCore<any, any, any, any, any>;
454
459
  export interface ViewTransitionOptions {
455
460
  types: Array<string> | ((locationChangeInfo: {
456
461
  fromLocation?: ParsedLocation;
@@ -477,8 +482,8 @@ export declare function getLocationChangeInfo(routerState: {
477
482
  hrefChanged: boolean;
478
483
  hashChanged: boolean;
479
484
  };
480
- export type CreateRouterFn = <TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption = 'never', TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>, TTransformerConfig = any>(options: undefined extends number ? 'strictNullChecks must be enabled in tsconfig.json' : RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>) => RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>;
481
- export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrailingSlashOption extends TrailingSlashOption, in out TDefaultStructuralSharingOption extends boolean, in out TRouterHistory extends RouterHistory = RouterHistory, in out TDehydrated extends Record<string, any> = Record<string, any>, in out TTransformerConfig = any> {
485
+ export type CreateRouterFn = <TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption = 'never', TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>>(options: undefined extends number ? 'strictNullChecks must be enabled in tsconfig.json' : RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>) => RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>;
486
+ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrailingSlashOption extends TrailingSlashOption, in out TDefaultStructuralSharingOption extends boolean, in out TRouterHistory extends RouterHistory = RouterHistory, in out TDehydrated extends Record<string, any> = Record<string, any>> {
482
487
  tempLocationKey: string | undefined;
483
488
  resetNextScroll: boolean;
484
489
  shouldViewTransition?: boolean | ViewTransitionOptions;
@@ -488,7 +493,7 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
488
493
  isScrollRestoring: boolean;
489
494
  isScrollRestorationSetup: boolean;
490
495
  __store: Store<RouterState<TRouteTree>>;
491
- options: PickAsRequired<RouterOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>, 'stringifySearch' | 'parseSearch' | 'context'>;
496
+ options: PickAsRequired<RouterOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>, 'stringifySearch' | 'parseSearch' | 'context'>;
492
497
  history: TRouterHistory;
493
498
  latestLocation: ParsedLocation<FullSearchSchema<TRouteTree>>;
494
499
  basepath: string;
@@ -501,12 +506,13 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
501
506
  /**
502
507
  * @deprecated Use the `createRouter` function instead
503
508
  */
504
- constructor(options: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>);
509
+ constructor(options: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>);
505
510
  startTransition: StartTransitionFn;
506
511
  isShell(): boolean;
507
512
  isPrerendering(): boolean;
508
- update: UpdateFn<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated, TTransformerConfig>;
513
+ update: UpdateFn<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>;
509
514
  get state(): RouterState<TRouteTree>;
515
+ updateLatestLocation: () => void;
510
516
  buildRouteTree: () => void;
511
517
  subscribe: SubscribeFn;
512
518
  emit: EmitFn;
@@ -5,42 +5,44 @@ const constants = require("../constants.cjs");
5
5
  function createSerializationAdapter(opts) {
6
6
  return opts;
7
7
  }
8
- function makeSsrSerovalPlugin(transformer, options) {
8
+ function makeSsrSerovalPlugin(serializationAdapter, options) {
9
9
  return seroval.createPlugin({
10
- tag: "$TSR/t/" + transformer.key,
11
- test: transformer.test,
10
+ tag: "$TSR/t/" + serializationAdapter.key,
11
+ test: serializationAdapter.test,
12
12
  parse: {
13
13
  stream(value, ctx) {
14
- return ctx.parse(transformer.toSerializable(value));
14
+ return ctx.parse(serializationAdapter.toSerializable(value));
15
15
  }
16
16
  },
17
17
  serialize(node, ctx) {
18
18
  options.didRun = true;
19
- return constants.GLOBAL_TSR + '.t.get("' + transformer.key + '")(' + ctx.serialize(node) + ")";
19
+ return constants.GLOBAL_TSR + '.t.get("' + serializationAdapter.key + '")(' + ctx.serialize(node) + ")";
20
20
  },
21
21
  // we never deserialize on the server during SSR
22
22
  deserialize: void 0
23
23
  });
24
24
  }
25
- function makeSerovalPlugin(transformer) {
25
+ function makeSerovalPlugin(serializationAdapter) {
26
26
  return seroval.createPlugin({
27
- tag: "$TSR/t/" + transformer.key,
28
- test: transformer.test,
27
+ tag: "$TSR/t/" + serializationAdapter.key,
28
+ test: serializationAdapter.test,
29
29
  parse: {
30
30
  sync(value, ctx) {
31
- return ctx.parse(transformer.toSerializable(value));
31
+ return ctx.parse(serializationAdapter.toSerializable(value));
32
32
  },
33
33
  async async(value, ctx) {
34
- return await ctx.parse(transformer.toSerializable(value));
34
+ return await ctx.parse(serializationAdapter.toSerializable(value));
35
35
  },
36
36
  stream(value, ctx) {
37
- return ctx.parse(transformer.toSerializable(value));
37
+ return ctx.parse(serializationAdapter.toSerializable(value));
38
38
  }
39
39
  },
40
40
  // we don't generate JS code outside of SSR (for now)
41
41
  serialize: void 0,
42
42
  deserialize(node, ctx) {
43
- return transformer.fromSerializable(ctx.deserialize(node));
43
+ return serializationAdapter.fromSerializable(
44
+ ctx.deserialize(node)
45
+ );
44
46
  }
45
47
  });
46
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.cjs","sources":["../../../../src/ssr/serializer/transformer.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport { GLOBAL_TSR } from '../constants'\nimport type { SerovalNode } from 'seroval'\n\nexport type Transformer<TInput, TTransformed> = {\n key: string\n test: (value: any) => value is TInput\n toSerializable: (value: TInput) => TTransformed\n fromSerializable: (value: TTransformed) => TInput\n}\n\nexport type AnyTransformer = Transformer<any, any>\n\nexport function createSerializationAdapter<\n TKey extends string,\n TInput,\n TTransformed /* we need to check that this type is actually serializable taking into account all seroval native types and any custom plugin WE=router/start add!!! */,\n>(opts: {\n key: TKey\n test: (value: any) => value is TInput\n toSerializable: (value: TInput) => TTransformed\n fromSerializable: (value: TTransformed) => TInput\n}): Transformer<TInput, TTransformed> {\n return opts\n}\n\nexport function makeSsrSerovalPlugin<TInput, TTransformed>(\n transformer: Transformer<TInput, TTransformed>,\n options: { didRun: boolean },\n) {\n return createPlugin<TInput, SerovalNode>({\n tag: '$TSR/t/' + transformer.key,\n test: transformer.test,\n parse: {\n stream(value, ctx) {\n return ctx.parse(transformer.toSerializable(value))\n },\n },\n serialize(node, ctx) {\n options.didRun = true\n return (\n GLOBAL_TSR +\n '.t.get(\"' +\n transformer.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\nexport function makeSerovalPlugin<TInput, TTransformed>(\n transformer: Transformer<TInput, TTransformed>,\n) {\n return createPlugin<TInput, SerovalNode>({\n tag: '$TSR/t/' + transformer.key,\n test: transformer.test,\n parse: {\n sync(value, ctx) {\n return ctx.parse(transformer.toSerializable(value))\n },\n async async(value, ctx) {\n return await ctx.parse(transformer.toSerializable(value))\n },\n stream(value, ctx) {\n return ctx.parse(transformer.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 transformer.fromSerializable(ctx.deserialize(node) as TTransformed)\n },\n })\n}\n"],"names":["createPlugin","GLOBAL_TSR"],"mappings":";;;;AAaO,SAAS,2BAId,MAKoC;AACpC,SAAO;AACT;AAEO,SAAS,qBACd,aACA,SACA;AACA,SAAOA,qBAAkC;AAAA,IACvC,KAAK,YAAY,YAAY;AAAA,IAC7B,MAAM,YAAY;AAAA,IAClB,OAAO;AAAA,MACL,OAAO,OAAO,KAAK;AACjB,eAAO,IAAI,MAAM,YAAY,eAAe,KAAK,CAAC;AAAA,MACpD;AAAA,IAAA;AAAA,IAEF,UAAU,MAAM,KAAK;AACnB,cAAQ,SAAS;AACjB,aACEC,UAAAA,aACA,aACA,YAAY,MACZ,QACA,IAAI,UAAU,IAAI,IAClB;AAAA,IAEJ;AAAA;AAAA,IAEA,aAAa;AAAA,EAAA,CACd;AACH;AAEO,SAAS,kBACd,aACA;AACA,SAAOD,qBAAkC;AAAA,IACvC,KAAK,YAAY,YAAY;AAAA,IAC7B,MAAM,YAAY;AAAA,IAClB,OAAO;AAAA,MACL,KAAK,OAAO,KAAK;AACf,eAAO,IAAI,MAAM,YAAY,eAAe,KAAK,CAAC;AAAA,MACpD;AAAA,MACA,MAAM,MAAM,OAAO,KAAK;AACtB,eAAO,MAAM,IAAI,MAAM,YAAY,eAAe,KAAK,CAAC;AAAA,MAC1D;AAAA,MACA,OAAO,OAAO,KAAK;AACjB,eAAO,IAAI,MAAM,YAAY,eAAe,KAAK,CAAC;AAAA,MACpD;AAAA,IAAA;AAAA;AAAA,IAGF,WAAW;AAAA,IACX,YAAY,MAAM,KAAK;AACrB,aAAO,YAAY,iBAAiB,IAAI,YAAY,IAAI,CAAiB;AAAA,IAC3E;AAAA,EAAA,CACD;AACH;;;;"}
1
+ {"version":3,"file":"transformer.cjs","sources":["../../../../src/ssr/serializer/transformer.ts"],"sourcesContent":["import { createPlugin } from 'seroval'\nimport { GLOBAL_TSR } from '../constants'\nimport type { Plugin, SerovalNode } from 'seroval'\nimport type { Register, SSROption } from '../../router'\nimport type { LooseReturnType } from '../../utils'\nimport type { AnyRoute, ResolveAllSSR } from '../../route'\n\nexport type Serializable =\n | number\n | string\n | boolean\n | null\n | undefined\n | bigint\n | Date\n\nexport function createSerializationAdapter<\n TInput = unknown,\n TOutput = unknown /* we need to check that this type is actually serializable taking into account all seroval native types and any custom plugin WE=router/start add!!! */,\n>(\n opts: CreateSerializationAdapterOptions<TInput, TOutput>,\n): SerializationAdapter<TInput, TOutput> {\n return opts as unknown as SerializationAdapter<TInput, TOutput>\n}\n\nexport interface CreateSerializationAdapterOptions<TInput, TOutput> {\n key: string\n test: (value: unknown) => value is TInput\n toSerializable: (value: TInput) => ValidateSerializable<TOutput, Serializable>\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 ? '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 : {\n [K in keyof T]: ValidateSerializable<T[K], TSerializable>\n }\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<TInput, TOutput> {\n '~types': SerializationAdapterTypes<TInput, TOutput>\n key: string\n test: (value: unknown) => value is TInput\n toSerializable: (value: TInput) => TOutput\n fromSerializable: (value: TOutput) => TInput\n makePlugin: (options: { didRun: boolean }) => Plugin<TInput, SerovalNode>\n}\n\nexport interface SerializationAdapterTypes<TInput, TOutput> {\n input: TInput\n output: TOutput\n}\n\nexport type AnySerializationAdapter = SerializationAdapter<any, any>\n\nexport function makeSsrSerovalPlugin<TInput, TOutput>(\n serializationAdapter: SerializationAdapter<TInput, TOutput>,\n options: { didRun: boolean },\n) {\n return createPlugin<TInput, 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\nexport function makeSerovalPlugin<TInput, TOutput>(\n serializationAdapter: SerializationAdapter<TInput, TOutput>,\n) {\n return createPlugin<TInput, 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(\n ctx.deserialize(node) as TOutput,\n )\n },\n })\n}\n\nexport type ValidateSerializableInput<\n TRegister extends Register,\n T,\n> = ValidateSerializable<T, RegisteredSerializableInput<TRegister>>\n\nexport type RegisteredSerializableInput<TRegister extends Register> =\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 extends Register> =\n TRegister['config']['~types']['serializationAdapters']\n\nexport type ValidateSerializableInputResult<\n TRegister extends Register,\n T,\n> = ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>\n\nexport type ValidateSerializableResult<T, TSerializable> =\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 extends Register> =\n unknown extends TRegister['config']['~types']['defaultSsr']\n ? SSROption\n : TRegister['config']['~types']['defaultSsr']\n\nexport type ValidateSerializableLifecycleResult<\n TRegister extends Register,\n TParentRoute extends AnyRoute,\n TSSR,\n TFn,\n> = false extends TRegister['ssr']\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 extends Register,\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"],"names":["createPlugin","GLOBAL_TSR"],"mappings":";;;;AAgBO,SAAS,2BAId,MACuC;AACvC,SAAO;AACT;AA2EO,SAAS,qBACd,sBACA,SACA;AACA,SAAOA,qBAAkC;AAAA,IACvC,KAAK,YAAY,qBAAqB;AAAA,IACtC,MAAM,qBAAqB;AAAA,IAC3B,OAAO;AAAA,MACL,OAAO,OAAO,KAAK;AACjB,eAAO,IAAI,MAAM,qBAAqB,eAAe,KAAK,CAAC;AAAA,MAC7D;AAAA,IAAA;AAAA,IAEF,UAAU,MAAM,KAAK;AACnB,cAAQ,SAAS;AACjB,aACEC,UAAAA,aACA,aACA,qBAAqB,MACrB,QACA,IAAI,UAAU,IAAI,IAClB;AAAA,IAEJ;AAAA;AAAA,IAEA,aAAa;AAAA,EAAA,CACd;AACH;AAEO,SAAS,kBACd,sBACA;AACA,SAAOD,qBAAkC;AAAA,IACvC,KAAK,YAAY,qBAAqB;AAAA,IACtC,MAAM,qBAAqB;AAAA,IAC3B,OAAO;AAAA,MACL,KAAK,OAAO,KAAK;AACf,eAAO,IAAI,MAAM,qBAAqB,eAAe,KAAK,CAAC;AAAA,MAC7D;AAAA,MACA,MAAM,MAAM,OAAO,KAAK;AACtB,eAAO,MAAM,IAAI,MAAM,qBAAqB,eAAe,KAAK,CAAC;AAAA,MACnE;AAAA,MACA,OAAO,OAAO,KAAK;AACjB,eAAO,IAAI,MAAM,qBAAqB,eAAe,KAAK,CAAC;AAAA,MAC7D;AAAA,IAAA;AAAA;AAAA,IAGF,WAAW;AAAA,IACX,YAAY,MAAM,KAAK;AACrB,aAAO,qBAAqB;AAAA,QAC1B,IAAI,YAAY,IAAI;AAAA,MAAA;AAAA,IAExB;AAAA,EAAA,CACD;AACH;;;;"}
@@ -1,18 +1,56 @@
1
- import { SerovalNode } from 'seroval';
2
- export type Transformer<TInput, TTransformed> = {
1
+ import { Plugin, SerovalNode } from 'seroval';
2
+ import { Register, SSROption } from '../../router.cjs';
3
+ import { LooseReturnType } from '../../utils.cjs';
4
+ import { AnyRoute, ResolveAllSSR } from '../../route.cjs';
5
+ export type Serializable = number | string | boolean | null | undefined | bigint | Date;
6
+ export declare function createSerializationAdapter<TInput = unknown, TOutput = unknown>(opts: CreateSerializationAdapterOptions<TInput, TOutput>): SerializationAdapter<TInput, TOutput>;
7
+ export interface CreateSerializationAdapterOptions<TInput, TOutput> {
3
8
  key: string;
4
- test: (value: any) => value is TInput;
5
- toSerializable: (value: TInput) => TTransformed;
6
- fromSerializable: (value: TTransformed) => TInput;
9
+ test: (value: unknown) => value is TInput;
10
+ toSerializable: (value: TInput) => ValidateSerializable<TOutput, Serializable>;
11
+ fromSerializable: (value: TOutput) => TInput;
12
+ }
13
+ export type ValidateSerializable<T, TSerializable> = 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> : {
14
+ [K in keyof T]: ValidateSerializable<T[K], TSerializable>;
7
15
  };
8
- export type AnyTransformer = Transformer<any, any>;
9
- export declare function createSerializationAdapter<TKey extends string, TInput, TTransformed>(opts: {
10
- key: TKey;
11
- test: (value: any) => value is TInput;
12
- toSerializable: (value: TInput) => TTransformed;
13
- fromSerializable: (value: TTransformed) => TInput;
14
- }): Transformer<TInput, TTransformed>;
15
- export declare function makeSsrSerovalPlugin<TInput, TTransformed>(transformer: Transformer<TInput, TTransformed>, options: {
16
+ export type ValidateSerializablePromise<T, TSerializable> = T extends Promise<infer TAwaited> ? Promise<ValidateSerializable<TAwaited, TSerializable>> : never;
17
+ export type ValidateReadableStream<T, TSerializable> = T extends ReadableStream<infer TStreamed> ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>> : never;
18
+ export type ValidateSerializableSet<T, TSerializable> = T extends Set<infer TItem> ? Set<ValidateSerializable<TItem, TSerializable>> : never;
19
+ export type ValidateSerializableMap<T, TSerializable> = T extends Map<infer TKey, infer TValue> ? Map<ValidateSerializable<TKey, TSerializable>, ValidateSerializable<TValue, TSerializable>> : never;
20
+ export type RegisteredReadableStream = unknown extends SerializerExtensions['ReadableStream'] ? never : SerializerExtensions['ReadableStream'];
21
+ export interface DefaultSerializerExtensions {
22
+ ReadableStream: unknown;
23
+ }
24
+ export interface SerializerExtensions extends DefaultSerializerExtensions {
25
+ }
26
+ export interface SerializationAdapter<TInput, TOutput> {
27
+ '~types': SerializationAdapterTypes<TInput, TOutput>;
28
+ key: string;
29
+ test: (value: unknown) => value is TInput;
30
+ toSerializable: (value: TInput) => TOutput;
31
+ fromSerializable: (value: TOutput) => TInput;
32
+ makePlugin: (options: {
33
+ didRun: boolean;
34
+ }) => Plugin<TInput, SerovalNode>;
35
+ }
36
+ export interface SerializationAdapterTypes<TInput, TOutput> {
37
+ input: TInput;
38
+ output: TOutput;
39
+ }
40
+ export type AnySerializationAdapter = SerializationAdapter<any, any>;
41
+ export declare function makeSsrSerovalPlugin<TInput, TOutput>(serializationAdapter: SerializationAdapter<TInput, TOutput>, options: {
16
42
  didRun: boolean;
17
- }): import('seroval').Plugin<TInput, SerovalNode>;
18
- export declare function makeSerovalPlugin<TInput, TTransformed>(transformer: Transformer<TInput, TTransformed>): import('seroval').Plugin<TInput, SerovalNode>;
43
+ }): Plugin<TInput, SerovalNode>;
44
+ export declare function makeSerovalPlugin<TInput, TOutput>(serializationAdapter: SerializationAdapter<TInput, TOutput>): Plugin<TInput, SerovalNode>;
45
+ export type ValidateSerializableInput<TRegister extends Register, T> = ValidateSerializable<T, RegisteredSerializableInput<TRegister>>;
46
+ export type RegisteredSerializableInput<TRegister extends Register> = (unknown extends RegisteredSerializationAdapters<TRegister> ? never : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter> ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input'] : never) | Serializable;
47
+ export type RegisteredSerializationAdapters<TRegister extends Register> = TRegister['config']['~types']['serializationAdapters'];
48
+ export type ValidateSerializableInputResult<TRegister extends Register, T> = ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>;
49
+ export type ValidateSerializableResult<T, TSerializable> = T extends TSerializable ? T : unknown extends SerializerExtensions['ReadableStream'] ? {
50
+ [K in keyof T]: ValidateSerializableResult<T[K], TSerializable>;
51
+ } : T extends SerializerExtensions['ReadableStream'] ? ReadableStream : {
52
+ [K in keyof T]: ValidateSerializableResult<T[K], TSerializable>;
53
+ };
54
+ export type RegisteredSSROption<TRegister extends Register> = unknown extends TRegister['config']['~types']['defaultSsr'] ? SSROption : TRegister['config']['~types']['defaultSsr'];
55
+ export type ValidateSerializableLifecycleResult<TRegister extends Register, TParentRoute extends AnyRoute, TSSR, TFn> = false extends TRegister['ssr'] ? any : ValidateSerializableLifecycleResultSSR<TRegister, TParentRoute, TSSR, TFn> extends infer TInput ? TInput : never;
56
+ export type ValidateSerializableLifecycleResultSSR<TRegister extends Register, TParentRoute extends AnyRoute, TSSR, TFn> = ResolveAllSSR<TParentRoute, TSSR> extends false ? any : RegisteredSSROption<TRegister> extends false ? any : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>;
@@ -4,3 +4,8 @@ export { defineHandlerCallback } from './handlerCallback.cjs';
4
4
  export type { HandlerCallback } from './handlerCallback.cjs';
5
5
  export { transformPipeableStreamWithRouter, transformStreamWithRouter, transformReadableStreamWithRouter, } from './transformStreamWithRouter.cjs';
6
6
  export { attachRouterServerSsrUtils } from './ssr-server.cjs';
7
+ declare module '../router' {
8
+ interface Register {
9
+ ssr: true;
10
+ }
11
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-client.cjs","sources":["../../../src/ssr/ssr-client.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { batch } from '@tanstack/store'\nimport { createControlledPromise } from '../utils'\nimport type { AnyRouteMatch, MakeRouteMatch } from '../Matches'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\nimport type { RouteContextOptions } from '../route'\nimport type { AnyTransformer } from './serializer/transformer'\nimport type { GLOBAL_TSR } from './constants'\n\ndeclare global {\n interface Window {\n [GLOBAL_TSR]?: TsrSsrGlobal\n }\n}\n\nexport interface TsrSsrGlobal {\n router?: DehydratedRouter\n // clean scripts; shortened since this is sent for each streamed script\n c: () => void\n // push script into buffer; shortened since this is sent for each streamed script as soon as the first custom transformer was invoked\n p: (script: () => void) => void\n buffer: Array<() => void>\n // custom transformers, shortened since this is sent for each streamed value that needs a custom transformer\n t?: Map<string, (value: any) => any>\n // this flag indicates whether the transformers were initialized\n initialized?: boolean\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}\nexport interface DehydratedMatch {\n i: MakeRouteMatch['id']\n b?: MakeRouteMatch['__beforeLoadContext']\n l?: MakeRouteMatch['loaderData']\n e?: MakeRouteMatch['error']\n u: MakeRouteMatch['updatedAt']\n s: MakeRouteMatch['status']\n ssr?: MakeRouteMatch['ssr']\n}\n\nexport interface DehydratedRouter {\n manifest: Manifest | undefined\n dehydratedData?: any\n lastMatchId?: string\n matches: Array<DehydratedMatch>\n}\n\nexport async function hydrate(router: AnyRouter): Promise<any> {\n invariant(\n window.$_TSR,\n 'Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!',\n )\n\n const serializationAdapters = router.options.serializationAdapters as\n | Array<AnyTransformer>\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 invariant(\n window.$_TSR.router,\n 'Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',\n )\n\n const { manifest, dehydratedData, lastMatchId } = window.$_TSR.router\n\n router.ssr = {\n manifest,\n }\n\n // Hydrate the router state\n const matches = router.matchRoutes(router.state.location)\n\n // kick off loading the route chunks\n const routeChunkPromise = Promise.all(\n matches.map((match) => {\n const route = router.looseRoutesById[match.routeId]!\n return router.loadRouteChunk(route)\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 // 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 = window.$_TSR!.router!.matches.find(\n (d) => d.i === match.id,\n )\n if (!dehydratedMatch) {\n match._nonReactive.dehydrated = false\n match.ssr = false\n return\n }\n\n hydrateMatch(match, dehydratedMatch)\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.__store.setState((s) => {\n return {\n ...s,\n matches,\n }\n })\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 await Promise.all(\n router.state.matches.map(async (match) => {\n const route = router.looseRoutesById[match.routeId]!\n\n const parentMatch = router.state.matches[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> = {\n deps: match.loaderDeps,\n params: match.params,\n context: parentContext ?? {},\n location: router.state.location,\n navigate: (opts: any) =>\n router.navigate({ ...opts, _fromLocation: router.state.location }),\n buildLocation: router.buildLocation,\n cause: match.cause,\n abortController: match.abortController,\n preload: false,\n matches,\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 matches: router.state.matches,\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 }),\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 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 invariant(\n match,\n 'Expected to find a match below the root match in SPA mode.',\n )\n setMatchForcePending(match)\n\n match._displayPending = true\n match._nonReactive.displayPendingPromise = loadPromise\n\n loadPromise.then(() => {\n 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.__store.state.status === 'pending') {\n router.__store.setState((s) => ({\n ...s,\n status: 'idle',\n resolvedLocation: s.location,\n }))\n }\n // hide the pending component once the load is finished\n router.updateMatch(match.id, (prev) => {\n return {\n ...prev,\n _displayPending: undefined,\n displayPendingPromise: undefined,\n }\n })\n })\n })\n }\n return routeChunkPromise\n}\n"],"names":["createControlledPromise","batch"],"mappings":";;;;;AA6BA,SAAS,aACP,OACA,kBACM;AACN,QAAM,KAAK,iBAAiB;AAC5B,QAAM,sBAAsB,iBAAiB;AAC7C,QAAM,aAAa,iBAAiB;AACpC,QAAM,SAAS,iBAAiB;AAChC,QAAM,MAAM,iBAAiB;AAC7B,QAAM,YAAY,iBAAiB;AACnC,QAAM,QAAQ,iBAAiB;AACjC;AAkBA,eAAsB,QAAQ,QAAiC;AAC7D;AAAA,IACE,OAAO;AAAA,IACP;AAAA,EAAA;AAGF,QAAM,wBAAwB,OAAO,QAAQ;AAI7C,MAAI,uBAAuB,QAAQ;AACjC,UAAM,0CAA0B,IAAA;AAChC,0BAAsB,QAAQ,CAAC,YAAY;AACzC,0BAAoB,IAAI,QAAQ,KAAK,QAAQ,gBAAgB;AAAA,IAC/D,CAAC;AACD,WAAO,MAAM,IAAI;AACjB,WAAO,MAAM,OAAO,QAAQ,CAAC,WAAW,QAAQ;AAAA,EAClD;AACA,SAAO,MAAM,cAAc;AAE3B;AAAA,IACE,OAAO,MAAM;AAAA,IACb;AAAA,EAAA;AAGF,QAAM,EAAE,UAAU,gBAAgB,YAAA,IAAgB,OAAO,MAAM;AAE/D,SAAO,MAAM;AAAA,IACX;AAAA,EAAA;AAIF,QAAM,UAAU,OAAO,YAAY,OAAO,MAAM,QAAQ;AAGxD,QAAM,oBAAoB,QAAQ;AAAA,IAChC,QAAQ,IAAI,CAAC,UAAU;AACrB,YAAM,QAAQ,OAAO,gBAAgB,MAAM,OAAO;AAClD,aAAO,OAAO,eAAe,KAAK;AAAA,IACpC,CAAC;AAAA,EAAA;AAGH,WAAS,qBAAqB,OAAsB;AAGlD,UAAM,QAAQ,OAAO,gBAAgB,MAAM,OAAO;AAClD,UAAM,eACJ,MAAM,QAAQ,gBAAgB,OAAO,QAAQ;AAC/C,QAAI,cAAc;AAChB,YAAM,oBAAoBA,MAAAA,wBAAA;AAC1B,YAAM,aAAa,oBAAoB;AACvC,YAAM,gBAAgB;AAEtB,iBAAW,MAAM;AACf,0BAAkB,QAAA;AAElB,eAAO,YAAY,MAAM,IAAI,CAAC,SAAS;AACrC,eAAK,aAAa,oBAAoB;AACtC,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,eAAe;AAAA,UAAA;AAAA,QAEnB,CAAC;AAAA,MACH,GAAG,YAAY;AAAA,IACjB;AAAA,EACF;AAIA,MAAI,wBAA4C;AAChD,UAAQ,QAAQ,CAAC,UAAU;AACzB,UAAM,kBAAkB,OAAO,MAAO,OAAQ,QAAQ;AAAA,MACpD,CAAC,MAAM,EAAE,MAAM,MAAM;AAAA,IAAA;AAEvB,QAAI,CAAC,iBAAiB;AACpB,YAAM,aAAa,aAAa;AAChC,YAAM,MAAM;AACZ;AAAA,IACF;AAEA,iBAAa,OAAO,eAAe;AAEnC,UAAM,aAAa,aAAa,MAAM,QAAQ;AAE9C,QAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,OAAO;AACpD,UAAI,0BAA0B,QAAW;AACvC,gCAAwB,MAAM;AAC9B,6BAAqB,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,QAAQ,SAAS,CAAC,MAAM;AAC7B,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,IAAA;AAAA,EAEJ,CAAC;AAGD,QAAM,OAAO,QAAQ,UAAU,cAAc;AAK7C,QAAM,QAAQ;AAAA,IACZ,OAAO,MAAM,QAAQ,IAAI,OAAO,UAAU;AACxC,YAAM,QAAQ,OAAO,gBAAgB,MAAM,OAAO;AAElD,YAAM,cAAc,OAAO,MAAM,QAAQ,MAAM,QAAQ,CAAC;AACxD,YAAM,gBAAgB,aAAa,WAAW,OAAO,QAAQ;AAI7D,UAAI,MAAM,QAAQ,SAAS;AACzB,cAAM,mBAA4D;AAAA,UAChE,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,UACd,SAAS,iBAAiB,CAAA;AAAA,UAC1B,UAAU,OAAO,MAAM;AAAA,UACvB,UAAU,CAAC,SACT,OAAO,SAAS,EAAE,GAAG,MAAM,eAAe,OAAO,MAAM,SAAA,CAAU;AAAA,UACnE,eAAe,OAAO;AAAA,UACtB,OAAO,MAAM;AAAA,UACb,iBAAiB,MAAM;AAAA,UACvB,SAAS;AAAA,UACT;AAAA,QAAA;AAEF,cAAM,iBACJ,MAAM,QAAQ,QAAQ,gBAAgB,KAAK;AAAA,MAC/C;AAEA,YAAM,UAAU;AAAA,QACd,GAAG;AAAA,QACH,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,MAAA;AAGX,YAAM,eAAe;AAAA,QACnB,SAAS,OAAO,MAAM;AAAA,QACtB;AAAA,QACA,QAAQ,MAAM;AAAA,QACd,YAAY,MAAM;AAAA,MAAA;AAEpB,YAAM,gBAAgB,MAAM,MAAM,QAAQ,OAAO,YAAY;AAE7D,YAAM,UAAU,MAAM,MAAM,QAAQ,UAAU,YAAY;AAE1D,YAAM,OAAO,eAAe;AAC5B,YAAM,QAAQ,eAAe;AAC7B,YAAM,cAAc,eAAe;AACnC,YAAM,SAAS,eAAe;AAC9B,YAAM,UAAU;AAAA,IAClB,CAAC;AAAA,EAAA;AAGH,QAAM,YAAY,QAAQ,QAAQ,SAAS,CAAC,EAAG,OAAO;AACtD,QAAM,qBAAqB,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,KAAK;AAE9D,MAAI,CAAC,sBAAsB,CAAC,WAAW;AACrC,YAAQ,QAAQ,CAAC,UAAU;AAEzB,YAAM,aAAa,aAAa;AAAA,IAClC,CAAC;AACD,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,QAAQ,QAAA,EACzB,KAAK,MAAM,OAAO,KAAA,CAAM,EACxB,MAAM,CAAC,QAAQ;AACd,YAAQ,MAAM,kCAAkC,GAAG;AAAA,EACrD,CAAC;AAIH,MAAI,WAAW;AACb,UAAM,QAAQ,QAAQ,CAAC;AACvB;AAAA,MACE;AAAA,MACA;AAAA,IAAA;AAEF,yBAAqB,KAAK;AAE1B,UAAM,kBAAkB;AACxB,UAAM,aAAa,wBAAwB;AAE3C,gBAAY,KAAK,MAAM;AACrBC,YAAAA,MAAM,MAAM;AAIV,YAAI,OAAO,QAAQ,MAAM,WAAW,WAAW;AAC7C,iBAAO,QAAQ,SAAS,CAAC,OAAO;AAAA,YAC9B,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,kBAAkB,EAAE;AAAA,UAAA,EACpB;AAAA,QACJ;AAEA,eAAO,YAAY,MAAM,IAAI,CAAC,SAAS;AACrC,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,iBAAiB;AAAA,YACjB,uBAAuB;AAAA,UAAA;AAAA,QAE3B,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,SAAO;AACT;;"}
1
+ {"version":3,"file":"ssr-client.cjs","sources":["../../../src/ssr/ssr-client.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { batch } from '@tanstack/store'\nimport { createControlledPromise } from '../utils'\nimport type { AnyRouteMatch, MakeRouteMatch } from '../Matches'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\nimport type { RouteContextOptions } from '../route'\nimport type { AnySerializationAdapter } from './serializer/transformer'\nimport type { GLOBAL_TSR } from './constants'\n\ndeclare global {\n interface Window {\n [GLOBAL_TSR]?: TsrSsrGlobal\n }\n}\n\nexport interface TsrSsrGlobal {\n router?: DehydratedRouter\n // clean scripts; shortened since this is sent for each streamed script\n c: () => void\n // push script into buffer; shortened since this is sent for each streamed script as soon as the first custom transformer was invoked\n p: (script: () => void) => void\n buffer: Array<() => void>\n // custom transformers, shortened since this is sent for each streamed value that needs a custom transformer\n t?: Map<string, (value: any) => any>\n // this flag indicates whether the transformers were initialized\n initialized?: boolean\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}\nexport interface DehydratedMatch {\n i: MakeRouteMatch['id']\n b?: MakeRouteMatch['__beforeLoadContext']\n l?: MakeRouteMatch['loaderData']\n e?: MakeRouteMatch['error']\n u: MakeRouteMatch['updatedAt']\n s: MakeRouteMatch['status']\n ssr?: MakeRouteMatch['ssr']\n}\n\nexport interface DehydratedRouter {\n manifest: Manifest | undefined\n dehydratedData?: any\n lastMatchId?: string\n matches: Array<DehydratedMatch>\n}\n\nexport async function hydrate(router: AnyRouter): Promise<any> {\n invariant(\n window.$_TSR,\n 'Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!',\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 invariant(\n window.$_TSR.router,\n 'Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',\n )\n\n const { manifest, dehydratedData, lastMatchId } = window.$_TSR.router\n\n router.ssr = {\n manifest,\n }\n\n // Hydrate the router state\n const matches = router.matchRoutes(router.state.location)\n\n // kick off loading the route chunks\n const routeChunkPromise = Promise.all(\n matches.map((match) => {\n const route = router.looseRoutesById[match.routeId]!\n return router.loadRouteChunk(route)\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 // 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 = window.$_TSR!.router!.matches.find(\n (d) => d.i === match.id,\n )\n if (!dehydratedMatch) {\n match._nonReactive.dehydrated = false\n match.ssr = false\n return\n }\n\n hydrateMatch(match, dehydratedMatch)\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.__store.setState((s) => {\n return {\n ...s,\n matches,\n }\n })\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 await Promise.all(\n router.state.matches.map(async (match) => {\n const route = router.looseRoutesById[match.routeId]!\n\n const parentMatch = router.state.matches[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> = {\n deps: match.loaderDeps,\n params: match.params,\n context: parentContext ?? {},\n location: router.state.location,\n navigate: (opts: any) =>\n router.navigate({ ...opts, _fromLocation: router.state.location }),\n buildLocation: router.buildLocation,\n cause: match.cause,\n abortController: match.abortController,\n preload: false,\n matches,\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 matches: router.state.matches,\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 }),\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 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 invariant(\n match,\n 'Expected to find a match below the root match in SPA mode.',\n )\n setMatchForcePending(match)\n\n match._displayPending = true\n match._nonReactive.displayPendingPromise = loadPromise\n\n loadPromise.then(() => {\n 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.__store.state.status === 'pending') {\n router.__store.setState((s) => ({\n ...s,\n status: 'idle',\n resolvedLocation: s.location,\n }))\n }\n // hide the pending component once the load is finished\n router.updateMatch(match.id, (prev) => {\n return {\n ...prev,\n _displayPending: undefined,\n displayPendingPromise: undefined,\n }\n })\n })\n })\n }\n return routeChunkPromise\n}\n"],"names":["createControlledPromise","batch"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-server.cjs","sources":["../../../src/ssr/ssr-server.ts"],"sourcesContent":["import { crossSerializeStream, getCrossReferenceHeader } from 'seroval'\nimport invariant from 'tiny-invariant'\nimport { createControlledPromise } from '../utils'\nimport minifiedTsrBootStrapScript from './tsrScript?script-string'\nimport { GLOBAL_TSR } from './constants'\nimport { defaultSerovalPlugins } from './serializer/seroval-plugins'\nimport { makeSsrSerovalPlugin } from './serializer/transformer'\nimport type { AnyRouter } from '../router'\nimport type { DehydratedMatch } from './ssr-client'\nimport type { DehydratedRouter } from './client'\nimport type { AnyRouteMatch } from '../Matches'\nimport type { Manifest } from '../manifest'\nimport type { AnyTransformer } from './serializer/transformer'\n\ndeclare module '../router' {\n interface ServerSsr {\n setRenderFinished: () => void\n }\n interface RouterEvents {\n onInjectedHtml: {\n type: 'onInjectedHtml'\n promise: Promise<string>\n }\n }\n}\n\nconst SCOPE_ID = 'tsr'\n\nexport function dehydrateMatch(match: AnyRouteMatch): DehydratedMatch {\n const dehydratedMatch: DehydratedMatch = {\n i: match.id,\n u: match.updatedAt,\n s: match.status,\n }\n\n const properties = [\n ['__beforeLoadContext', 'b'],\n ['loaderData', 'l'],\n ['error', 'e'],\n ['ssr', 'ssr'],\n ] as const\n\n for (const [key, shorthand] of properties) {\n if (match[key] !== undefined) {\n dehydratedMatch[shorthand] = match[key]\n }\n }\n return dehydratedMatch\n}\n\nexport function attachRouterServerSsrUtils(\n router: AnyRouter,\n manifest: Manifest | undefined,\n) {\n router.ssr = {\n manifest,\n }\n let initialScriptSent = false\n const getInitialScript = () => {\n if (initialScriptSent) {\n return ''\n }\n initialScriptSent = true\n return `${getCrossReferenceHeader(SCOPE_ID)};${minifiedTsrBootStrapScript};`\n }\n let _dehydrated = false\n const listeners: Array<() => void> = []\n\n router.serverSsr = {\n injectedHtml: [],\n injectHtml: (getHtml) => {\n const promise = Promise.resolve().then(getHtml)\n router.serverSsr!.injectedHtml.push(promise)\n router.emit({\n type: 'onInjectedHtml',\n promise,\n })\n\n return promise.then(() => {})\n },\n injectScript: (getScript) => {\n return router.serverSsr!.injectHtml(async () => {\n const script = await getScript()\n return `<script class='$tsr'>${getInitialScript()}${script};$_TSR.c()</script>`\n })\n },\n dehydrate: async () => {\n invariant(!_dehydrated, 'router is already dehydrated!')\n let matchesToDehydrate = router.state.matches\n if (router.isShell()) {\n // In SPA mode we only want to dehydrate the root match\n matchesToDehydrate = matchesToDehydrate.slice(0, 1)\n }\n const matches = matchesToDehydrate.map(dehydrateMatch)\n\n const dehydratedRouter: DehydratedRouter = {\n manifest: router.ssr!.manifest,\n matches,\n }\n const lastMatchId = matchesToDehydrate[matchesToDehydrate.length - 1]?.id\n if (lastMatchId) {\n dehydratedRouter.lastMatchId = lastMatchId\n }\n dehydratedRouter.dehydratedData = await router.options.dehydrate?.()\n _dehydrated = true\n\n const p = createControlledPromise<string>()\n const trackPlugins = { didRun: false }\n const plugins =\n (\n router.options.serializationAdapters as\n | Array<AnyTransformer>\n | undefined\n )?.map((t) => makeSsrSerovalPlugin(t, trackPlugins)) ?? []\n crossSerializeStream(dehydratedRouter, {\n refs: new Map(),\n plugins: [...plugins, ...defaultSerovalPlugins],\n onSerialize: (data, initial) => {\n let serialized = initial ? GLOBAL_TSR + '.router=' + data : data\n if (trackPlugins.didRun) {\n serialized = GLOBAL_TSR + '.p(()=>' + serialized + ')'\n }\n router.serverSsr!.injectScript(() => serialized)\n },\n scopeId: SCOPE_ID,\n onDone: () => p.resolve(''),\n onError: (err) => p.reject(err),\n })\n // make sure the stream is kept open until the promise is resolved\n router.serverSsr!.injectHtml(() => p)\n },\n isDehydrated() {\n return _dehydrated\n },\n onRenderFinished: (listener) => listeners.push(listener),\n setRenderFinished: () => {\n listeners.forEach((l) => l())\n },\n }\n}\n"],"names":["getCrossReferenceHeader","minifiedTsrBootStrapScript","createControlledPromise","makeSsrSerovalPlugin","crossSerializeStream","defaultSerovalPlugins","GLOBAL_TSR"],"mappings":"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"}
1
+ {"version":3,"file":"ssr-server.cjs","sources":["../../../src/ssr/ssr-server.ts"],"sourcesContent":["import { crossSerializeStream, getCrossReferenceHeader } from 'seroval'\nimport invariant from 'tiny-invariant'\nimport { createControlledPromise } from '../utils'\nimport minifiedTsrBootStrapScript from './tsrScript?script-string'\nimport { GLOBAL_TSR } from './constants'\nimport { defaultSerovalPlugins } from './serializer/seroval-plugins'\nimport { makeSsrSerovalPlugin } from './serializer/transformer'\nimport type { AnyRouter } from '../router'\nimport type { DehydratedMatch } from './ssr-client'\nimport type { DehydratedRouter } from './client'\nimport type { AnyRouteMatch } from '../Matches'\nimport type { Manifest } from '../manifest'\nimport type { AnySerializationAdapter } from './serializer/transformer'\n\ndeclare module '../router' {\n interface ServerSsr {\n setRenderFinished: () => void\n }\n interface RouterEvents {\n onInjectedHtml: {\n type: 'onInjectedHtml'\n promise: Promise<string>\n }\n }\n}\n\nconst SCOPE_ID = 'tsr'\n\nexport function dehydrateMatch(match: AnyRouteMatch): DehydratedMatch {\n const dehydratedMatch: DehydratedMatch = {\n i: match.id,\n u: match.updatedAt,\n s: match.status,\n }\n\n const properties = [\n ['__beforeLoadContext', 'b'],\n ['loaderData', 'l'],\n ['error', 'e'],\n ['ssr', 'ssr'],\n ] as const\n\n for (const [key, shorthand] of properties) {\n if (match[key] !== undefined) {\n dehydratedMatch[shorthand] = match[key]\n }\n }\n return dehydratedMatch\n}\n\nexport function attachRouterServerSsrUtils(\n router: AnyRouter,\n manifest: Manifest | undefined,\n) {\n router.ssr = {\n manifest,\n }\n let initialScriptSent = false\n const getInitialScript = () => {\n if (initialScriptSent) {\n return ''\n }\n initialScriptSent = true\n return `${getCrossReferenceHeader(SCOPE_ID)};${minifiedTsrBootStrapScript};`\n }\n let _dehydrated = false\n const listeners: Array<() => void> = []\n\n router.serverSsr = {\n injectedHtml: [],\n injectHtml: (getHtml) => {\n const promise = Promise.resolve().then(getHtml)\n router.serverSsr!.injectedHtml.push(promise)\n router.emit({\n type: 'onInjectedHtml',\n promise,\n })\n\n return promise.then(() => {})\n },\n injectScript: (getScript) => {\n return router.serverSsr!.injectHtml(async () => {\n const script = await getScript()\n return `<script class='$tsr'>${getInitialScript()}${script};$_TSR.c()</script>`\n })\n },\n dehydrate: async () => {\n invariant(!_dehydrated, 'router is already dehydrated!')\n let matchesToDehydrate = router.state.matches\n if (router.isShell()) {\n // In SPA mode we only want to dehydrate the root match\n matchesToDehydrate = matchesToDehydrate.slice(0, 1)\n }\n const matches = matchesToDehydrate.map(dehydrateMatch)\n\n const dehydratedRouter: DehydratedRouter = {\n manifest: router.ssr!.manifest,\n matches,\n }\n const lastMatchId = matchesToDehydrate[matchesToDehydrate.length - 1]?.id\n if (lastMatchId) {\n dehydratedRouter.lastMatchId = lastMatchId\n }\n dehydratedRouter.dehydratedData = await router.options.dehydrate?.()\n _dehydrated = true\n\n const p = createControlledPromise<string>()\n const trackPlugins = { didRun: false }\n const plugins =\n (\n router.options.serializationAdapters as\n | Array<AnySerializationAdapter>\n | undefined\n )?.map((t) => makeSsrSerovalPlugin(t, trackPlugins)) ?? []\n crossSerializeStream(dehydratedRouter, {\n refs: new Map(),\n plugins: [...plugins, ...defaultSerovalPlugins],\n onSerialize: (data, initial) => {\n let serialized = initial ? GLOBAL_TSR + '.router=' + data : data\n if (trackPlugins.didRun) {\n serialized = GLOBAL_TSR + '.p(()=>' + serialized + ')'\n }\n router.serverSsr!.injectScript(() => serialized)\n },\n scopeId: SCOPE_ID,\n onDone: () => p.resolve(''),\n onError: (err) => p.reject(err),\n })\n // make sure the stream is kept open until the promise is resolved\n router.serverSsr!.injectHtml(() => p)\n },\n isDehydrated() {\n return _dehydrated\n },\n onRenderFinished: (listener) => listeners.push(listener),\n setRenderFinished: () => {\n listeners.forEach((l) => l())\n },\n }\n}\n"],"names":["getCrossReferenceHeader","minifiedTsrBootStrapScript","createControlledPromise","makeSsrSerovalPlugin","crossSerializeStream","defaultSerovalPlugins","GLOBAL_TSR"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { AnyRoute, StaticDataRouteOption } from './route.js';
2
2
  import { AllContext, AllLoaderData, AllParams, FullSearchSchema, ParseRoute, RouteById, RouteIds } from './routeInfo.js';
3
- import { AnyRouter, RegisteredRouter } from './router.js';
3
+ import { AnyRouter, RegisteredRouter, SSROption } from './router.js';
4
4
  import { Constrain, ControlledPromise } from './utils.js';
5
5
  export type AnyMatchAndValue = {
6
6
  match: any;
@@ -72,7 +72,7 @@ export interface RouteMatch<out TRouteId, out TFullPath, out TAllParams, out TFu
72
72
  globalNotFound?: boolean;
73
73
  staticData: StaticDataRouteOption;
74
74
  /** This attribute is not reactive */
75
- ssr?: boolean | 'data-only';
75
+ ssr?: SSROption;
76
76
  _forcePending?: boolean;
77
77
  _displayPending?: boolean;
78
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Matches.js","sources":["../../src/Matches.ts"],"sourcesContent":["import type { AnyRoute, StaticDataRouteOption } from './route'\nimport type {\n AllContext,\n AllLoaderData,\n AllParams,\n FullSearchSchema,\n ParseRoute,\n RouteById,\n RouteIds,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { Constrain, ControlledPromise } from './utils'\n\nexport type AnyMatchAndValue = { match: any; value: any }\n\nexport type FindValueByIndex<\n TKey,\n TValue extends ReadonlyArray<any>,\n> = TKey extends `${infer TIndex extends number}` ? TValue[TIndex] : never\n\nexport type FindValueByKey<TKey, TValue> =\n TValue extends ReadonlyArray<any>\n ? FindValueByIndex<TKey, TValue>\n : TValue[TKey & keyof TValue]\n\nexport type CreateMatchAndValue<TMatch, TValue> = TValue extends any\n ? {\n match: TMatch\n value: TValue\n }\n : never\n\nexport type NextMatchAndValue<\n TKey,\n TMatchAndValue extends AnyMatchAndValue,\n> = TMatchAndValue extends any\n ? CreateMatchAndValue<\n TMatchAndValue['match'],\n FindValueByKey<TKey, TMatchAndValue['value']>\n >\n : never\n\nexport type IsMatchKeyOf<TValue> =\n TValue extends ReadonlyArray<any>\n ? number extends TValue['length']\n ? `${number}`\n : keyof TValue & `${number}`\n : TValue extends object\n ? keyof TValue & string\n : never\n\nexport type IsMatchPath<\n TParentPath extends string,\n TMatchAndValue extends AnyMatchAndValue,\n> = `${TParentPath}${IsMatchKeyOf<TMatchAndValue['value']>}`\n\nexport type IsMatchResult<\n TKey,\n TMatchAndValue extends AnyMatchAndValue,\n> = TMatchAndValue extends any\n ? TKey extends keyof TMatchAndValue['value']\n ? TMatchAndValue['match']\n : never\n : never\n\nexport type IsMatchParse<\n TPath,\n TMatchAndValue extends AnyMatchAndValue,\n TParentPath extends string = '',\n> = TPath extends `${string}.${string}`\n ? TPath extends `${infer TFirst}.${infer TRest}`\n ? IsMatchParse<\n TRest,\n NextMatchAndValue<TFirst, TMatchAndValue>,\n `${TParentPath}${TFirst}.`\n >\n : never\n : {\n path: IsMatchPath<TParentPath, TMatchAndValue>\n result: IsMatchResult<TPath, TMatchAndValue>\n }\n\nexport type IsMatch<TMatch, TPath> = IsMatchParse<\n TPath,\n TMatch extends any ? { match: TMatch; value: TMatch } : never\n>\n\n/**\n * Narrows matches based on a path\n * @experimental\n */\nexport const isMatch = <TMatch, TPath extends string>(\n match: TMatch,\n path: Constrain<TPath, IsMatch<TMatch, TPath>['path']>,\n): match is IsMatch<TMatch, TPath>['result'] => {\n const parts = (path as string).split('.')\n let part\n let value: any = match\n\n while ((part = parts.shift()) != null && value != null) {\n value = value[part]\n }\n\n return value != null\n}\n\nexport interface DefaultRouteMatchExtensions {\n scripts?: unknown\n links?: unknown\n headScripts?: unknown\n meta?: unknown\n styles?: unknown\n}\n\nexport interface RouteMatchExtensions extends DefaultRouteMatchExtensions {}\n\nexport interface RouteMatch<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n out TLoaderData,\n out TAllContext,\n out TLoaderDeps,\n> extends RouteMatchExtensions {\n id: string\n routeId: TRouteId\n fullPath: TFullPath\n index: number\n pathname: string\n params: TAllParams\n _strictParams: TAllParams\n status: 'pending' | 'success' | 'error' | 'redirected' | 'notFound'\n isFetching: false | 'beforeLoad' | 'loader'\n error: unknown\n paramsError: unknown\n searchError: unknown\n updatedAt: number\n _nonReactive: {\n /** @internal */\n beforeLoadPromise?: ControlledPromise<void>\n /** @internal */\n loaderPromise?: ControlledPromise<void>\n /** @internal */\n pendingTimeout?: ReturnType<typeof setTimeout>\n loadPromise?: ControlledPromise<void>\n displayPendingPromise?: Promise<void>\n minPendingPromise?: ControlledPromise<void>\n dehydrated?: boolean\n }\n loaderData?: TLoaderData\n /** @internal */\n __routeContext?: Record<string, unknown>\n /** @internal */\n __beforeLoadContext?: Record<string, unknown>\n context: TAllContext\n search: TFullSearchSchema\n _strictSearch: TFullSearchSchema\n fetchCount: number\n abortController: AbortController\n cause: 'preload' | 'enter' | 'stay'\n loaderDeps: TLoaderDeps\n preload: boolean\n invalid: boolean\n headers?: Record<string, string>\n globalNotFound?: boolean\n staticData: StaticDataRouteOption\n /** This attribute is not reactive */\n ssr?: boolean | 'data-only'\n _forcePending?: boolean\n _displayPending?: boolean\n}\n\nexport interface PreValidationErrorHandlingRouteMatch<\n TRouteId,\n TFullPath,\n TAllParams,\n TFullSearchSchema,\n> {\n id: string\n routeId: TRouteId\n fullPath: TFullPath\n index: number\n pathname: string\n search:\n | { status: 'success'; value: TFullSearchSchema }\n | { status: 'error'; error: unknown }\n params:\n | { status: 'success'; value: TAllParams }\n | { status: 'error'; error: unknown }\n staticData: StaticDataRouteOption\n ssr?: boolean | 'data-only'\n}\n\nexport type MakePreValidationErrorHandlingRouteMatchUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? PreValidationErrorHandlingRouteMatch<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\nexport type MakeRouteMatchFromRoute<TRoute extends AnyRoute> = RouteMatch<\n TRoute['types']['id'],\n TRoute['types']['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema'],\n TRoute['types']['loaderData'],\n TRoute['types']['allContext'],\n TRoute['types']['loaderDeps']\n>\n\nexport type MakeRouteMatch<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TRouteId = RouteIds<TRouteTree>,\n TStrict extends boolean = true,\n> = RouteMatch<\n TRouteId,\n RouteById<TRouteTree, TRouteId>['types']['fullPath'],\n TStrict extends false\n ? AllParams<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['allParams'],\n TStrict extends false\n ? FullSearchSchema<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'],\n TStrict extends false\n ? AllLoaderData<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['loaderData'],\n TStrict extends false\n ? AllContext<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['allContext'],\n RouteById<TRouteTree, TRouteId>['types']['loaderDeps']\n>\n\nexport type AnyRouteMatch = RouteMatch<any, any, any, any, any, any, any>\n\nexport type MakeRouteMatchUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? RouteMatch<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema'],\n TRoute['types']['loaderData'],\n TRoute['types']['allContext'],\n TRoute['types']['loaderDeps']\n >\n : never\n\n/**\n * The `MatchRouteOptions` type is used to describe the options that can be used when matching a route.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#matchrouteoptions-type)\n */\nexport interface MatchRouteOptions {\n /**\n * If `true`, will match against pending location instead of the current location.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#pending-property)\n */\n pending?: boolean\n /**\n * If `true`, will match against the current location with case sensitivity.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#casesensitive-property)\n */\n caseSensitive?: boolean\n /**\n * If `true`, will match against the current location's search params using a deep inclusive check. e.g. `{ a: 1 }` will match for a current location of `{ a: 1, b: 2 }`.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#includesearch-property)\n */\n includeSearch?: boolean\n /**\n * If `true`, will match against the current location using a fuzzy match. e.g. `/posts` will match for a current location of `/posts/123`.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#fuzzy-property)\n */\n fuzzy?: boolean\n}\n"],"names":[],"mappings":"AA2FO,MAAM,UAAU,CACrB,OACA,SAC8C;AAC9C,QAAM,QAAS,KAAgB,MAAM,GAAG;AACxC,MAAI;AACJ,MAAI,QAAa;AAEjB,UAAQ,OAAO,MAAM,MAAA,MAAY,QAAQ,SAAS,MAAM;AACtD,YAAQ,MAAM,IAAI;AAAA,EACpB;AAEA,SAAO,SAAS;AAClB;"}
1
+ {"version":3,"file":"Matches.js","sources":["../../src/Matches.ts"],"sourcesContent":["import type { AnyRoute, StaticDataRouteOption } from './route'\nimport type {\n AllContext,\n AllLoaderData,\n AllParams,\n FullSearchSchema,\n ParseRoute,\n RouteById,\n RouteIds,\n} from './routeInfo'\nimport type { AnyRouter, RegisteredRouter, SSROption } from './router'\nimport type { Constrain, ControlledPromise } from './utils'\n\nexport type AnyMatchAndValue = { match: any; value: any }\n\nexport type FindValueByIndex<\n TKey,\n TValue extends ReadonlyArray<any>,\n> = TKey extends `${infer TIndex extends number}` ? TValue[TIndex] : never\n\nexport type FindValueByKey<TKey, TValue> =\n TValue extends ReadonlyArray<any>\n ? FindValueByIndex<TKey, TValue>\n : TValue[TKey & keyof TValue]\n\nexport type CreateMatchAndValue<TMatch, TValue> = TValue extends any\n ? {\n match: TMatch\n value: TValue\n }\n : never\n\nexport type NextMatchAndValue<\n TKey,\n TMatchAndValue extends AnyMatchAndValue,\n> = TMatchAndValue extends any\n ? CreateMatchAndValue<\n TMatchAndValue['match'],\n FindValueByKey<TKey, TMatchAndValue['value']>\n >\n : never\n\nexport type IsMatchKeyOf<TValue> =\n TValue extends ReadonlyArray<any>\n ? number extends TValue['length']\n ? `${number}`\n : keyof TValue & `${number}`\n : TValue extends object\n ? keyof TValue & string\n : never\n\nexport type IsMatchPath<\n TParentPath extends string,\n TMatchAndValue extends AnyMatchAndValue,\n> = `${TParentPath}${IsMatchKeyOf<TMatchAndValue['value']>}`\n\nexport type IsMatchResult<\n TKey,\n TMatchAndValue extends AnyMatchAndValue,\n> = TMatchAndValue extends any\n ? TKey extends keyof TMatchAndValue['value']\n ? TMatchAndValue['match']\n : never\n : never\n\nexport type IsMatchParse<\n TPath,\n TMatchAndValue extends AnyMatchAndValue,\n TParentPath extends string = '',\n> = TPath extends `${string}.${string}`\n ? TPath extends `${infer TFirst}.${infer TRest}`\n ? IsMatchParse<\n TRest,\n NextMatchAndValue<TFirst, TMatchAndValue>,\n `${TParentPath}${TFirst}.`\n >\n : never\n : {\n path: IsMatchPath<TParentPath, TMatchAndValue>\n result: IsMatchResult<TPath, TMatchAndValue>\n }\n\nexport type IsMatch<TMatch, TPath> = IsMatchParse<\n TPath,\n TMatch extends any ? { match: TMatch; value: TMatch } : never\n>\n\n/**\n * Narrows matches based on a path\n * @experimental\n */\nexport const isMatch = <TMatch, TPath extends string>(\n match: TMatch,\n path: Constrain<TPath, IsMatch<TMatch, TPath>['path']>,\n): match is IsMatch<TMatch, TPath>['result'] => {\n const parts = (path as string).split('.')\n let part\n let value: any = match\n\n while ((part = parts.shift()) != null && value != null) {\n value = value[part]\n }\n\n return value != null\n}\n\nexport interface DefaultRouteMatchExtensions {\n scripts?: unknown\n links?: unknown\n headScripts?: unknown\n meta?: unknown\n styles?: unknown\n}\n\nexport interface RouteMatchExtensions extends DefaultRouteMatchExtensions {}\n\nexport interface RouteMatch<\n out TRouteId,\n out TFullPath,\n out TAllParams,\n out TFullSearchSchema,\n out TLoaderData,\n out TAllContext,\n out TLoaderDeps,\n> extends RouteMatchExtensions {\n id: string\n routeId: TRouteId\n fullPath: TFullPath\n index: number\n pathname: string\n params: TAllParams\n _strictParams: TAllParams\n status: 'pending' | 'success' | 'error' | 'redirected' | 'notFound'\n isFetching: false | 'beforeLoad' | 'loader'\n error: unknown\n paramsError: unknown\n searchError: unknown\n updatedAt: number\n _nonReactive: {\n /** @internal */\n beforeLoadPromise?: ControlledPromise<void>\n /** @internal */\n loaderPromise?: ControlledPromise<void>\n /** @internal */\n pendingTimeout?: ReturnType<typeof setTimeout>\n loadPromise?: ControlledPromise<void>\n displayPendingPromise?: Promise<void>\n minPendingPromise?: ControlledPromise<void>\n dehydrated?: boolean\n }\n loaderData?: TLoaderData\n /** @internal */\n __routeContext?: Record<string, unknown>\n /** @internal */\n __beforeLoadContext?: Record<string, unknown>\n context: TAllContext\n search: TFullSearchSchema\n _strictSearch: TFullSearchSchema\n fetchCount: number\n abortController: AbortController\n cause: 'preload' | 'enter' | 'stay'\n loaderDeps: TLoaderDeps\n preload: boolean\n invalid: boolean\n headers?: Record<string, string>\n globalNotFound?: boolean\n staticData: StaticDataRouteOption\n /** This attribute is not reactive */\n ssr?: SSROption\n _forcePending?: boolean\n _displayPending?: boolean\n}\n\nexport interface PreValidationErrorHandlingRouteMatch<\n TRouteId,\n TFullPath,\n TAllParams,\n TFullSearchSchema,\n> {\n id: string\n routeId: TRouteId\n fullPath: TFullPath\n index: number\n pathname: string\n search:\n | { status: 'success'; value: TFullSearchSchema }\n | { status: 'error'; error: unknown }\n params:\n | { status: 'success'; value: TAllParams }\n | { status: 'error'; error: unknown }\n staticData: StaticDataRouteOption\n ssr?: boolean | 'data-only'\n}\n\nexport type MakePreValidationErrorHandlingRouteMatchUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? PreValidationErrorHandlingRouteMatch<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema']\n >\n : never\n\nexport type MakeRouteMatchFromRoute<TRoute extends AnyRoute> = RouteMatch<\n TRoute['types']['id'],\n TRoute['types']['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema'],\n TRoute['types']['loaderData'],\n TRoute['types']['allContext'],\n TRoute['types']['loaderDeps']\n>\n\nexport type MakeRouteMatch<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TRouteId = RouteIds<TRouteTree>,\n TStrict extends boolean = true,\n> = RouteMatch<\n TRouteId,\n RouteById<TRouteTree, TRouteId>['types']['fullPath'],\n TStrict extends false\n ? AllParams<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['allParams'],\n TStrict extends false\n ? FullSearchSchema<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'],\n TStrict extends false\n ? AllLoaderData<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['loaderData'],\n TStrict extends false\n ? AllContext<TRouteTree>\n : RouteById<TRouteTree, TRouteId>['types']['allContext'],\n RouteById<TRouteTree, TRouteId>['types']['loaderDeps']\n>\n\nexport type AnyRouteMatch = RouteMatch<any, any, any, any, any, any, any>\n\nexport type MakeRouteMatchUnion<\n TRouter extends AnyRouter = RegisteredRouter,\n TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,\n> = TRoute extends any\n ? RouteMatch<\n TRoute['id'],\n TRoute['fullPath'],\n TRoute['types']['allParams'],\n TRoute['types']['fullSearchSchema'],\n TRoute['types']['loaderData'],\n TRoute['types']['allContext'],\n TRoute['types']['loaderDeps']\n >\n : never\n\n/**\n * The `MatchRouteOptions` type is used to describe the options that can be used when matching a route.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#matchrouteoptions-type)\n */\nexport interface MatchRouteOptions {\n /**\n * If `true`, will match against pending location instead of the current location.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#pending-property)\n */\n pending?: boolean\n /**\n * If `true`, will match against the current location with case sensitivity.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#casesensitive-property)\n */\n caseSensitive?: boolean\n /**\n * If `true`, will match against the current location's search params using a deep inclusive check. e.g. `{ a: 1 }` will match for a current location of `{ a: 1, b: 2 }`.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#includesearch-property)\n */\n includeSearch?: boolean\n /**\n * If `true`, will match against the current location using a fuzzy match. e.g. `/posts` will match for a current location of `/posts/123`.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/MatchRouteOptionsType#fuzzy-property)\n */\n fuzzy?: boolean\n}\n"],"names":[],"mappings":"AA2FO,MAAM,UAAU,CACrB,OACA,SAC8C;AAC9C,QAAM,QAAS,KAAgB,MAAM,GAAG;AACxC,MAAI;AACJ,MAAI,QAAa;AAEjB,UAAQ,OAAO,MAAM,MAAA,MAAY,QAAQ,SAAS,MAAM;AACtD,YAAQ,MAAM,IAAI;AAAA,EACpB;AAEA,SAAO,SAAS;AAClB;"}
@@ -0,0 +1,17 @@
1
+ import { SSROption } from './router.js';
2
+ import { AnySerializationAdapter } from './ssr/serializer/transformer.js';
3
+ export interface RouterConfigOptions<in out TSerializationAdapters, in out TDefaultSsr> {
4
+ serializationAdapters?: TSerializationAdapters;
5
+ defaultSsr?: TDefaultSsr;
6
+ }
7
+ export interface RouterConfig<in out TSerializationAdapters, in out TDefaultSsr> {
8
+ '~types': RouterConfigTypes<TSerializationAdapters, TDefaultSsr>;
9
+ serializationAdapters: TSerializationAdapters;
10
+ defaultSsr: TDefaultSsr | undefined;
11
+ }
12
+ export interface RouterConfigTypes<in out TSerializationAdapters, in out TDefaultSsr> {
13
+ serializationAdapters: TSerializationAdapters;
14
+ defaultSsr: TDefaultSsr;
15
+ }
16
+ export declare const createRouterConfig: <const TSerializationAdapters extends ReadonlyArray<AnySerializationAdapter> = [], TDefaultSsr extends SSROption = SSROption>(options: RouterConfigOptions<TSerializationAdapters, TDefaultSsr>) => RouterConfig<TSerializationAdapters, TDefaultSsr>;
17
+ export type AnyRouterConfig = RouterConfig<any, any>;
@@ -0,0 +1,10 @@
1
+ const createRouterConfig = (options) => {
2
+ return {
3
+ serializationAdapters: options.serializationAdapters,
4
+ defaultSsr: options.defaultSsr
5
+ };
6
+ };
7
+ export {
8
+ createRouterConfig
9
+ };
10
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import type { SSROption } from './router'\nimport type { AnySerializationAdapter } from './ssr/serializer/transformer'\n\nexport interface RouterConfigOptions<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n> {\n serializationAdapters?: TSerializationAdapters\n defaultSsr?: TDefaultSsr\n}\n\nexport interface RouterConfig<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n> {\n '~types': RouterConfigTypes<TSerializationAdapters, TDefaultSsr>\n serializationAdapters: TSerializationAdapters\n defaultSsr: TDefaultSsr | undefined\n}\n\nexport interface RouterConfigTypes<\n in out TSerializationAdapters,\n in out TDefaultSsr,\n> {\n serializationAdapters: TSerializationAdapters\n defaultSsr: TDefaultSsr\n}\n\nexport const createRouterConfig = <\n const TSerializationAdapters extends\n ReadonlyArray<AnySerializationAdapter> = [],\n TDefaultSsr extends SSROption = SSROption,\n>(\n options: RouterConfigOptions<TSerializationAdapters, TDefaultSsr>,\n): RouterConfig<TSerializationAdapters, TDefaultSsr> => {\n return {\n serializationAdapters: options.serializationAdapters,\n defaultSsr: options.defaultSsr,\n } as RouterConfig<TSerializationAdapters, TDefaultSsr>\n}\n\nexport type AnyRouterConfig = RouterConfig<any, any>\n"],"names":[],"mappings":"AA4BO,MAAM,qBAAqB,CAKhC,YACsD;AACtD,SAAO;AAAA,IACL,uBAAuB,QAAQ;AAAA,IAC/B,YAAY,QAAQ;AAAA,EAAA;AAExB;"}
@@ -1,4 +1,5 @@
1
1
  import { AnyContext, AnyPathParams, AnyRoute, FileBaseRouteOptions, ResolveParams, Route, RouteConstraints, UpdatableRouteOptions } from './route.js';
2
+ import { Register } from './router.js';
2
3
  import { AnyValidator } from './validators.js';
3
4
  export interface FileRouteTypes {
4
5
  fileRoutesByFullPath: any;
@@ -11,9 +12,9 @@ export interface FileRouteTypes {
11
12
  export type InferFileRouteTypes<TRouteTree extends AnyRoute> = unknown extends TRouteTree['types']['fileRouteTypes'] ? never : TRouteTree['types']['fileRouteTypes'] extends FileRouteTypes ? TRouteTree['types']['fileRouteTypes'] : never;
12
13
  export interface FileRoutesByPath {
13
14
  }
14
- export interface FileRouteOptions<TFilePath extends string, TParentRoute extends AnyRoute, TId extends RouteConstraints['TId'], TPath extends RouteConstraints['TPath'], TFullPath extends RouteConstraints['TFullPath'], TSearchValidator = undefined, TParams = ResolveParams<TPath>, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined> extends FileBaseRouteOptions<TParentRoute, TId, TPath, TSearchValidator, TParams, TLoaderDeps, TLoaderFn, AnyContext, TRouteContextFn, TBeforeLoadFn>, UpdatableRouteOptions<TParentRoute, TId, TFullPath, TParams, TSearchValidator, TLoaderFn, TLoaderDeps, AnyContext, TRouteContextFn, TBeforeLoadFn> {
15
+ export interface FileRouteOptions<TRegister extends Register, TFilePath extends string, TParentRoute extends AnyRoute, TId extends RouteConstraints['TId'], TPath extends RouteConstraints['TPath'], TFullPath extends RouteConstraints['TFullPath'], TSearchValidator = undefined, TParams = ResolveParams<TPath>, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined, TSSR = unknown> extends FileBaseRouteOptions<TRegister, TParentRoute, TId, TPath, TSearchValidator, TParams, TLoaderDeps, TLoaderFn, AnyContext, TRouteContextFn, TBeforeLoadFn, AnyContext, TSSR>, UpdatableRouteOptions<TParentRoute, TId, TFullPath, TParams, TSearchValidator, TLoaderFn, TLoaderDeps, AnyContext, TRouteContextFn, TBeforeLoadFn> {
15
16
  }
16
- export type CreateFileRoute<TFilePath extends string, TParentRoute extends AnyRoute, TId extends RouteConstraints['TId'], TPath extends RouteConstraints['TPath'], TFullPath extends RouteConstraints['TFullPath']> = <TSearchValidator = undefined, TParams = ResolveParams<TPath>, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined>(options?: FileRouteOptions<TFilePath, TParentRoute, TId, TPath, TFullPath, TSearchValidator, TParams, TRouteContextFn, TBeforeLoadFn, TLoaderDeps, TLoaderFn>) => Route<TParentRoute, TPath, TFullPath, TFilePath, TId, TSearchValidator, TParams, AnyContext, TRouteContextFn, TBeforeLoadFn, TLoaderDeps, TLoaderFn, unknown, unknown>;
17
+ export type CreateFileRoute<TFilePath extends string, TParentRoute extends AnyRoute, TId extends RouteConstraints['TId'], TPath extends RouteConstraints['TPath'], TFullPath extends RouteConstraints['TFullPath']> = <TRegister extends Register = Register, TSearchValidator = undefined, TParams = ResolveParams<TPath>, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined, TSSR = unknown>(options?: FileRouteOptions<TRegister, TFilePath, TParentRoute, TId, TPath, TFullPath, TSearchValidator, TParams, TRouteContextFn, TBeforeLoadFn, TLoaderDeps, TLoaderFn, TSSR>) => Route<TRegister, TParentRoute, TPath, TFullPath, TFilePath, TId, TSearchValidator, TParams, AnyContext, TRouteContextFn, TBeforeLoadFn, TLoaderDeps, TLoaderFn, unknown, unknown, TSSR>;
17
18
  export type LazyRouteOptions = Pick<UpdatableRouteOptions<AnyRoute, string, string, AnyPathParams, AnyValidator, {}, AnyContext, AnyContext, AnyContext, AnyContext>, 'component' | 'errorComponent' | 'pendingComponent' | 'notFoundComponent'>;
18
19
  export interface LazyRoute<in out TRoute extends AnyRoute> {
19
20
  options: {
@@ -18,7 +18,8 @@ export type { RootRouteId } from './root.js';
18
18
  export { BaseRoute, BaseRouteApi, BaseRootRoute } from './route.js';
19
19
  export type { AnyPathParams, SearchSchemaInput, AnyContext, RouteContext, PreloadableObj, RoutePathOptions, StaticDataRouteOption, RoutePathOptionsIntersection, SearchFilter, SearchMiddlewareContext, SearchMiddleware, ResolveId, InferFullSearchSchema, InferFullSearchSchemaInput, InferAllParams, InferAllContext, MetaDescriptor, RouteLinkEntry, SearchValidator, AnySearchValidator, DefaultSearchValidator, ErrorRouteProps, ErrorComponentProps, NotFoundRouteProps, ResolveParams, ParseParamsFn, StringifyParamsFn, ParamsOptions, UpdatableStaticRouteOption, ContextReturnType, ContextAsyncReturnType, ResolveRouteContext, ResolveLoaderData, RoutePrefix, TrimPath, TrimPathLeft, TrimPathRight, ResolveSearchSchemaFnInput, ResolveSearchSchemaInput, ResolveSearchSchemaFn, ResolveSearchSchema, ResolveFullSearchSchema, ResolveFullSearchSchemaInput, ResolveAllContext, BeforeLoadContextParameter, RouteContextParameter, ResolveAllParamsFromParent, AnyRoute, Route, RouteTypes, FullSearchSchemaOption, RemountDepsOptions, MakeRemountDepsOptionsUnion, ResolveFullPath, AnyRouteWithContext, RouteOptions, FileBaseRouteOptions, BaseRouteOptions, UpdatableRouteOptions, RouteLoaderFn, LoaderFnContext, RouteContextFn, BeforeLoadFn, ContextOptions, RouteContextOptions, BeforeLoadContextOptions, RootRouteOptions, RootRouteOptionsExtensions, UpdatableRouteOptionsExtensions, RouteConstraints, RouteTypesById, RouteMask, RouteExtensions, RouteLazyFn, RouteAddChildrenFn, RouteAddFileChildrenFn, RouteAddFileTypesFn, ResolveOptionalParams, ResolveRequiredParams, RootRoute, } from './route.js';
20
20
  export { defaultSerializeError, getLocationChangeInfo, RouterCore, lazyFn, SearchParamError, PathParamError, getInitialRouterState, processRouteTree, getMatchedRoutes, } from './router.js';
21
- export type { ViewTransitionOptions, TrailingSlashOption, Register, AnyRouter, AnyRouterWithContext, RegisteredRouter, RouterState, BuildNextOptions, RouterListener, RouterEvent, ListenerFn, RouterEvents, MatchRoutesOpts, RouterOptionsExtensions, DefaultRemountDepsFn, PreloadRouteFn, MatchRouteFn, RouterContextOptions, RouterOptions, RouterConstructorOptions, UpdateFn, ParseLocationFn, InvalidateFn, ControllablePromise, InjectedHtmlEntry, EmitFn, LoadFn, GetMatchFn, SubscribeFn, UpdateMatchFn, CommitLocationFn, GetMatchRoutesFn, MatchRoutesFn, StartTransitionFn, LoadRouteChunkFn, ClearCacheFn, CreateRouterFn, ProcessRouteTreeResult, } from './router.js';
21
+ export type { ViewTransitionOptions, TrailingSlashOption, Register, AnyRouter, AnyRouterWithContext, RegisteredRouter, RouterState, BuildNextOptions, RouterListener, RouterEvent, ListenerFn, RouterEvents, MatchRoutesOpts, RouterOptionsExtensions, DefaultRemountDepsFn, PreloadRouteFn, MatchRouteFn, RouterContextOptions, RouterOptions, RouterConstructorOptions, UpdateFn, ParseLocationFn, InvalidateFn, ControllablePromise, InjectedHtmlEntry, EmitFn, LoadFn, GetMatchFn, SubscribeFn, UpdateMatchFn, CommitLocationFn, GetMatchRoutesFn, MatchRoutesFn, StartTransitionFn, LoadRouteChunkFn, ClearCacheFn, CreateRouterFn, ProcessRouteTreeResult, SSROption, DefaultRegister, } from './router.js';
22
+ export * from './config.js';
22
23
  export type { MatchLocation, CommitLocationOptions, NavigateFn, BuildLocationFn, } from './RouterProvider.js';
23
24
  export { retainSearchParams, stripSearchParams } from './searchMiddleware.js';
24
25
  export { defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, } from './searchParams.js';
@@ -40,6 +41,6 @@ export { isNotFound, notFound } from './not-found.js';
40
41
  export { defaultGetScrollRestorationKey, restoreScroll, storageKey, getCssSelector, scrollRestorationCache, setupScrollRestoration, handleHashScroll, } from './scroll-restoration.js';
41
42
  export type { ScrollRestorationOptions, ScrollRestorationEntry, } from './scroll-restoration.js';
42
43
  export type { ValidateFromPath, ValidateToPath, ValidateSearch, ValidateParams, InferFrom, InferTo, InferMaskTo, InferMaskFrom, ValidateNavigateOptions, ValidateNavigateOptionsArray, ValidateRedirectOptions, ValidateRedirectOptionsArray, ValidateId, InferStrict, InferShouldThrow, InferSelected, ValidateUseSearchResult, ValidateUseParamsResult, } from './typePrimitives.js';
43
- export type { AnyTransformer, Transformer } from './ssr/serializer/transformer.js';
44
+ export type { AnySerializationAdapter, SerializationAdapter, ValidateSerializableInput, ValidateSerializableInputResult, SerializerExtensions, ValidateSerializable, RegisteredSerializableInput, } from './ssr/serializer/transformer.js';
44
45
  export { createSerializationAdapter, makeSerovalPlugin, makeSsrSerovalPlugin, } from './ssr/serializer/transformer.js';
45
46
  export { defaultSerovalPlugins } from './ssr/serializer/seroval-plugins.js';
package/dist/esm/index.js CHANGED
@@ -7,6 +7,7 @@ import { decode, encode } from "./qss.js";
7
7
  import { rootRouteId } from "./root.js";
8
8
  import { BaseRootRoute, BaseRoute, BaseRouteApi } from "./route.js";
9
9
  import { PathParamError, RouterCore, SearchParamError, defaultSerializeError, getInitialRouterState, getLocationChangeInfo, getMatchedRoutes, lazyFn, processRouteTree } from "./router.js";
10
+ import { createRouterConfig } from "./config.js";
10
11
  import { retainSearchParams, stripSearchParams } from "./searchMiddleware.js";
11
12
  import { defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith } from "./searchParams.js";
12
13
  import { createControlledPromise, deepEqual, functionalUpdate, isModuleNotFoundError, isPlainArray, isPlainObject, last, replaceEqualDeep } from "./utils.js";
@@ -26,6 +27,7 @@ export {
26
27
  cleanPath,
27
28
  componentTypes,
28
29
  createControlledPromise,
30
+ createRouterConfig,
29
31
  createSerializationAdapter,
30
32
  decode,
31
33
  deepEqual,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}