@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.12 → 3.2.0-ultramodern.121

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 (136) hide show
  1. package/dist/cjs/cli/index.js +89 -31
  2. package/dist/cjs/cli/routeSplitting.js +55 -0
  3. package/dist/cjs/cli/tanstackTypes.js +172 -170
  4. package/dist/cjs/cli.js +12 -8
  5. package/dist/cjs/runtime/basepathRewrite.js +12 -8
  6. package/dist/cjs/runtime/dataMutation.js +9 -5
  7. package/dist/cjs/runtime/hooks.js +20 -19
  8. package/dist/cjs/runtime/hydrationBoundary.js +48 -0
  9. package/dist/cjs/runtime/index.js +79 -35
  10. package/dist/cjs/runtime/lifecycle.js +21 -91
  11. package/dist/cjs/runtime/loaderBridge.js +173 -0
  12. package/dist/cjs/runtime/outlet.js +58 -0
  13. package/dist/cjs/runtime/plugin.js +195 -114
  14. package/dist/cjs/runtime/plugin.node.js +45 -45
  15. package/dist/cjs/runtime/plugin.worker.js +53 -0
  16. package/dist/cjs/runtime/pluginCore.js +55 -0
  17. package/dist/cjs/runtime/prefetchLink.js +10 -6
  18. package/dist/cjs/runtime/register.js +56 -0
  19. package/dist/cjs/runtime/routeTree.js +74 -207
  20. package/dist/cjs/runtime/router.js +41 -0
  21. package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
  22. package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
  23. package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
  24. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
  25. package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
  26. package/dist/cjs/runtime/rsc/client.js +9 -5
  27. package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
  28. package/dist/cjs/runtime/rsc/index.js +9 -5
  29. package/dist/cjs/runtime/rsc/payloadRouter.js +44 -6
  30. package/dist/cjs/runtime/rsc/server.js +9 -5
  31. package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
  32. package/dist/cjs/runtime/rsc/symbols.js +20 -15
  33. package/dist/cjs/runtime/state.js +45 -0
  34. package/dist/cjs/runtime/types.js +31 -1
  35. package/dist/cjs/runtime/utils.js +9 -10
  36. package/dist/cjs/runtime.js +9 -5
  37. package/dist/esm/cli/index.mjs +75 -27
  38. package/dist/esm/cli/routeSplitting.mjs +14 -0
  39. package/dist/esm/cli/tanstackTypes.mjs +158 -160
  40. package/dist/esm/runtime/hooks.mjs +1 -8
  41. package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
  42. package/dist/esm/runtime/index.mjs +5 -2
  43. package/dist/esm/runtime/lifecycle.mjs +1 -82
  44. package/dist/esm/runtime/loaderBridge.mjs +114 -0
  45. package/dist/esm/runtime/outlet.mjs +17 -0
  46. package/dist/esm/runtime/plugin.mjs +191 -114
  47. package/dist/esm/runtime/plugin.node.mjs +40 -44
  48. package/dist/esm/runtime/plugin.worker.mjs +1 -0
  49. package/dist/esm/runtime/pluginCore.mjs +14 -0
  50. package/dist/esm/runtime/prefetchLink.mjs +1 -1
  51. package/dist/esm/runtime/register.mjs +18 -0
  52. package/dist/esm/runtime/routeTree.mjs +59 -193
  53. package/dist/esm/runtime/router.mjs +2 -0
  54. package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
  55. package/dist/esm/runtime/state.mjs +7 -0
  56. package/dist/esm/runtime/types.mjs +7 -0
  57. package/dist/esm/runtime/utils.mjs +0 -5
  58. package/dist/esm-node/cli/index.mjs +75 -27
  59. package/dist/esm-node/cli/routeSplitting.mjs +15 -0
  60. package/dist/esm-node/cli/tanstackTypes.mjs +158 -160
  61. package/dist/esm-node/runtime/hooks.mjs +1 -8
  62. package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
  63. package/dist/esm-node/runtime/index.mjs +5 -2
  64. package/dist/esm-node/runtime/lifecycle.mjs +1 -82
  65. package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
  66. package/dist/esm-node/runtime/outlet.mjs +18 -0
  67. package/dist/esm-node/runtime/plugin.mjs +191 -114
  68. package/dist/esm-node/runtime/plugin.node.mjs +40 -44
  69. package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
  70. package/dist/esm-node/runtime/pluginCore.mjs +15 -0
  71. package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
  72. package/dist/esm-node/runtime/register.mjs +19 -0
  73. package/dist/esm-node/runtime/routeTree.mjs +59 -193
  74. package/dist/esm-node/runtime/router.mjs +3 -0
  75. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
  76. package/dist/esm-node/runtime/state.mjs +8 -0
  77. package/dist/esm-node/runtime/types.mjs +7 -0
  78. package/dist/esm-node/runtime/utils.mjs +0 -5
  79. package/dist/types/cli/index.d.ts +14 -1
  80. package/dist/types/cli/routeSplitting.d.ts +20 -0
  81. package/dist/types/cli/tanstackTypes.d.ts +21 -1
  82. package/dist/types/runtime/hooks.d.ts +8 -33
  83. package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
  84. package/dist/types/runtime/index.d.ts +8 -3
  85. package/dist/types/runtime/lifecycle.d.ts +7 -22
  86. package/dist/types/runtime/loaderBridge.d.ts +48 -0
  87. package/dist/types/runtime/outlet.d.ts +2 -0
  88. package/dist/types/runtime/plugin.d.ts +2 -15
  89. package/dist/types/runtime/plugin.node.d.ts +2 -15
  90. package/dist/types/runtime/plugin.worker.d.ts +1 -0
  91. package/dist/types/runtime/pluginCore.d.ts +21 -0
  92. package/dist/types/runtime/register.d.ts +9 -0
  93. package/dist/types/runtime/routeTree.d.ts +0 -2
  94. package/dist/types/runtime/router.d.ts +14 -0
  95. package/dist/types/runtime/state.d.ts +16 -0
  96. package/dist/types/runtime/types.d.ts +14 -53
  97. package/package.json +42 -40
  98. package/rstest.config.mts +6 -0
  99. package/src/cli/index.ts +162 -23
  100. package/src/cli/routeSplitting.ts +43 -0
  101. package/src/cli/tanstackTypes.ts +331 -187
  102. package/src/runtime/hooks.ts +10 -27
  103. package/src/runtime/hydrationBoundary.tsx +12 -0
  104. package/src/runtime/index.tsx +17 -7
  105. package/src/runtime/lifecycle.ts +16 -151
  106. package/src/runtime/loaderBridge.ts +257 -0
  107. package/src/runtime/outlet.tsx +48 -0
  108. package/src/runtime/plugin.node.tsx +72 -85
  109. package/src/runtime/plugin.tsx +361 -206
  110. package/src/runtime/plugin.worker.tsx +4 -0
  111. package/src/runtime/pluginCore.ts +48 -0
  112. package/src/runtime/prefetchLink.tsx +1 -1
  113. package/src/runtime/register.ts +58 -0
  114. package/src/runtime/routeTree.ts +163 -354
  115. package/src/runtime/router.ts +15 -0
  116. package/src/runtime/rsc/payloadRouter.ts +45 -2
  117. package/src/runtime/ssr-shim.d.ts +1 -3
  118. package/src/runtime/state.ts +29 -0
  119. package/src/runtime/types.ts +32 -66
  120. package/src/runtime/utils.tsx +3 -6
  121. package/tests/router/cli.test.ts +586 -5
  122. package/tests/router/fastDefaults.test.ts +25 -0
  123. package/tests/router/hooks.test.ts +26 -0
  124. package/tests/router/hydrationBoundary.test.tsx +23 -0
  125. package/tests/router/loaderBridge.test.ts +211 -0
  126. package/tests/router/packageSurface.test.ts +24 -0
  127. package/tests/router/prefetchLink.test.tsx +43 -7
  128. package/tests/router/register.test.ts +46 -0
  129. package/tests/router/routeTree.test.ts +381 -81
  130. package/tests/router/rsc.test.tsx +70 -0
  131. package/tests/router/tanstackTypes.test.ts +573 -1
  132. package/dist/cjs/runtime/DefaultNotFound.js +0 -47
  133. package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
  134. package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
  135. package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
  136. package/src/runtime/DefaultNotFound.tsx +0 -15
@@ -1,23 +1,17 @@
1
1
  // @effect-diagnostics asyncFunction:off newPromise:off strictBooleanExpressions:off unnecessaryArrowBlock:off
2
2
  /// <reference path="./ssr-shim.d.ts" />
3
3
 
4
- import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
5
- import type { RuntimePluginAPI } from '@modern-js/plugin/runtime';
6
4
  import {
7
5
  getGlobalEnableRsc,
8
- getGlobalLayoutApp,
9
- getGlobalRoutes,
10
6
  InternalRuntimeContext,
11
7
  type ServerPayload,
12
8
  type TInternalRuntimeContext,
13
9
  } from '@modern-js/runtime/context';
14
- import { merge } from '@modern-js/runtime-utils/merge';
15
10
  import {
16
11
  createRequestContext,
17
12
  type RequestContext,
18
13
  storage,
19
14
  } from '@modern-js/runtime-utils/node';
20
- import type { RouteObject } from '@modern-js/runtime-utils/router';
21
15
  import { time } from '@modern-js/runtime-utils/time';
22
16
  import { LOADER_REPORTER_NAME } from '@modern-js/utils/universal/constants';
23
17
  import {
@@ -26,24 +20,24 @@ import {
26
20
  createRouter,
27
21
  RouterProvider,
28
22
  } from '@tanstack/react-router';
29
- import { attachRouterServerSsrUtils } from '@tanstack/react-router/ssr/server';
23
+ import { attachRouterServerSsrUtils } from '@tanstack/router-core/ssr/server';
30
24
  import type React from 'react';
31
- import { Suspense, useContext } from 'react';
25
+ import { useContext } from 'react';
32
26
  import { createModernBasepathRewrite } from './basepathRewrite';
33
- import {
34
- modifyRoutes as modifyRoutesHook,
35
- onAfterCreateRouter as onAfterCreateRouterHook,
36
- onAfterHydrateRouter as onAfterHydrateRouterHook,
37
- onBeforeCreateRouter as onBeforeCreateRouterHook,
38
- onBeforeCreateRoutes as onBeforeCreateRoutesHook,
39
- onBeforeHydrateRouter as onBeforeHydrateRouterHook,
40
- type RouterExtendsHooks,
41
- } from './hooks';
27
+ import { routerProviderRegistryHooks } from './hooks';
28
+ import { wrapTanstackSsrHydrationBoundary } from './hydrationBoundary';
42
29
  import {
43
30
  applyRouterServerPrepareResult,
44
31
  createRouterServerSnapshot,
32
+ getRouterRuntimeState,
45
33
  type RouterLifecycleContext,
46
34
  } from './lifecycle';
35
+ import {
36
+ getFinalRouteConfig,
37
+ getMergedRouterConfig,
38
+ type TanstackRouterPluginAPI,
39
+ type TanstackRouterRuntimePlugin,
40
+ } from './pluginCore';
47
41
  import {
48
42
  createRouteTreeFromRouteObjects,
49
43
  getModernRouteIdsFromMatches,
@@ -52,7 +46,11 @@ import {
52
46
  createTanstackRscServerPayload,
53
47
  handleTanstackRscRedirect,
54
48
  } from './rsc/payloadRouter';
55
- import type { InternalRouterServerSnapshot, RouterConfig } from './types';
49
+ import {
50
+ getModernTanstackRouterFastDefaults,
51
+ type InternalRouterServerSnapshot,
52
+ type RouterConfig,
53
+ } from './types';
56
54
  import { createRouteObjectsFromConfig, urlJoin } from './utils';
57
55
 
58
56
  type ModernTanstackRouterContext = {
@@ -60,25 +58,6 @@ type ModernTanstackRouterContext = {
60
58
  requestContext: RequestContext<Record<string, unknown>>;
61
59
  };
62
60
 
63
- type TanstackRouterRuntimeConfig = {
64
- plugins?: TanstackRouterRuntimePlugin[];
65
- router?: Partial<RouterConfig>;
66
- [key: string]: unknown;
67
- };
68
-
69
- type TanstackRouterRuntimeExtends = Required<
70
- RuntimePluginExtends<TanstackRouterRuntimeConfig, TInternalRuntimeContext>
71
- > & {
72
- extendHooks: RouterExtendsHooks;
73
- };
74
-
75
- type TanstackRouterPluginAPI = RuntimePluginAPI<TanstackRouterRuntimeExtends>;
76
-
77
- type TanstackRouterRuntimePlugin = Plugin<
78
- TanstackRouterPluginAPI,
79
- TInternalRuntimeContext
80
- >;
81
-
82
61
  const setTanstackRscServerPayload = (payload: ServerPayload) => {
83
62
  const storageContext = storage.useContext?.() as
84
63
  | { serverPayload?: ServerPayload }
@@ -119,6 +98,17 @@ type PreloadableRouteComponent = {
119
98
  preload?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
120
99
  };
121
100
 
101
+ type ReactLazyRouteComponent = {
102
+ _init?: (payload: unknown) => unknown;
103
+ _payload?: unknown;
104
+ };
105
+
106
+ function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
107
+ return Boolean(
108
+ value && typeof (value as PromiseLike<unknown>).then === 'function',
109
+ );
110
+ }
111
+
122
112
  type TanstackRouterWithServerSsr = AnyRouter & {
123
113
  resolveRedirect?: (redirect: Response) => Response;
124
114
  routesById?: Record<string, RouterRouteWithOptions>;
@@ -149,7 +139,38 @@ function isPreloadableRouteComponent(
149
139
  );
150
140
  }
151
141
 
142
+ function isReactLazyRouteComponent(
143
+ component: unknown,
144
+ ): component is ReactLazyRouteComponent {
145
+ return (
146
+ component !== null &&
147
+ component !== undefined &&
148
+ typeof component === 'object' &&
149
+ typeof (component as ReactLazyRouteComponent)._init === 'function' &&
150
+ '_payload' in component
151
+ );
152
+ }
153
+
154
+ async function preloadReactLazyRouteComponent(
155
+ component: ReactLazyRouteComponent,
156
+ ) {
157
+ try {
158
+ component._init?.(component._payload);
159
+ } catch (thrown) {
160
+ if (!isPromiseLike(thrown)) {
161
+ throw thrown;
162
+ }
163
+ await thrown;
164
+ component._init?.(component._payload);
165
+ }
166
+ }
167
+
152
168
  async function preloadRouteComponent(component: unknown) {
169
+ if (isReactLazyRouteComponent(component)) {
170
+ await preloadReactLazyRouteComponent(component);
171
+ return;
172
+ }
173
+
153
174
  if (!isPreloadableRouteComponent(component)) {
154
175
  return;
155
176
  }
@@ -253,20 +274,6 @@ function createGetSsrHref(request: Request): string {
253
274
  return `${url.pathname}${url.search}${url.hash}`;
254
275
  }
255
276
 
256
- function stripSyntheticNotFoundRoute(routes: RouteObject[]): RouteObject[] {
257
- return routes
258
- .filter(route => !(route.path === '*' && !route.id && !route.loader))
259
- .map(route => {
260
- if (!route.children?.length) {
261
- return route;
262
- }
263
- return {
264
- ...route,
265
- children: stripSyntheticNotFoundRoute(route.children),
266
- };
267
- });
268
- }
269
-
270
277
  function collectRouterErrors(
271
278
  tanstackRouter: AnyRouter,
272
279
  ): Record<string, unknown> | undefined {
@@ -298,35 +305,18 @@ export const tanstackRouterPlugin = (
298
305
  ): TanstackRouterRuntimePlugin => {
299
306
  const plugin: TanstackRouterRuntimePlugin = {
300
307
  name: '@modern-js/plugin-router-tanstack',
301
- registryHooks: {
302
- modifyRoutes: modifyRoutesHook,
303
- onAfterCreateRouter: onAfterCreateRouterHook,
304
- onAfterHydrateRouter: onAfterHydrateRouterHook,
305
- onBeforeCreateRouter: onBeforeCreateRouterHook,
306
- onBeforeCreateRoutes: onBeforeCreateRoutesHook,
307
- onBeforeHydrateRouter: onBeforeHydrateRouterHook,
308
- },
308
+ registryHooks: routerProviderRegistryHooks,
309
309
  setup: (api: TanstackRouterPluginAPI) => {
310
310
  api.onBeforeRender(async (context, interrupt) => {
311
- const pluginConfig = api.getRuntimeConfig() as {
312
- router?: Partial<RouterConfig>;
313
- };
314
- const mergedConfig = merge(
315
- pluginConfig.router || {},
316
- userConfig,
317
- ) as RouterConfig;
311
+ const mergedConfig = getMergedRouterConfig(api, userConfig);
318
312
  const serializationAdapters = getGlobalEnableRsc()
319
313
  ? (await import('./rsc/server')).getTanstackRscSerializationAdapters()
320
314
  : undefined;
321
315
  const enableRsc = getGlobalEnableRsc();
322
316
 
323
- const { basename = '', routesConfig, createRoutes } = mergedConfig;
317
+ const { basename = '', createRoutes } = mergedConfig;
324
318
 
325
- const finalRouteConfig = {
326
- routes: getGlobalRoutes(),
327
- globalApp: getGlobalLayoutApp(),
328
- ...routesConfig,
329
- };
319
+ const finalRouteConfig = getFinalRouteConfig(mergedConfig);
330
320
 
331
321
  if (!finalRouteConfig.routes && !createRoutes) {
332
322
  return;
@@ -341,12 +331,7 @@ export const tanstackRouterPlugin = (
341
331
  routesConfig: finalRouteConfig,
342
332
  ssrMode: context.ssrContext?.mode,
343
333
  }) || [];
344
- const normalizedRouteObjects = createRoutes
345
- ? routeObjects
346
- : stripSyntheticNotFoundRoute(routeObjects);
347
- const modifiedRouteObjects = hooks.modifyRoutes.call(
348
- normalizedRouteObjects,
349
- );
334
+ const modifiedRouteObjects = hooks.modifyRoutes.call(routeObjects);
350
335
 
351
336
  if (!modifiedRouteObjects.length) {
352
337
  return;
@@ -398,6 +383,7 @@ export const tanstackRouterPlugin = (
398
383
  hooks.onBeforeCreateRouter.call(routerLifecycleContext);
399
384
 
400
385
  const tanstackRouter = createRouter({
386
+ ...getModernTanstackRouterFastDefaults(mergedConfig),
401
387
  routeTree,
402
388
  history,
403
389
  basepath: '/',
@@ -458,9 +444,12 @@ export const tanstackRouterPlugin = (
458
444
  context.ssrContext?.response.status(tanstackRouter.state.statusCode);
459
445
 
460
446
  await serverRouter.serverSsr?.dehydrate?.();
461
- await waitForRouterSerialization(serverRouter);
462
447
 
463
448
  if (isRSCNavigation) {
449
+ // RSC navigations consume the server payload directly. Normal HTML SSR
450
+ // emits the buffered bootstrap script below and must not wait here
451
+ // because Modern's non-streaming hook has not rendered the app yet.
452
+ await waitForRouterSerialization(serverRouter);
464
453
  setTanstackRscServerPayload(
465
454
  createTanstackRscServerPayload(serverRouter, {
466
455
  omitClientLoaderData: true,
@@ -509,16 +498,14 @@ export const tanstackRouterPlugin = (
509
498
  const context = useContext(
510
499
  InternalRuntimeContext,
511
500
  ) as unknown as TInternalRuntimeContext;
512
- const router =
513
- context.routerInstance ?? context.routerRuntime?.instance;
501
+ const router = getRouterRuntimeState(context)?.instance;
514
502
  if (!router) {
515
503
  return App ? <App {...props} /> : null;
516
504
  }
517
505
 
518
- const routerWrapper = (
519
- <Suspense fallback={null}>
520
- <RouterProvider router={router as AnyRouter} />
521
- </Suspense>
506
+ const routerWrapper = wrapTanstackSsrHydrationBoundary(
507
+ <RouterProvider router={router as AnyRouter} />,
508
+ true,
522
509
  );
523
510
 
524
511
  return App ? <App>{routerWrapper}</App> : routerWrapper;