@tanstack/router-core 1.121.0-alpha.27 → 1.121.0-alpha.28

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 (165) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +31 -1
  3. package/dist/cjs/RouterProvider.d.cts +2 -1
  4. package/dist/cjs/defer.cjs +1 -1
  5. package/dist/cjs/defer.cjs.map +1 -1
  6. package/dist/cjs/global.d.cts +7 -0
  7. package/dist/cjs/index.cjs +1 -2
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/index.d.cts +6 -6
  10. package/dist/cjs/link.cjs.map +1 -1
  11. package/dist/cjs/link.d.cts +12 -0
  12. package/dist/cjs/lru-cache.cjs +62 -0
  13. package/dist/cjs/lru-cache.cjs.map +1 -0
  14. package/dist/cjs/lru-cache.d.cts +5 -0
  15. package/dist/cjs/not-found.cjs +1 -1
  16. package/dist/cjs/not-found.cjs.map +1 -1
  17. package/dist/cjs/path.cjs +316 -148
  18. package/dist/cjs/path.cjs.map +1 -1
  19. package/dist/cjs/path.d.cts +18 -24
  20. package/dist/cjs/qss.cjs.map +1 -1
  21. package/dist/cjs/redirect.cjs +3 -0
  22. package/dist/cjs/redirect.cjs.map +1 -1
  23. package/dist/cjs/route.cjs +6 -12
  24. package/dist/cjs/route.cjs.map +1 -1
  25. package/dist/cjs/route.d.cts +29 -9
  26. package/dist/cjs/router.cjs +453 -272
  27. package/dist/cjs/router.cjs.map +1 -1
  28. package/dist/cjs/router.d.cts +55 -85
  29. package/dist/cjs/scroll-restoration.cjs +20 -13
  30. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  31. package/dist/cjs/scroll-restoration.d.cts +9 -1
  32. package/dist/cjs/searchMiddleware.cjs.map +1 -1
  33. package/dist/cjs/searchParams.cjs.map +1 -1
  34. package/dist/cjs/ssr/client.cjs +10 -0
  35. package/dist/cjs/ssr/client.cjs.map +1 -0
  36. package/dist/cjs/ssr/client.d.cts +5 -0
  37. package/dist/cjs/ssr/createRequestHandler.cjs +50 -0
  38. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -0
  39. package/dist/cjs/ssr/createRequestHandler.d.cts +9 -0
  40. package/dist/cjs/ssr/handlerCallback.cjs +7 -0
  41. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -0
  42. package/dist/cjs/ssr/handlerCallback.d.cts +9 -0
  43. package/dist/cjs/ssr/headers.cjs +39 -0
  44. package/dist/cjs/ssr/headers.cjs.map +1 -0
  45. package/dist/cjs/ssr/headers.d.cts +5 -0
  46. package/dist/cjs/ssr/json.cjs +14 -0
  47. package/dist/cjs/ssr/json.cjs.map +1 -0
  48. package/dist/cjs/ssr/json.d.cts +4 -0
  49. package/dist/cjs/ssr/seroval-plugins.cjs +34 -0
  50. package/dist/cjs/ssr/seroval-plugins.cjs.map +1 -0
  51. package/dist/cjs/ssr/seroval-plugins.d.cts +10 -0
  52. package/dist/cjs/ssr/server.cjs +13 -0
  53. package/dist/cjs/ssr/server.cjs.map +1 -0
  54. package/dist/cjs/ssr/server.d.cts +6 -0
  55. package/dist/cjs/ssr/ssr-client.cjs +159 -0
  56. package/dist/cjs/ssr/ssr-client.cjs.map +1 -0
  57. package/dist/cjs/ssr/ssr-client.d.cts +29 -0
  58. package/dist/cjs/ssr/ssr-server.cjs +107 -0
  59. package/dist/cjs/ssr/ssr-server.cjs.map +1 -0
  60. package/dist/cjs/ssr/ssr-server.d.cts +18 -0
  61. package/dist/cjs/ssr/transformStreamWithRouter.cjs +183 -0
  62. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -0
  63. package/dist/cjs/ssr/transformStreamWithRouter.d.cts +6 -0
  64. package/dist/cjs/ssr/tsrScript.cjs +4 -0
  65. package/dist/cjs/ssr/tsrScript.cjs.map +1 -0
  66. package/dist/cjs/ssr/tsrScript.d.cts +0 -0
  67. package/dist/cjs/utils.cjs +7 -25
  68. package/dist/cjs/utils.cjs.map +1 -1
  69. package/dist/cjs/utils.d.cts +1 -6
  70. package/dist/esm/Matches.d.ts +31 -1
  71. package/dist/esm/Matches.js.map +1 -1
  72. package/dist/esm/RouterProvider.d.ts +2 -1
  73. package/dist/esm/defer.js +1 -1
  74. package/dist/esm/defer.js.map +1 -1
  75. package/dist/esm/global.d.ts +7 -0
  76. package/dist/esm/index.d.ts +6 -6
  77. package/dist/esm/index.js +2 -3
  78. package/dist/esm/link.d.ts +12 -0
  79. package/dist/esm/link.js.map +1 -1
  80. package/dist/esm/lru-cache.d.ts +5 -0
  81. package/dist/esm/lru-cache.js +62 -0
  82. package/dist/esm/lru-cache.js.map +1 -0
  83. package/dist/esm/not-found.js +1 -1
  84. package/dist/esm/not-found.js.map +1 -1
  85. package/dist/esm/path.d.ts +18 -24
  86. package/dist/esm/path.js +316 -148
  87. package/dist/esm/path.js.map +1 -1
  88. package/dist/esm/qss.js.map +1 -1
  89. package/dist/esm/redirect.js +3 -0
  90. package/dist/esm/redirect.js.map +1 -1
  91. package/dist/esm/route.d.ts +29 -9
  92. package/dist/esm/route.js +6 -12
  93. package/dist/esm/route.js.map +1 -1
  94. package/dist/esm/router.d.ts +55 -85
  95. package/dist/esm/router.js +462 -281
  96. package/dist/esm/router.js.map +1 -1
  97. package/dist/esm/scroll-restoration.d.ts +9 -1
  98. package/dist/esm/scroll-restoration.js +20 -13
  99. package/dist/esm/scroll-restoration.js.map +1 -1
  100. package/dist/esm/searchMiddleware.js.map +1 -1
  101. package/dist/esm/searchParams.js.map +1 -1
  102. package/dist/esm/ssr/client.d.ts +5 -0
  103. package/dist/esm/ssr/client.js +10 -0
  104. package/dist/esm/ssr/client.js.map +1 -0
  105. package/dist/esm/ssr/createRequestHandler.d.ts +9 -0
  106. package/dist/esm/ssr/createRequestHandler.js +50 -0
  107. package/dist/esm/ssr/createRequestHandler.js.map +1 -0
  108. package/dist/esm/ssr/handlerCallback.d.ts +9 -0
  109. package/dist/esm/ssr/handlerCallback.js +7 -0
  110. package/dist/esm/ssr/handlerCallback.js.map +1 -0
  111. package/dist/esm/ssr/headers.d.ts +5 -0
  112. package/dist/esm/ssr/headers.js +39 -0
  113. package/dist/esm/ssr/headers.js.map +1 -0
  114. package/dist/esm/ssr/json.d.ts +4 -0
  115. package/dist/esm/ssr/json.js +14 -0
  116. package/dist/esm/ssr/json.js.map +1 -0
  117. package/dist/esm/ssr/seroval-plugins.d.ts +10 -0
  118. package/dist/esm/ssr/seroval-plugins.js +34 -0
  119. package/dist/esm/ssr/seroval-plugins.js.map +1 -0
  120. package/dist/esm/ssr/server.d.ts +6 -0
  121. package/dist/esm/ssr/server.js +13 -0
  122. package/dist/esm/ssr/server.js.map +1 -0
  123. package/dist/esm/ssr/ssr-client.d.ts +29 -0
  124. package/dist/esm/ssr/ssr-client.js +159 -0
  125. package/dist/esm/ssr/ssr-client.js.map +1 -0
  126. package/dist/esm/ssr/ssr-server.d.ts +18 -0
  127. package/dist/esm/ssr/ssr-server.js +107 -0
  128. package/dist/esm/ssr/ssr-server.js.map +1 -0
  129. package/dist/esm/ssr/transformStreamWithRouter.d.ts +6 -0
  130. package/dist/esm/ssr/transformStreamWithRouter.js +183 -0
  131. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -0
  132. package/dist/esm/ssr/tsrScript.d.ts +0 -0
  133. package/dist/esm/ssr/tsrScript.js +5 -0
  134. package/dist/esm/ssr/tsrScript.js.map +1 -0
  135. package/dist/esm/utils.d.ts +1 -6
  136. package/dist/esm/utils.js +8 -26
  137. package/dist/esm/utils.js.map +1 -1
  138. package/package.json +29 -2
  139. package/src/Matches.ts +40 -1
  140. package/src/RouterProvider.ts +2 -1
  141. package/src/global.ts +9 -0
  142. package/src/index.ts +12 -20
  143. package/src/link.ts +12 -0
  144. package/src/lru-cache.ts +68 -0
  145. package/src/path.ts +424 -174
  146. package/src/redirect.ts +3 -0
  147. package/src/route.ts +44 -13
  148. package/src/router.ts +580 -312
  149. package/src/scroll-restoration.ts +30 -18
  150. package/src/ssr/client.ts +5 -0
  151. package/src/ssr/createRequestHandler.ts +74 -0
  152. package/src/ssr/handlerCallback.ts +15 -0
  153. package/src/ssr/headers.ts +51 -0
  154. package/src/ssr/json.ts +18 -0
  155. package/src/ssr/seroval-plugins.ts +43 -0
  156. package/src/ssr/server.ts +10 -0
  157. package/src/ssr/ssr-client.ts +242 -0
  158. package/src/ssr/ssr-server.ts +132 -0
  159. package/src/ssr/transformStreamWithRouter.ts +259 -0
  160. package/src/ssr/tsrScript.ts +7 -0
  161. package/src/utils.ts +10 -39
  162. package/src/vite-env.d.ts +4 -0
  163. package/dist/cjs/serializer.d.cts +0 -22
  164. package/dist/esm/serializer.d.ts +0 -22
  165. package/src/serializer.ts +0 -32
@@ -1,24 +1,18 @@
1
1
  import { Store } from '@tanstack/store';
2
+ import { ParsePathnameCache } from './path.cjs';
2
3
  import { SearchParser, SearchSerializer } from './searchParams.cjs';
3
4
  import { AnyRedirect, ResolvedRedirect } from './redirect.cjs';
4
5
  import { HistoryLocation, HistoryState, ParsedHistoryState, RouterHistory } from '@tanstack/history';
5
- import { ControlledPromise, NoInfer, NonNullableUpdater, PickAsRequired, Updater } from './utils.cjs';
6
+ import { Awaitable, ControlledPromise, NoInfer, NonNullableUpdater, PickAsRequired, Updater } from './utils.cjs';
6
7
  import { ParsedLocation } from './location.cjs';
7
- import { DeferredPromiseState } from './defer.cjs';
8
8
  import { AnyContext, AnyRoute, AnyRouteWithContext, MakeRemountDepsOptionsUnion, RouteMask } from './route.cjs';
9
9
  import { FullSearchSchema, RouteById, RoutePaths, RoutesById, RoutesByPath } from './routeInfo.cjs';
10
10
  import { AnyRouteMatch, MakeRouteMatch, MakeRouteMatchUnion, MatchRouteOptions } from './Matches.cjs';
11
11
  import { BuildLocationFn, CommitLocationOptions, NavigateFn } from './RouterProvider.cjs';
12
12
  import { Manifest } from './manifest.cjs';
13
- import { StartSerializer } from './serializer.cjs';
14
13
  import { AnySchema } from './validators.cjs';
15
14
  import { NavigateOptions, ResolveRelativePath, ToOptions } from './link.cjs';
16
15
  import { NotFoundError } from './not-found.cjs';
17
- declare global {
18
- interface Window {
19
- __TSR_ROUTER__?: AnyRouter;
20
- }
21
- }
22
16
  export type ControllablePromise<T = any> = Promise<T> & {
23
17
  resolve: (value: T) => void;
24
18
  reject: (value?: any) => void;
@@ -202,16 +196,14 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
202
196
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#dehydrate-method)
203
197
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)
204
198
  */
205
- dehydrate?: () => TDehydrated;
199
+ dehydrate?: () => Awaitable<TDehydrated>;
206
200
  /**
207
201
  * A function that will be called when the router is hydrated.
208
202
  *
209
- * The return value of this function will be serialized and stored in the router's dehydrated state.
210
- *
211
203
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#hydrate-method)
212
204
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)
213
205
  */
214
- hydrate?: (dehydrated: TDehydrated) => void;
206
+ hydrate?: (dehydrated: TDehydrated) => Awaitable<void>;
215
207
  /**
216
208
  * An array of route masks that will be used to mask routes in the route tree.
217
209
  *
@@ -257,7 +249,20 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
257
249
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#isserver-property)
258
250
  */
259
251
  isServer?: boolean;
260
- defaultSsr?: boolean;
252
+ /**
253
+ * @default false
254
+ */
255
+ isShell?: boolean;
256
+ /**
257
+ * @default false
258
+ */
259
+ isPrerendering?: boolean;
260
+ /**
261
+ * The default `ssr` a route should use if no `ssr` is provided.
262
+ *
263
+ * @default true
264
+ */
265
+ defaultSsr?: boolean | 'data-only';
261
266
  search?: {
262
267
  /**
263
268
  * Configures how unknown search params (= not returned by any `validateSearch`) are treated.
@@ -305,6 +310,16 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
305
310
  * @default ['window']
306
311
  */
307
312
  scrollToTopSelectors?: Array<string | (() => Element | null | undefined)>;
313
+ /**
314
+ * When `true`, disables the global catch boundary that normally wraps all route matches.
315
+ * This allows unhandled errors to bubble up to top-level error handlers in the browser.
316
+ *
317
+ * Useful for testing tools (like Storybook Test Runner), error reporting services,
318
+ * and debugging scenarios where you want errors to reach the browser's global error handlers.
319
+ *
320
+ * @default false
321
+ */
322
+ disableGlobalCatchBoundary?: boolean;
308
323
  }
309
324
  export interface RouterState<in out TRouteTree extends AnyRoute = AnyRoute, in out TRouteMatch = MakeRouteMatchUnion> {
310
325
  status: 'pending' | 'idle';
@@ -337,6 +352,7 @@ export interface BuildNextOptions {
337
352
  href?: string;
338
353
  _fromLocation?: ParsedLocation;
339
354
  unsafeRelative?: 'path';
355
+ _isNavigate?: boolean;
340
356
  }
341
357
  type NavigationEventInfo = {
342
358
  fromLocation?: ParsedLocation;
@@ -345,7 +361,7 @@ type NavigationEventInfo = {
345
361
  hrefChanged: boolean;
346
362
  hashChanged: boolean;
347
363
  };
348
- export type RouterEvents = {
364
+ export interface RouterEvents {
349
365
  onBeforeNavigate: {
350
366
  type: 'onBeforeNavigate';
351
367
  } & NavigationEventInfo;
@@ -361,20 +377,17 @@ export type RouterEvents = {
361
377
  onBeforeRouteMount: {
362
378
  type: 'onBeforeRouteMount';
363
379
  } & NavigationEventInfo;
364
- onInjectedHtml: {
365
- type: 'onInjectedHtml';
366
- promise: Promise<string>;
367
- };
368
380
  onRendered: {
369
381
  type: 'onRendered';
370
382
  } & NavigationEventInfo;
371
- };
383
+ }
372
384
  export type RouterEvent = RouterEvents[keyof RouterEvents];
373
385
  export type ListenerFn<TEvent extends RouterEvent> = (event: TEvent) => void;
374
386
  export type RouterListener<TRouterEvent extends RouterEvent> = {
375
387
  eventType: TRouterEvent['type'];
376
388
  fn: ListenerFn<TRouterEvent>;
377
389
  };
390
+ export type SubscribeFn = <TType extends keyof RouterEvents>(eventType: TType, fn: ListenerFn<RouterEvents[TType]>) => () => void;
378
391
  export interface MatchRoutesOpts {
379
392
  preload?: boolean;
380
393
  throwOnError?: boolean;
@@ -388,16 +401,13 @@ export type RouterContextOptions<TRouteTree extends AnyRoute> = AnyContext exten
388
401
  context: InferRouterContext<TRouteTree>;
389
402
  };
390
403
  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>;
391
- export interface RouterErrorSerializer<TSerializedError> {
392
- serialize: (err: unknown) => TSerializedError;
393
- deserialize: (err: TSerializedError) => unknown;
394
- }
395
404
  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>;
396
405
  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'];
397
406
  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;
398
407
  export type InvalidateFn<TRouter extends AnyRouter> = (opts?: {
399
408
  filter?: (d: MakeRouteMatchUnion<TRouter>) => boolean;
400
409
  sync?: boolean;
410
+ forcePending?: boolean;
401
411
  }) => Promise<void>;
402
412
  export type ParseLocationFn<TRouteTree extends AnyRoute> = (previousLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>, locationToParse?: HistoryLocation) => ParsedLocation<FullSearchSchema<TRouteTree>>;
403
413
  export type GetMatchRoutesFn = (pathname: string, routePathname: string | undefined) => {
@@ -411,31 +421,30 @@ export type LoadFn = (opts?: {
411
421
  }) => Promise<void>;
412
422
  export type CommitLocationFn = ({ viewTransition, ignoreBlocker, ...next }: ParsedLocation & CommitLocationOptions) => Promise<void>;
413
423
  export type StartTransitionFn = (fn: () => void) => void;
414
- export type SubscribeFn = <TType extends keyof RouterEvents>(eventType: TType, fn: ListenerFn<RouterEvents[TType]>) => () => void;
415
424
  export interface MatchRoutesFn {
416
- (pathname: string, locationSearch: AnySchema, opts?: MatchRoutesOpts): Array<AnyRouteMatch>;
425
+ (pathname: string, locationSearch?: AnySchema, opts?: MatchRoutesOpts): Array<MakeRouteMatchUnion>;
426
+ /**
427
+ * @deprecated use the following signature instead
428
+ */
417
429
  (next: ParsedLocation, opts?: MatchRoutesOpts): Array<AnyRouteMatch>;
418
430
  (pathnameOrNext: string | ParsedLocation, locationSearchOrOpts?: AnySchema | MatchRoutesOpts, opts?: MatchRoutesOpts): Array<AnyRouteMatch>;
419
431
  }
420
432
  export type GetMatchFn = (matchId: string) => AnyRouteMatch | undefined;
421
- export type UpdateMatchFn = (id: string, updater: (match: AnyRouteMatch) => AnyRouteMatch) => AnyRouteMatch;
433
+ export type UpdateMatchFn = (id: string, updater: (match: AnyRouteMatch) => AnyRouteMatch) => void;
422
434
  export type LoadRouteChunkFn = (route: AnyRoute) => Promise<Array<void>>;
423
435
  export type ResolveRedirect = (err: AnyRedirect) => ResolvedRedirect;
424
436
  export type ClearCacheFn<TRouter extends AnyRouter> = (opts?: {
425
437
  filter?: (d: MakeRouteMatchUnion<TRouter>) => boolean;
426
438
  }) => void;
427
- export interface ServerSrr {
439
+ export interface ServerSsr {
428
440
  injectedHtml: Array<InjectedHtmlEntry>;
429
441
  injectHtml: (getHtml: () => string | Promise<string>) => Promise<void>;
430
442
  injectScript: (getScript: () => string | Promise<string>, opts?: {
431
443
  logScript?: boolean;
432
444
  }) => Promise<void>;
433
- streamValue: (key: string, value: any) => void;
434
- streamedKeys: Set<string>;
435
- onMatchSettled: (opts: {
436
- router: AnyRouter;
437
- match: AnyRouteMatch;
438
- }) => any;
445
+ isDehydrated: () => boolean;
446
+ onRenderFinished: (listener: () => void) => void;
447
+ dehydrate: () => Promise<void>;
439
448
  }
440
449
  export type AnyRouterWithContext<TContext> = RouterCore<AnyRouteWithContext<TContext>, any, any, any, any>;
441
450
  export type AnyRouter = RouterCore<any, any, any, any, any>;
@@ -454,25 +463,6 @@ export declare function defaultSerializeError(err: unknown): {
454
463
  } | {
455
464
  data: unknown;
456
465
  };
457
- export interface ExtractedBaseEntry {
458
- dataType: '__beforeLoadContext' | 'loaderData';
459
- type: string;
460
- path: Array<string>;
461
- id: number;
462
- matchIndex: number;
463
- }
464
- export interface ExtractedStream extends ExtractedBaseEntry {
465
- type: 'stream';
466
- streamState: StreamState;
467
- }
468
- export interface ExtractedPromise extends ExtractedBaseEntry {
469
- type: 'promise';
470
- promiseState: DeferredPromiseState<any>;
471
- }
472
- export type ExtractedEntry = ExtractedStream | ExtractedPromise;
473
- export type StreamState = {
474
- promises: Array<ControlledPromise<string | null>>;
475
- };
476
466
  export type TrailingSlashOption = 'always' | 'never' | 'preserve';
477
467
  export declare function getLocationChangeInfo(routerState: {
478
468
  resolvedLocation?: ParsedLocation;
@@ -510,7 +500,8 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
510
500
  */
511
501
  constructor(options: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>);
512
502
  startTransition: StartTransitionFn;
513
- isShell: boolean;
503
+ isShell(): boolean;
504
+ isPrerendering(): boolean;
514
505
  update: UpdateFn<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>;
515
506
  get state(): RouterState<TRouteTree, import('./Matches.cjs').RouteMatch<any, any, any, any, any, any, any>>;
516
507
  buildRouteTree: () => void;
@@ -519,17 +510,10 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
519
510
  parseLocation: ParseLocationFn<TRouteTree>;
520
511
  resolvePathWithBase: (from: string, path: string) => string;
521
512
  get looseRoutesById(): Record<string, AnyRoute>;
522
- /**
523
- @deprecated use the following signature instead
524
- ```ts
525
- matchRoutes (
526
- next: ParsedLocation,
527
- opts?: { preload?: boolean; throwOnError?: boolean },
528
- ): Array<AnyRouteMatch>;
529
- ```
530
- */
531
513
  matchRoutes: MatchRoutesFn;
532
514
  private matchRoutesInternal;
515
+ /** a cache for `parsePathname` */
516
+ private parsePathnameCache;
533
517
  getMatchedRoutes: GetMatchRoutesFn;
534
518
  cancelMatch: (id: string) => void;
535
519
  cancelMatches: () => void;
@@ -562,24 +546,8 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
562
546
  matchRoute: MatchRouteFn<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory>;
563
547
  ssr?: {
564
548
  manifest: Manifest | undefined;
565
- serializer: StartSerializer;
566
- };
567
- serverSsr?: {
568
- injectedHtml: Array<InjectedHtmlEntry>;
569
- injectHtml: (getHtml: () => string | Promise<string>) => Promise<void>;
570
- injectScript: (getScript: () => string | Promise<string>, opts?: {
571
- logScript?: boolean;
572
- }) => Promise<void>;
573
- streamValue: (key: string, value: any) => void;
574
- streamedKeys: Set<string>;
575
- onMatchSettled: (opts: {
576
- router: AnyRouter;
577
- match: AnyRouteMatch;
578
- }) => any;
579
- };
580
- clientSsr?: {
581
- getStreamedValue: <T>(key: string) => T | undefined;
582
549
  };
550
+ serverSsr?: ServerSsr;
583
551
  _handleNotFound: (matches: Array<AnyRouteMatch>, err: NotFoundError, { updateMatch, }?: {
584
552
  updateMatch?: (id: string, updater: (match: AnyRouteMatch) => AnyRouteMatch) => void;
585
553
  }) => void;
@@ -604,15 +572,16 @@ interface RouteLike {
604
572
  caseSensitive?: boolean;
605
573
  };
606
574
  }
607
- export declare function processRouteTree<TRouteLike extends RouteLike>({ routeTree, initRoute, }: {
608
- routeTree: TRouteLike;
609
- initRoute?: (route: TRouteLike, index: number) => void;
610
- }): {
575
+ export type ProcessRouteTreeResult<TRouteLike extends RouteLike> = {
611
576
  routesById: Record<string, TRouteLike>;
612
577
  routesByPath: Record<string, TRouteLike>;
613
- flatRoutes: TRouteLike[];
578
+ flatRoutes: Array<TRouteLike>;
614
579
  };
615
- export declare function getMatchedRoutes<TRouteLike extends RouteLike>({ pathname, routePathname, basepath, caseSensitive, routesByPath, routesById, flatRoutes, }: {
580
+ export declare function processRouteTree<TRouteLike extends RouteLike>({ routeTree, initRoute, }: {
581
+ routeTree: TRouteLike;
582
+ initRoute?: (route: TRouteLike, index: number) => void;
583
+ }): ProcessRouteTreeResult<TRouteLike>;
584
+ export declare function getMatchedRoutes<TRouteLike extends RouteLike>({ pathname, routePathname, basepath, caseSensitive, routesByPath, routesById, flatRoutes, parseCache, }: {
616
585
  pathname: string;
617
586
  routePathname?: string;
618
587
  basepath: string;
@@ -620,6 +589,7 @@ export declare function getMatchedRoutes<TRouteLike extends RouteLike>({ pathnam
620
589
  routesByPath: Record<string, TRouteLike>;
621
590
  routesById: Record<string, TRouteLike>;
622
591
  flatRoutes: Array<TRouteLike>;
592
+ parseCache?: ParsePathnameCache;
623
593
  }): {
624
594
  matchedRoutes: TRouteLike[];
625
595
  routeParams: Record<string, string>;
@@ -40,7 +40,7 @@ function createScrollRestorationCache() {
40
40
  }
41
41
  const scrollRestorationCache = createScrollRestorationCache();
42
42
  const defaultGetScrollRestorationKey = (location) => {
43
- return location.state.key || location.href;
43
+ return location.state.__TSR_key || location.href;
44
44
  };
45
45
  function getCssSelector(el) {
46
46
  const path = [];
@@ -54,8 +54,14 @@ function getCssSelector(el) {
54
54
  return `${path.join(" > ")}`.toLowerCase();
55
55
  }
56
56
  let ignoreScroll = false;
57
- function restoreScroll(storageKey2, key, behavior, shouldScrollRestoration, scrollToTopSelectors) {
58
- var _a;
57
+ function restoreScroll({
58
+ storageKey: storageKey2,
59
+ key,
60
+ behavior,
61
+ shouldScrollRestoration,
62
+ scrollToTopSelectors,
63
+ location
64
+ }) {
59
65
  let byKey;
60
66
  try {
61
67
  byKey = JSON.parse(sessionStorage.getItem(storageKey2) || "{}");
@@ -63,11 +69,11 @@ function restoreScroll(storageKey2, key, behavior, shouldScrollRestoration, scro
63
69
  console.error(error);
64
70
  return;
65
71
  }
66
- const resolvedKey = key || ((_a = window.history.state) == null ? void 0 : _a.key);
72
+ const resolvedKey = key || window.history.state?.key;
67
73
  const elementEntries = byKey[resolvedKey];
68
74
  ignoreScroll = true;
69
75
  (() => {
70
- if (shouldScrollRestoration && elementEntries) {
76
+ if (shouldScrollRestoration && elementEntries && Object.keys(elementEntries).length > 0) {
71
77
  for (const elementSelector in elementEntries) {
72
78
  const entry = elementEntries[elementSelector];
73
79
  if (elementSelector === "window") {
@@ -86,7 +92,7 @@ function restoreScroll(storageKey2, key, behavior, shouldScrollRestoration, scro
86
92
  }
87
93
  return;
88
94
  }
89
- const hash = window.location.hash.split("#")[1];
95
+ const hash = (location ?? window.location).hash.split("#")[1];
90
96
  if (hash) {
91
97
  const hashScrollIntoViewOptions = (window.history.state || {}).__hashScrollIntoViewOptions ?? true;
92
98
  if (hashScrollIntoViewOptions) {
@@ -99,7 +105,7 @@ function restoreScroll(storageKey2, key, behavior, shouldScrollRestoration, scro
99
105
  }
100
106
  [
101
107
  "window",
102
- ...(scrollToTopSelectors == null ? void 0 : scrollToTopSelectors.filter((d) => d !== "window")) ?? []
108
+ ...scrollToTopSelectors?.filter((d) => d !== "window") ?? []
103
109
  ].forEach((selector) => {
104
110
  const element = selector === "window" ? window : typeof selector === "function" ? selector() : document.querySelector(selector);
105
111
  if (element) {
@@ -171,13 +177,14 @@ function setupScrollRestoration(router, force) {
171
177
  router.resetNextScroll = true;
172
178
  return;
173
179
  }
174
- restoreScroll(
180
+ restoreScroll({
175
181
  storageKey,
176
- cacheKey,
177
- router.options.scrollRestorationBehavior || void 0,
178
- router.isScrollRestoring || void 0,
179
- router.options.scrollToTopSelectors || void 0
180
- );
182
+ key: cacheKey,
183
+ behavior: router.options.scrollRestorationBehavior,
184
+ shouldScrollRestoration: router.isScrollRestoring,
185
+ scrollToTopSelectors: router.options.scrollToTopSelectors,
186
+ location: router.history.location
187
+ });
181
188
  if (router.isScrollRestoring) {
182
189
  scrollRestorationCache.set((state) => {
183
190
  state[cacheKey] = state[cacheKey] || {};
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-restoration.cjs","sources":["../../src/scroll-restoration.ts"],"sourcesContent":["import { functionalUpdate } from './utils'\nimport type { AnyRouter } from './router'\nimport type { ParsedLocation } from './location'\nimport type { NonNullableUpdater } from './utils'\n\nexport type ScrollRestorationEntry = { scrollX: number; scrollY: number }\n\nexport type ScrollRestorationByElement = Record<string, ScrollRestorationEntry>\n\nexport type ScrollRestorationByKey = Record<string, ScrollRestorationByElement>\n\nexport type ScrollRestorationCache = {\n state: ScrollRestorationByKey\n set: (updater: NonNullableUpdater<ScrollRestorationByKey>) => void\n}\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n scrollBehavior?: ScrollToOptions['behavior']\n}\n\nfunction getSafeSessionStorage() {\n try {\n if (\n typeof window !== 'undefined' &&\n typeof window.sessionStorage === 'object'\n ) {\n return window.sessionStorage\n }\n } catch {\n return undefined\n }\n return undefined\n}\n\nexport const storageKey = 'tsr-scroll-restoration-v1_3'\n\nconst throttle = (fn: (...args: Array<any>) => void, wait: number) => {\n let timeout: any\n return (...args: Array<any>) => {\n if (!timeout) {\n timeout = setTimeout(() => {\n fn(...args)\n timeout = null\n }, wait)\n }\n }\n}\n\nfunction createScrollRestorationCache(): ScrollRestorationCache | undefined {\n const safeSessionStorage = getSafeSessionStorage()\n if (!safeSessionStorage) {\n return undefined\n }\n\n const persistedState = safeSessionStorage.getItem(storageKey)\n let state: ScrollRestorationByKey = persistedState\n ? JSON.parse(persistedState)\n : {}\n\n return {\n state,\n // This setter is simply to make sure that we set the sessionStorage right\n // after the state is updated. It doesn't necessarily need to be a functional\n // update.\n set: (updater) => (\n (state = functionalUpdate(updater, state) || state),\n safeSessionStorage.setItem(storageKey, JSON.stringify(state))\n ),\n }\n}\n\nexport const scrollRestorationCache = createScrollRestorationCache()\n\n/**\n * The default `getKey` function for `useScrollRestoration`.\n * It returns the `key` from the location state or the `href` of the location.\n *\n * The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render.\n */\n\nexport const defaultGetScrollRestorationKey = (location: ParsedLocation) => {\n return location.state.key! || location.href\n}\n\nexport function getCssSelector(el: any): string {\n const path = []\n let parent\n while ((parent = el.parentNode)) {\n path.unshift(\n `${el.tagName}:nth-child(${([].indexOf as any).call(parent.children, el) + 1})`,\n )\n el = parent\n }\n return `${path.join(' > ')}`.toLowerCase()\n}\n\nlet ignoreScroll = false\n\n// NOTE: This function must remain pure and not use any outside variables\n// unless they are passed in as arguments. Why? Because we need to be able to\n// toString() it into a script tag to execute as early as possible in the browser\n// during SSR. Additionally, we also call it from within the router lifecycle\nexport function restoreScroll(\n storageKey: string,\n key: string | undefined,\n behavior: ScrollToOptions['behavior'] | undefined,\n shouldScrollRestoration: boolean | undefined,\n scrollToTopSelectors:\n | Array<string | (() => Element | null | undefined)>\n | undefined,\n) {\n let byKey: ScrollRestorationByKey\n\n try {\n byKey = JSON.parse(sessionStorage.getItem(storageKey) || '{}')\n } catch (error: any) {\n console.error(error)\n return\n }\n\n const resolvedKey = key || window.history.state?.key\n const elementEntries = byKey[resolvedKey]\n\n //\n ignoreScroll = true\n\n //\n ;(() => {\n // If we have a cached entry for this location state,\n // we always need to prefer that over the hash scroll.\n if (shouldScrollRestoration && elementEntries) {\n for (const elementSelector in elementEntries) {\n const entry = elementEntries[elementSelector]!\n if (elementSelector === 'window') {\n window.scrollTo({\n top: entry.scrollY,\n left: entry.scrollX,\n behavior,\n })\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n element.scrollLeft = entry.scrollX\n element.scrollTop = entry.scrollY\n }\n }\n }\n\n return\n }\n\n // If we don't have a cached entry for the hash,\n // Which means we've never seen this location before,\n // we need to check if there is a hash in the URL.\n // If there is, we need to scroll it's ID into view.\n const hash = window.location.hash.split('#')[1]\n\n if (hash) {\n const hashScrollIntoViewOptions =\n (window.history.state || {}).__hashScrollIntoViewOptions ?? true\n\n if (hashScrollIntoViewOptions) {\n const el = document.getElementById(hash)\n if (el) {\n el.scrollIntoView(hashScrollIntoViewOptions)\n }\n }\n\n return\n }\n\n // If there is no cached entry for the hash and there is no hash in the URL,\n // we need to scroll to the top of the page for every scrollToTop element\n ;[\n 'window',\n ...(scrollToTopSelectors?.filter((d) => d !== 'window') ?? []),\n ].forEach((selector) => {\n const element =\n selector === 'window'\n ? window\n : typeof selector === 'function'\n ? selector()\n : document.querySelector(selector)\n if (element) {\n element.scrollTo({\n top: 0,\n left: 0,\n behavior,\n })\n }\n })\n })()\n\n //\n ignoreScroll = false\n}\n\nexport function setupScrollRestoration(router: AnyRouter, force?: boolean) {\n if (scrollRestorationCache === undefined) {\n return\n }\n const shouldScrollRestoration =\n force ?? router.options.scrollRestoration ?? false\n\n if (shouldScrollRestoration) {\n router.isScrollRestoring = true\n }\n\n if (typeof document === 'undefined' || router.isScrollRestorationSetup) {\n return\n }\n\n router.isScrollRestorationSetup = true\n\n //\n ignoreScroll = false\n\n const getKey =\n router.options.getScrollRestorationKey || defaultGetScrollRestorationKey\n\n window.history.scrollRestoration = 'manual'\n\n // // Create a MutationObserver to monitor DOM changes\n // const mutationObserver = new MutationObserver(() => {\n // ;ignoreScroll = true\n // requestAnimationFrame(() => {\n // ;ignoreScroll = false\n\n // // Attempt to restore scroll position on each dom\n // // mutation until the user scrolls. We do this\n // // because dynamic content may come in at different\n // // ticks after the initial render and we want to\n // // keep up with that content as much as possible.\n // // As soon as the user scrolls, we no longer need\n // // to attempt router.\n // // console.log('mutation observer restoreScroll')\n // restoreScroll(\n // storageKey,\n // getKey(router.state.location),\n // router.options.scrollRestorationBehavior,\n // )\n // })\n // })\n\n // const observeDom = () => {\n // // Observe changes to the entire document\n // mutationObserver.observe(document, {\n // childList: true, // Detect added or removed child nodes\n // subtree: true, // Monitor all descendants\n // characterData: true, // Detect text content changes\n // })\n // }\n\n // const unobserveDom = () => {\n // mutationObserver.disconnect()\n // }\n\n // observeDom()\n\n const onScroll = (event: Event) => {\n // unobserveDom()\n\n if (ignoreScroll || !router.isScrollRestoring) {\n return\n }\n\n let elementSelector = ''\n\n if (event.target === document || event.target === window) {\n elementSelector = 'window'\n } else {\n const attrId = (event.target as Element).getAttribute(\n 'data-scroll-restoration-id',\n )\n\n if (attrId) {\n elementSelector = `[data-scroll-restoration-id=\"${attrId}\"]`\n } else {\n elementSelector = getCssSelector(event.target)\n }\n }\n\n const restoreKey = getKey(router.state.location)\n\n scrollRestorationCache.set((state) => {\n const keyEntry = (state[restoreKey] =\n state[restoreKey] || ({} as ScrollRestorationByElement))\n\n const elementEntry = (keyEntry[elementSelector] =\n keyEntry[elementSelector] || ({} as ScrollRestorationEntry))\n\n if (elementSelector === 'window') {\n elementEntry.scrollX = window.scrollX || 0\n elementEntry.scrollY = window.scrollY || 0\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n elementEntry.scrollX = element.scrollLeft || 0\n elementEntry.scrollY = element.scrollTop || 0\n }\n }\n\n return state\n })\n }\n\n // Throttle the scroll event to avoid excessive updates\n if (typeof document !== 'undefined') {\n document.addEventListener('scroll', throttle(onScroll, 100), true)\n }\n\n router.subscribe('onRendered', (event) => {\n // unobserveDom()\n\n const cacheKey = getKey(event.toLocation)\n\n // If the user doesn't want to restore the scroll position,\n // we don't need to do anything.\n if (!router.resetNextScroll) {\n router.resetNextScroll = true\n return\n }\n\n restoreScroll(\n storageKey,\n cacheKey,\n router.options.scrollRestorationBehavior || undefined,\n router.isScrollRestoring || undefined,\n router.options.scrollToTopSelectors || undefined,\n )\n\n if (router.isScrollRestoring) {\n // Mark the location as having been seen\n scrollRestorationCache.set((state) => {\n state[cacheKey] = state[cacheKey] || ({} as ScrollRestorationByElement)\n\n return state\n })\n }\n })\n}\n\n/**\n * @internal\n * Handles hash-based scrolling after navigation completes.\n * To be used in framework-specific <Transitioner> components during the onResolved event.\n *\n * Provides hash scrolling for programmatic navigation when default browser handling is prevented.\n * @param router The router instance containing current location and state\n */\nexport function handleHashScroll(router: AnyRouter) {\n if (typeof document !== 'undefined' && (document as any).querySelector) {\n const hashScrollIntoViewOptions =\n router.state.location.state.__hashScrollIntoViewOptions ?? true\n\n if (hashScrollIntoViewOptions && router.state.location.hash !== '') {\n const el = document.getElementById(router.state.location.hash)\n if (el) {\n el.scrollIntoView(hashScrollIntoViewOptions)\n }\n }\n }\n}\n"],"names":["functionalUpdate","storageKey"],"mappings":"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"}
1
+ {"version":3,"file":"scroll-restoration.cjs","sources":["../../src/scroll-restoration.ts"],"sourcesContent":["import { functionalUpdate } from './utils'\nimport type { AnyRouter } from './router'\nimport type { ParsedLocation } from './location'\nimport type { NonNullableUpdater } from './utils'\nimport type { HistoryLocation } from '@tanstack/history'\n\nexport type ScrollRestorationEntry = { scrollX: number; scrollY: number }\n\nexport type ScrollRestorationByElement = Record<string, ScrollRestorationEntry>\n\nexport type ScrollRestorationByKey = Record<string, ScrollRestorationByElement>\n\nexport type ScrollRestorationCache = {\n state: ScrollRestorationByKey\n set: (updater: NonNullableUpdater<ScrollRestorationByKey>) => void\n}\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n scrollBehavior?: ScrollToOptions['behavior']\n}\n\nfunction getSafeSessionStorage() {\n try {\n if (\n typeof window !== 'undefined' &&\n typeof window.sessionStorage === 'object'\n ) {\n return window.sessionStorage\n }\n } catch {\n return undefined\n }\n return undefined\n}\n\nexport const storageKey = 'tsr-scroll-restoration-v1_3'\n\nconst throttle = (fn: (...args: Array<any>) => void, wait: number) => {\n let timeout: any\n return (...args: Array<any>) => {\n if (!timeout) {\n timeout = setTimeout(() => {\n fn(...args)\n timeout = null\n }, wait)\n }\n }\n}\n\nfunction createScrollRestorationCache(): ScrollRestorationCache | undefined {\n const safeSessionStorage = getSafeSessionStorage()\n if (!safeSessionStorage) {\n return undefined\n }\n\n const persistedState = safeSessionStorage.getItem(storageKey)\n let state: ScrollRestorationByKey = persistedState\n ? JSON.parse(persistedState)\n : {}\n\n return {\n state,\n // This setter is simply to make sure that we set the sessionStorage right\n // after the state is updated. It doesn't necessarily need to be a functional\n // update.\n set: (updater) => (\n (state = functionalUpdate(updater, state) || state),\n safeSessionStorage.setItem(storageKey, JSON.stringify(state))\n ),\n }\n}\n\nexport const scrollRestorationCache = createScrollRestorationCache()\n\n/**\n * The default `getKey` function for `useScrollRestoration`.\n * It returns the `key` from the location state or the `href` of the location.\n *\n * The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render.\n */\n\nexport const defaultGetScrollRestorationKey = (location: ParsedLocation) => {\n return location.state.__TSR_key! || location.href\n}\n\nexport function getCssSelector(el: any): string {\n const path = []\n let parent\n while ((parent = el.parentNode)) {\n path.unshift(\n `${el.tagName}:nth-child(${([].indexOf as any).call(parent.children, el) + 1})`,\n )\n el = parent\n }\n return `${path.join(' > ')}`.toLowerCase()\n}\n\nlet ignoreScroll = false\n\n// NOTE: This function must remain pure and not use any outside variables\n// unless they are passed in as arguments. Why? Because we need to be able to\n// toString() it into a script tag to execute as early as possible in the browser\n// during SSR. Additionally, we also call it from within the router lifecycle\nexport function restoreScroll({\n storageKey,\n key,\n behavior,\n shouldScrollRestoration,\n scrollToTopSelectors,\n location,\n}: {\n storageKey: string\n key?: string\n behavior?: ScrollToOptions['behavior']\n shouldScrollRestoration?: boolean\n scrollToTopSelectors?: Array<string | (() => Element | null | undefined)>\n location?: HistoryLocation\n}) {\n let byKey: ScrollRestorationByKey\n\n try {\n byKey = JSON.parse(sessionStorage.getItem(storageKey) || '{}')\n } catch (error: any) {\n console.error(error)\n return\n }\n\n const resolvedKey = key || window.history.state?.key\n const elementEntries = byKey[resolvedKey]\n\n //\n ignoreScroll = true\n\n //\n ;(() => {\n // If we have a cached entry for this location state,\n // we always need to prefer that over the hash scroll.\n if (\n shouldScrollRestoration &&\n elementEntries &&\n Object.keys(elementEntries).length > 0\n ) {\n for (const elementSelector in elementEntries) {\n const entry = elementEntries[elementSelector]!\n if (elementSelector === 'window') {\n window.scrollTo({\n top: entry.scrollY,\n left: entry.scrollX,\n behavior,\n })\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n element.scrollLeft = entry.scrollX\n element.scrollTop = entry.scrollY\n }\n }\n }\n\n return\n }\n\n // If we don't have a cached entry for the hash,\n // Which means we've never seen this location before,\n // we need to check if there is a hash in the URL.\n // If there is, we need to scroll it's ID into view.\n const hash = (location ?? window.location).hash.split('#')[1]\n\n if (hash) {\n const hashScrollIntoViewOptions =\n (window.history.state || {}).__hashScrollIntoViewOptions ?? true\n\n if (hashScrollIntoViewOptions) {\n const el = document.getElementById(hash)\n if (el) {\n el.scrollIntoView(hashScrollIntoViewOptions)\n }\n }\n\n return\n }\n\n // If there is no cached entry for the hash and there is no hash in the URL,\n // we need to scroll to the top of the page for every scrollToTop element\n ;[\n 'window',\n ...(scrollToTopSelectors?.filter((d) => d !== 'window') ?? []),\n ].forEach((selector) => {\n const element =\n selector === 'window'\n ? window\n : typeof selector === 'function'\n ? selector()\n : document.querySelector(selector)\n if (element) {\n element.scrollTo({\n top: 0,\n left: 0,\n behavior,\n })\n }\n })\n })()\n\n //\n ignoreScroll = false\n}\n\nexport function setupScrollRestoration(router: AnyRouter, force?: boolean) {\n if (scrollRestorationCache === undefined) {\n return\n }\n const shouldScrollRestoration =\n force ?? router.options.scrollRestoration ?? false\n\n if (shouldScrollRestoration) {\n router.isScrollRestoring = true\n }\n\n if (typeof document === 'undefined' || router.isScrollRestorationSetup) {\n return\n }\n\n router.isScrollRestorationSetup = true\n\n //\n ignoreScroll = false\n\n const getKey =\n router.options.getScrollRestorationKey || defaultGetScrollRestorationKey\n\n window.history.scrollRestoration = 'manual'\n\n // // Create a MutationObserver to monitor DOM changes\n // const mutationObserver = new MutationObserver(() => {\n // ;ignoreScroll = true\n // requestAnimationFrame(() => {\n // ;ignoreScroll = false\n\n // // Attempt to restore scroll position on each dom\n // // mutation until the user scrolls. We do this\n // // because dynamic content may come in at different\n // // ticks after the initial render and we want to\n // // keep up with that content as much as possible.\n // // As soon as the user scrolls, we no longer need\n // // to attempt router.\n // // console.log('mutation observer restoreScroll')\n // restoreScroll(\n // storageKey,\n // getKey(router.state.location),\n // router.options.scrollRestorationBehavior,\n // )\n // })\n // })\n\n // const observeDom = () => {\n // // Observe changes to the entire document\n // mutationObserver.observe(document, {\n // childList: true, // Detect added or removed child nodes\n // subtree: true, // Monitor all descendants\n // characterData: true, // Detect text content changes\n // })\n // }\n\n // const unobserveDom = () => {\n // mutationObserver.disconnect()\n // }\n\n // observeDom()\n\n const onScroll = (event: Event) => {\n // unobserveDom()\n\n if (ignoreScroll || !router.isScrollRestoring) {\n return\n }\n\n let elementSelector = ''\n\n if (event.target === document || event.target === window) {\n elementSelector = 'window'\n } else {\n const attrId = (event.target as Element).getAttribute(\n 'data-scroll-restoration-id',\n )\n\n if (attrId) {\n elementSelector = `[data-scroll-restoration-id=\"${attrId}\"]`\n } else {\n elementSelector = getCssSelector(event.target)\n }\n }\n\n const restoreKey = getKey(router.state.location)\n\n scrollRestorationCache.set((state) => {\n const keyEntry = (state[restoreKey] =\n state[restoreKey] || ({} as ScrollRestorationByElement))\n\n const elementEntry = (keyEntry[elementSelector] =\n keyEntry[elementSelector] || ({} as ScrollRestorationEntry))\n\n if (elementSelector === 'window') {\n elementEntry.scrollX = window.scrollX || 0\n elementEntry.scrollY = window.scrollY || 0\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n elementEntry.scrollX = element.scrollLeft || 0\n elementEntry.scrollY = element.scrollTop || 0\n }\n }\n\n return state\n })\n }\n\n // Throttle the scroll event to avoid excessive updates\n if (typeof document !== 'undefined') {\n document.addEventListener('scroll', throttle(onScroll, 100), true)\n }\n\n router.subscribe('onRendered', (event) => {\n // unobserveDom()\n\n const cacheKey = getKey(event.toLocation)\n\n // If the user doesn't want to restore the scroll position,\n // we don't need to do anything.\n if (!router.resetNextScroll) {\n router.resetNextScroll = true\n return\n }\n\n restoreScroll({\n storageKey,\n key: cacheKey,\n behavior: router.options.scrollRestorationBehavior,\n shouldScrollRestoration: router.isScrollRestoring,\n scrollToTopSelectors: router.options.scrollToTopSelectors,\n location: router.history.location,\n })\n\n if (router.isScrollRestoring) {\n // Mark the location as having been seen\n scrollRestorationCache.set((state) => {\n state[cacheKey] = state[cacheKey] || ({} as ScrollRestorationByElement)\n\n return state\n })\n }\n })\n}\n\n/**\n * @internal\n * Handles hash-based scrolling after navigation completes.\n * To be used in framework-specific <Transitioner> components during the onResolved event.\n *\n * Provides hash scrolling for programmatic navigation when default browser handling is prevented.\n * @param router The router instance containing current location and state\n */\nexport function handleHashScroll(router: AnyRouter) {\n if (typeof document !== 'undefined' && (document as any).querySelector) {\n const hashScrollIntoViewOptions =\n router.state.location.state.__hashScrollIntoViewOptions ?? true\n\n if (hashScrollIntoViewOptions && router.state.location.hash !== '') {\n const el = document.getElementById(router.state.location.hash)\n if (el) {\n el.scrollIntoView(hashScrollIntoViewOptions)\n }\n }\n }\n}\n"],"names":["functionalUpdate","storageKey"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { AnyRouter } from './router.cjs';
2
2
  import { ParsedLocation } from './location.cjs';
3
3
  import { NonNullableUpdater } from './utils.cjs';
4
+ import { HistoryLocation } from '@tanstack/history';
4
5
  export type ScrollRestorationEntry = {
5
6
  scrollX: number;
6
7
  scrollY: number;
@@ -25,7 +26,14 @@ export declare const scrollRestorationCache: ScrollRestorationCache | undefined;
25
26
  */
26
27
  export declare const defaultGetScrollRestorationKey: (location: ParsedLocation) => string;
27
28
  export declare function getCssSelector(el: any): string;
28
- export declare function restoreScroll(storageKey: string, key: string | undefined, behavior: ScrollToOptions['behavior'] | undefined, shouldScrollRestoration: boolean | undefined, scrollToTopSelectors: Array<string | (() => Element | null | undefined)> | undefined): void;
29
+ export declare function restoreScroll({ storageKey, key, behavior, shouldScrollRestoration, scrollToTopSelectors, location, }: {
30
+ storageKey: string;
31
+ key?: string;
32
+ behavior?: ScrollToOptions['behavior'];
33
+ shouldScrollRestoration?: boolean;
34
+ scrollToTopSelectors?: Array<string | (() => Element | null | undefined)>;
35
+ location?: HistoryLocation;
36
+ }): void;
29
37
  export declare function setupScrollRestoration(router: AnyRouter, force?: boolean): void;
30
38
  /**
31
39
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"searchMiddleware.cjs","sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import { deepEqual } from './utils'\nimport type { NoInfer, PickOptional } from './utils'\nimport type { SearchMiddleware } from './route'\nimport type { IsRequiredParams } from './link'\n\nexport function retainSearchParams<TSearchSchema extends object>(\n keys: Array<keyof TSearchSchema> | true,\n): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n const result = next(search)\n if (keys === true) {\n return { ...search, ...result }\n }\n // add missing keys from search to result\n keys.forEach((key) => {\n if (!(key in result)) {\n result[key] = search[key]\n }\n })\n return result\n }\n}\n\nexport function stripSearchParams<\n TSearchSchema,\n TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,\n const TValues =\n | Partial<NoInfer<TOptionalProps>>\n | Array<keyof TOptionalProps>,\n const TInput = IsRequiredParams<TSearchSchema> extends never\n ? TValues | true\n : TValues,\n>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n if (input === true) {\n return {}\n }\n const result = next(search) as Record<string, unknown>\n if (Array.isArray(input)) {\n input.forEach((key) => {\n delete result[key]\n })\n } else {\n Object.entries(input as Record<string, unknown>).forEach(\n ([key, value]) => {\n if (deepEqual(result[key], value)) {\n delete result[key]\n }\n },\n )\n }\n return result as any\n }\n}\n"],"names":["deepEqual"],"mappings":";;;AAKO,SAAS,mBACd,MACiC;AACjC,SAAO,CAAC,EAAE,QAAQ,WAAW;AACrB,UAAA,SAAS,KAAK,MAAM;AAC1B,QAAI,SAAS,MAAM;AACjB,aAAO,EAAE,GAAG,QAAQ,GAAG,OAAO;AAAA,IAAA;AAG3B,SAAA,QAAQ,CAAC,QAAQ;AAChB,UAAA,EAAE,OAAO,SAAS;AACb,eAAA,GAAG,IAAI,OAAO,GAAG;AAAA,MAAA;AAAA,IAC1B,CACD;AACM,WAAA;AAAA,EACT;AACF;AAEO,SAAS,kBASd,OAAyD;AACzD,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,QAAI,UAAU,MAAM;AAClB,aAAO,CAAC;AAAA,IAAA;AAEJ,UAAA,SAAS,KAAK,MAAM;AACtB,QAAA,MAAM,QAAQ,KAAK,GAAG;AAClB,YAAA,QAAQ,CAAC,QAAQ;AACrB,eAAO,OAAO,GAAG;AAAA,MAAA,CAClB;AAAA,IAAA,OACI;AACE,aAAA,QAAQ,KAAgC,EAAE;AAAA,QAC/C,CAAC,CAAC,KAAK,KAAK,MAAM;AAChB,cAAIA,MAAU,UAAA,OAAO,GAAG,GAAG,KAAK,GAAG;AACjC,mBAAO,OAAO,GAAG;AAAA,UAAA;AAAA,QACnB;AAAA,MAEJ;AAAA,IAAA;AAEK,WAAA;AAAA,EACT;AACF;;;"}
1
+ {"version":3,"file":"searchMiddleware.cjs","sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import { deepEqual } from './utils'\nimport type { NoInfer, PickOptional } from './utils'\nimport type { SearchMiddleware } from './route'\nimport type { IsRequiredParams } from './link'\n\nexport function retainSearchParams<TSearchSchema extends object>(\n keys: Array<keyof TSearchSchema> | true,\n): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n const result = next(search)\n if (keys === true) {\n return { ...search, ...result }\n }\n // add missing keys from search to result\n keys.forEach((key) => {\n if (!(key in result)) {\n result[key] = search[key]\n }\n })\n return result\n }\n}\n\nexport function stripSearchParams<\n TSearchSchema,\n TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,\n const TValues =\n | Partial<NoInfer<TOptionalProps>>\n | Array<keyof TOptionalProps>,\n const TInput = IsRequiredParams<TSearchSchema> extends never\n ? TValues | true\n : TValues,\n>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n if (input === true) {\n return {}\n }\n const result = next(search) as Record<string, unknown>\n if (Array.isArray(input)) {\n input.forEach((key) => {\n delete result[key]\n })\n } else {\n Object.entries(input as Record<string, unknown>).forEach(\n ([key, value]) => {\n if (deepEqual(result[key], value)) {\n delete result[key]\n }\n },\n )\n }\n return result as any\n }\n}\n"],"names":["deepEqual"],"mappings":";;;AAKO,SAAS,mBACd,MACiC;AACjC,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,SAAS,MAAM;AACjB,aAAO,EAAE,GAAG,QAAQ,GAAG,OAAA;AAAA,IACzB;AAEA,SAAK,QAAQ,CAAC,QAAQ;AACpB,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI,OAAO,GAAG;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,kBASd,OAAyD;AACzD,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,QAAI,UAAU,MAAM;AAClB,aAAO,CAAA;AAAA,IACT;AACA,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,QAAQ,CAAC,QAAQ;AACrB,eAAO,OAAO,GAAG;AAAA,MACnB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,QAAQ,KAAgC,EAAE;AAAA,QAC/C,CAAC,CAAC,KAAK,KAAK,MAAM;AAChB,cAAIA,MAAAA,UAAU,OAAO,GAAG,GAAG,KAAK,GAAG;AACjC,mBAAO,OAAO,GAAG;AAAA,UACnB;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AACF;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"searchParams.cjs","sources":["../../src/searchParams.ts"],"sourcesContent":["import { decode, encode } from './qss'\nimport type { AnySchema } from './validators'\n\nexport const defaultParseSearch = parseSearchWith(JSON.parse)\nexport const defaultStringifySearch = stringifySearchWith(\n JSON.stringify,\n JSON.parse,\n)\n\nexport function parseSearchWith(parser: (str: string) => any) {\n return (searchStr: string): AnySchema => {\n if (searchStr.substring(0, 1) === '?') {\n searchStr = searchStr.substring(1)\n }\n\n const query: Record<string, unknown> = decode(searchStr)\n\n // Try to parse any query params that might be json\n for (const key in query) {\n const value = query[key]\n if (typeof value === 'string') {\n try {\n query[key] = parser(value)\n } catch (err) {\n //\n }\n }\n }\n\n return query\n }\n}\n\nexport function stringifySearchWith(\n stringify: (search: any) => string,\n parser?: (str: string) => any,\n) {\n function stringifyValue(val: any) {\n if (typeof val === 'object' && val !== null) {\n try {\n return stringify(val)\n } catch (err) {\n // silent\n }\n } else if (typeof val === 'string' && typeof parser === 'function') {\n try {\n // Check if it's a valid parseable string.\n // If it is, then stringify it again.\n parser(val)\n return stringify(val)\n } catch (err) {\n // silent\n }\n }\n return val\n }\n\n return (search: Record<string, any>) => {\n search = { ...search }\n\n Object.keys(search).forEach((key) => {\n const val = search[key]\n if (typeof val === 'undefined' || val === undefined) {\n delete search[key]\n } else {\n search[key] = stringifyValue(val)\n }\n })\n\n const searchStr = encode(search as Record<string, string>).toString()\n\n return searchStr ? `?${searchStr}` : ''\n }\n}\n\nexport type SearchSerializer = (searchObj: Record<string, any>) => string\nexport type SearchParser = (searchStr: string) => Record<string, any>\n"],"names":["decode","encode"],"mappings":";;;AAGa,MAAA,qBAAqB,gBAAgB,KAAK,KAAK;AACrD,MAAM,yBAAyB;AAAA,EACpC,KAAK;AAAA,EACL,KAAK;AACP;AAEO,SAAS,gBAAgB,QAA8B;AAC5D,SAAO,CAAC,cAAiC;AACvC,QAAI,UAAU,UAAU,GAAG,CAAC,MAAM,KAAK;AACzB,kBAAA,UAAU,UAAU,CAAC;AAAA,IAAA;AAG7B,UAAA,QAAiCA,WAAO,SAAS;AAGvD,eAAW,OAAO,OAAO;AACjB,YAAA,QAAQ,MAAM,GAAG;AACnB,UAAA,OAAO,UAAU,UAAU;AACzB,YAAA;AACI,gBAAA,GAAG,IAAI,OAAO,KAAK;AAAA,iBAClB,KAAK;AAAA,QAAA;AAAA,MAEd;AAAA,IACF;AAGK,WAAA;AAAA,EACT;AACF;AAEgB,SAAA,oBACd,WACA,QACA;AACA,WAAS,eAAe,KAAU;AAChC,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACvC,UAAA;AACF,eAAO,UAAU,GAAG;AAAA,eACb,KAAK;AAAA,MAAA;AAAA,eAGL,OAAO,QAAQ,YAAY,OAAO,WAAW,YAAY;AAC9D,UAAA;AAGF,eAAO,GAAG;AACV,eAAO,UAAU,GAAG;AAAA,eACb,KAAK;AAAA,MAAA;AAAA,IAEd;AAEK,WAAA;AAAA,EAAA;AAGT,SAAO,CAAC,WAAgC;AAC7B,aAAA,EAAE,GAAG,OAAO;AAErB,WAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,QAAQ;AAC7B,YAAA,MAAM,OAAO,GAAG;AACtB,UAAI,OAAO,QAAQ,eAAe,QAAQ,QAAW;AACnD,eAAO,OAAO,GAAG;AAAA,MAAA,OACZ;AACE,eAAA,GAAG,IAAI,eAAe,GAAG;AAAA,MAAA;AAAA,IAClC,CACD;AAED,UAAM,YAAYC,IAAAA,OAAO,MAAgC,EAAE,SAAS;AAE7D,WAAA,YAAY,IAAI,SAAS,KAAK;AAAA,EACvC;AACF;;;;;"}
1
+ {"version":3,"file":"searchParams.cjs","sources":["../../src/searchParams.ts"],"sourcesContent":["import { decode, encode } from './qss'\nimport type { AnySchema } from './validators'\n\nexport const defaultParseSearch = parseSearchWith(JSON.parse)\nexport const defaultStringifySearch = stringifySearchWith(\n JSON.stringify,\n JSON.parse,\n)\n\nexport function parseSearchWith(parser: (str: string) => any) {\n return (searchStr: string): AnySchema => {\n if (searchStr.substring(0, 1) === '?') {\n searchStr = searchStr.substring(1)\n }\n\n const query: Record<string, unknown> = decode(searchStr)\n\n // Try to parse any query params that might be json\n for (const key in query) {\n const value = query[key]\n if (typeof value === 'string') {\n try {\n query[key] = parser(value)\n } catch (err) {\n //\n }\n }\n }\n\n return query\n }\n}\n\nexport function stringifySearchWith(\n stringify: (search: any) => string,\n parser?: (str: string) => any,\n) {\n function stringifyValue(val: any) {\n if (typeof val === 'object' && val !== null) {\n try {\n return stringify(val)\n } catch (err) {\n // silent\n }\n } else if (typeof val === 'string' && typeof parser === 'function') {\n try {\n // Check if it's a valid parseable string.\n // If it is, then stringify it again.\n parser(val)\n return stringify(val)\n } catch (err) {\n // silent\n }\n }\n return val\n }\n\n return (search: Record<string, any>) => {\n search = { ...search }\n\n Object.keys(search).forEach((key) => {\n const val = search[key]\n if (typeof val === 'undefined' || val === undefined) {\n delete search[key]\n } else {\n search[key] = stringifyValue(val)\n }\n })\n\n const searchStr = encode(search as Record<string, string>).toString()\n\n return searchStr ? `?${searchStr}` : ''\n }\n}\n\nexport type SearchSerializer = (searchObj: Record<string, any>) => string\nexport type SearchParser = (searchStr: string) => Record<string, any>\n"],"names":["decode","encode"],"mappings":";;;AAGO,MAAM,qBAAqB,gBAAgB,KAAK,KAAK;AACrD,MAAM,yBAAyB;AAAA,EACpC,KAAK;AAAA,EACL,KAAK;AACP;AAEO,SAAS,gBAAgB,QAA8B;AAC5D,SAAO,CAAC,cAAiC;AACvC,QAAI,UAAU,UAAU,GAAG,CAAC,MAAM,KAAK;AACrC,kBAAY,UAAU,UAAU,CAAC;AAAA,IACnC;AAEA,UAAM,QAAiCA,IAAAA,OAAO,SAAS;AAGvD,eAAW,OAAO,OAAO;AACvB,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,OAAO,UAAU,UAAU;AAC7B,YAAI;AACF,gBAAM,GAAG,IAAI,OAAO,KAAK;AAAA,QAC3B,SAAS,KAAK;AAAA,QAEd;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,oBACd,WACA,QACA;AACA,WAAS,eAAe,KAAU;AAChC,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAI;AACF,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,KAAK;AAAA,MAEd;AAAA,IACF,WAAW,OAAO,QAAQ,YAAY,OAAO,WAAW,YAAY;AAClE,UAAI;AAGF,eAAO,GAAG;AACV,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,KAAK;AAAA,MAEd;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,WAAgC;AACtC,aAAS,EAAE,GAAG,OAAA;AAEd,WAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,QAAQ;AACnC,YAAM,MAAM,OAAO,GAAG;AACtB,UAAI,OAAO,QAAQ,eAAe,QAAQ,QAAW;AACnD,eAAO,OAAO,GAAG;AAAA,MACnB,OAAO;AACL,eAAO,GAAG,IAAI,eAAe,GAAG;AAAA,MAClC;AAAA,IACF,CAAC;AAED,UAAM,YAAYC,IAAAA,OAAO,MAAgC,EAAE,SAAA;AAE3D,WAAO,YAAY,IAAI,SAAS,KAAK;AAAA,EACvC;AACF;;;;;"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const headers = require("./headers.cjs");
4
+ const json = require("./json.cjs");
5
+ const ssrClient = require("./ssr-client.cjs");
6
+ exports.headersInitToObject = headers.headersInitToObject;
7
+ exports.mergeHeaders = headers.mergeHeaders;
8
+ exports.json = json.json;
9
+ exports.hydrate = ssrClient.hydrate;
10
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,5 @@
1
+ export { mergeHeaders, headersInitToObject } from './headers.cjs';
2
+ export { json } from './json.cjs';
3
+ export type { JsonResponse } from './json.cjs';
4
+ export { hydrate } from './ssr-client.cjs';
5
+ export * from './ssr-client.cjs';
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const history = require("@tanstack/history");
4
+ const headers = require("./headers.cjs");
5
+ const ssrServer = require("./ssr-server.cjs");
6
+ function createRequestHandler({
7
+ createRouter,
8
+ request,
9
+ getRouterManifest
10
+ }) {
11
+ return async (cb) => {
12
+ const router = createRouter();
13
+ ssrServer.attachRouterServerSsrUtils(router, await getRouterManifest?.());
14
+ const url = new URL(request.url, "http://localhost");
15
+ const href = url.href.replace(url.origin, "");
16
+ const history$1 = history.createMemoryHistory({
17
+ initialEntries: [href]
18
+ });
19
+ router.update({
20
+ history: history$1
21
+ });
22
+ await router.load();
23
+ await router.serverSsr?.dehydrate();
24
+ const responseHeaders = getRequestHeaders({
25
+ router
26
+ });
27
+ return cb({
28
+ request,
29
+ router,
30
+ responseHeaders
31
+ });
32
+ };
33
+ }
34
+ function getRequestHeaders(opts) {
35
+ let headers$1 = headers.mergeHeaders(
36
+ {
37
+ "Content-Type": "text/html; charset=UTF-8"
38
+ },
39
+ ...opts.router.state.matches.map((match) => {
40
+ return match.headers;
41
+ })
42
+ );
43
+ const { redirect } = opts.router.state;
44
+ if (redirect) {
45
+ headers$1 = headers.mergeHeaders(headers$1, redirect.headers);
46
+ }
47
+ return headers$1;
48
+ }
49
+ exports.createRequestHandler = createRequestHandler;
50
+ //# sourceMappingURL=createRequestHandler.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRequestHandler.cjs","sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport { mergeHeaders } from './headers'\nimport { attachRouterServerSsrUtils } from './ssr-server'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => Manifest | Promise<Manifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const router = createRouter()\n\n attachRouterServerSsrUtils(router, await getRouterManifest?.())\n\n const url = new URL(request.url, 'http://localhost')\n\n const href = url.href.replace(url.origin, '')\n\n // Create a history for the router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n // Update the router with the history and context\n router.update({\n history,\n })\n\n await router.load()\n\n await router.serverSsr?.dehydrate()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n return cb({\n request,\n router,\n responseHeaders,\n } as any)\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n let headers = mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...opts.router.state.matches.map((match) => {\n return match.headers\n }),\n )\n\n // Handle Redirects\n const { redirect } = opts.router.state\n\n if (redirect) {\n headers = mergeHeaders(headers, redirect.headers)\n }\n\n return headers\n}\n"],"names":["attachRouterServerSsrUtils","history","createMemoryHistory","headers","mergeHeaders"],"mappings":";;;;;AAWO,SAAS,qBAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,GAI4B;AAC1B,SAAO,OAAO,OAAO;AACnB,UAAM,SAAS,aAAA;AAEfA,yCAA2B,QAAQ,MAAM,qBAAqB;AAE9D,UAAM,MAAM,IAAI,IAAI,QAAQ,KAAK,kBAAkB;AAEnD,UAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAAE;AAG5C,UAAMC,YAAUC,QAAAA,oBAAoB;AAAA,MAClC,gBAAgB,CAAC,IAAI;AAAA,IAAA,CACtB;AAGD,WAAO,OAAO;AAAA,MAAA,SACZD;AAAAA,IAAA,CACD;AAED,UAAM,OAAO,KAAA;AAEb,UAAM,OAAO,WAAW,UAAA;AAExB,UAAM,kBAAkB,kBAAkB;AAAA,MACxC;AAAA,IAAA,CACD;AAED,WAAO,GAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACM;AAAA,EACV;AACF;AAEA,SAAS,kBAAkB,MAAsC;AAC/D,MAAIE,YAAUC,QAAAA;AAAAA,IACZ;AAAA,MACE,gBAAgB;AAAA,IAAA;AAAA,IAElB,GAAG,KAAK,OAAO,MAAM,QAAQ,IAAI,CAAC,UAAU;AAC1C,aAAO,MAAM;AAAA,IACf,CAAC;AAAA,EAAA;AAIH,QAAM,EAAE,SAAA,IAAa,KAAK,OAAO;AAEjC,MAAI,UAAU;AACZD,gBAAUC,QAAAA,aAAaD,WAAS,SAAS,OAAO;AAAA,EAClD;AAEA,SAAOA;AACT;;"}
@@ -0,0 +1,9 @@
1
+ import { HandlerCallback } from './handlerCallback.cjs';
2
+ import { AnyRouter } from '../router.cjs';
3
+ import { Manifest } from '../manifest.cjs';
4
+ export type RequestHandler<TRouter extends AnyRouter> = (cb: HandlerCallback<TRouter>) => Promise<Response>;
5
+ export declare function createRequestHandler<TRouter extends AnyRouter>({ createRouter, request, getRouterManifest, }: {
6
+ createRouter: () => TRouter;
7
+ request: Request;
8
+ getRouterManifest?: () => Manifest | Promise<Manifest>;
9
+ }): RequestHandler<TRouter>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function defineHandlerCallback(handler) {
4
+ return handler;
5
+ }
6
+ exports.defineHandlerCallback = defineHandlerCallback;
7
+ //# sourceMappingURL=handlerCallback.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlerCallback.cjs","sources":["../../../src/ssr/handlerCallback.ts"],"sourcesContent":["import type { AnyRouter } from '../router'\n\nexport interface HandlerCallback<TRouter extends AnyRouter> {\n (ctx: {\n request: Request\n router: TRouter\n responseHeaders: Headers\n }): Response | Promise<Response>\n}\n\nexport function defineHandlerCallback<TRouter extends AnyRouter>(\n handler: HandlerCallback<TRouter>,\n): HandlerCallback<TRouter> {\n return handler\n}\n"],"names":[],"mappings":";;AAUO,SAAS,sBACd,SAC0B;AAC1B,SAAO;AACT;;"}
@@ -0,0 +1,9 @@
1
+ import { AnyRouter } from '../router.cjs';
2
+ export interface HandlerCallback<TRouter extends AnyRouter> {
3
+ (ctx: {
4
+ request: Request;
5
+ router: TRouter;
6
+ responseHeaders: Headers;
7
+ }): Response | Promise<Response>;
8
+ }
9
+ export declare function defineHandlerCallback<TRouter extends AnyRouter>(handler: HandlerCallback<TRouter>): HandlerCallback<TRouter>;