rasengan 1.1.3 → 1.2.0-beta.0

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 (33) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/esm/core/config/vite/defaults.js +1 -17
  3. package/lib/esm/core/dynamic/index.js +32 -0
  4. package/lib/esm/core/plugins/index.js +1 -1
  5. package/lib/esm/entries/client/render.js +45 -16
  6. package/lib/esm/entries/server/entry.server.js +1 -0
  7. package/lib/esm/entries/server/index.js +3 -3
  8. package/lib/esm/routing/components/fallback.js +8 -0
  9. package/lib/esm/routing/components/index.js +7 -4
  10. package/lib/esm/routing/components/template.js +8 -7
  11. package/lib/esm/routing/providers/metadata.js +23 -13
  12. package/lib/esm/routing/utils/define-router.js +10 -6
  13. package/lib/esm/routing/utils/flat-routes.js +46 -75
  14. package/lib/esm/routing/utils/generate-routes.js +279 -178
  15. package/lib/esm/server/build/manifest.js +19 -7
  16. package/lib/esm/server/dev/handlers.js +1 -1
  17. package/lib/esm/server/dev/server.js +19 -1
  18. package/lib/esm/server/node/index.js +8 -2
  19. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  20. package/lib/tsconfig.types.tsbuildinfo +1 -1
  21. package/lib/types/core/dynamic/index.d.ts +15 -0
  22. package/lib/types/core/types.d.ts +1 -1
  23. package/lib/types/entries/client/render.d.ts +3 -2
  24. package/lib/types/routing/components/fallback.d.ts +5 -0
  25. package/lib/types/routing/components/template.d.ts +1 -1
  26. package/lib/types/routing/interfaces.d.ts +5 -4
  27. package/lib/types/routing/providers/metadata.d.ts +1 -3
  28. package/lib/types/routing/types.d.ts +21 -3
  29. package/lib/types/routing/utils/define-routes-group.d.ts +1 -1
  30. package/lib/types/routing/utils/flat-routes.d.ts +21 -3
  31. package/lib/types/routing/utils/generate-routes.d.ts +6 -6
  32. package/lib/types/server/build/manifest.d.ts +4 -4
  33. package/package.json +1 -1
@@ -1,23 +1,12 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { RouterProvider, createBrowserRouter, useLoaderData, useParams, } from 'react-router';
2
+ import { Outlet, matchRoutes, useLoaderData, useParams } from 'react-router';
3
3
  import { ErrorBoundary, NotFoundPageComponent, RasenganPageComponent, } from '../components/index.js';
4
- import { Suspense } from 'react';
5
4
  import MetadataProvider from '../providers/metadata.js';
5
+ import { convertMDXPageToPageComponent, isMDXPage, } from './index.js';
6
6
  const defaultMetadata = {
7
7
  title: 'Not Found',
8
8
  description: 'Page not found',
9
9
  };
10
- /**
11
- * This function receives a router component and get a formated router first
12
- * and then return a router.
13
- */
14
- export const getRouter = (routerInstance) => {
15
- const routes = generateRoutes(routerInstance);
16
- let router = createBrowserRouter(routes, {
17
- hydrationData: window.__staticRouterHydrationData,
18
- });
19
- return () => _jsx(RouterProvider, { router: router });
20
- };
21
10
  /**
22
11
  * This function merge the metadata, giving priority to the ones comming from loader
23
12
  */
@@ -112,7 +101,7 @@ const mergeMetaData = (responseMeta, meta, isLayout = false) => {
112
101
  /**
113
102
  * This function create a loader function
114
103
  */
115
- const createLoaderFunction = ({ loader, metadata, isLayout = false, }) => {
104
+ const createLoaderFunction = ({ loader, metadata, isLayout = false, source, }) => {
116
105
  return async ({ params, request }) => {
117
106
  try {
118
107
  // Check if the loader is defined
@@ -120,6 +109,7 @@ const createLoaderFunction = ({ loader, metadata, isLayout = false, }) => {
120
109
  return {
121
110
  props: {},
122
111
  meta: metadata,
112
+ source,
123
113
  };
124
114
  }
125
115
  // Get the response from the loader
@@ -138,6 +128,7 @@ const createLoaderFunction = ({ loader, metadata, isLayout = false, }) => {
138
128
  return {
139
129
  props: response.props,
140
130
  meta: mergeMetaData(response.meta ?? {}, metadata, isLayout),
131
+ source,
141
132
  };
142
133
  }
143
134
  catch (error) {
@@ -157,75 +148,163 @@ const createLoaderFunction = ({ loader, metadata, isLayout = false, }) => {
157
148
  metaTags: [],
158
149
  links: [],
159
150
  },
151
+ source,
160
152
  };
161
153
  }
162
154
  };
163
155
  };
156
+ /**
157
+ * This function preload the matching lazy routes
158
+ * @param url
159
+ * @param routes
160
+ */
161
+ export const preloadMatches = async (url, routes) => {
162
+ const matches = matchRoutes(routes, url);
163
+ if (!matches)
164
+ return;
165
+ await Promise.all(matches.map(async (match) => {
166
+ if (match.route.lazy) {
167
+ const resolved = await match.route.lazy();
168
+ Object.assign(match.route, resolved);
169
+ // Strip lazy so Router never tries to suspend again
170
+ delete match.route.lazy;
171
+ }
172
+ }));
173
+ };
164
174
  /**
165
175
  * This function receives a router component and return a formated router for static routing
166
176
  * @param router Represents the router component
167
177
  * @returns
168
178
  */
169
- export const generateRoutes = (router, isRoot = true, parentLayout = undefined) => {
179
+ export const generateRoutes = (router, isRoot = true, parentLayoutPath = undefined) => {
170
180
  // Initialization of the list of routes
171
181
  const routes = [];
172
- // Get information about the layout and the path
173
- const Layout = router.layout;
174
- const route = {
175
- path: !isRoot
176
- ? router.useParentLayout
177
- ? Layout.path.replace(parentLayout.path + '/', '')
178
- : Layout.path
179
- : Layout.path,
180
- errorElement: _jsx(ErrorBoundary, {}),
181
- Component() {
182
- // Default data
183
- const defaultData = {
184
- props: {},
185
- };
186
- // Get SSR data
187
- let { props } = useLoaderData() || defaultData;
188
- // get params
189
- const params = useParams();
190
- const layoutProps = {
191
- ...props,
192
- params,
193
- };
194
- // Check if the layout is the root layout and wrap it in a MetadataProvider
195
- if (isRoot || !router.useParentLayout) {
196
- // Generate metadata mapping
197
- const metadataMapping = generateMetadataMapping(router);
198
- return (_jsx(MetadataProvider, { metadataMapping: metadataMapping, children: _jsx(Layout, { ...layoutProps }) }));
199
- }
200
- return _jsx(Layout, { ...layoutProps });
201
- },
202
- async loader({ params, request }) {
203
- // Extract metadata from the layout
204
- const metadata = {
205
- openGraph: {
206
- url: '',
207
- image: '',
208
- },
209
- twitter: {
210
- card: 'summary_large_image',
211
- image: '',
212
- title: '',
213
- },
214
- ...Layout.metadata,
215
- };
216
- return createLoaderFunction({
217
- loader: Layout.loader,
218
- metadata,
219
- isLayout: true,
220
- })({
221
- params,
222
- request,
223
- });
224
- },
225
- children: [],
226
- nested: router.useParentLayout,
227
- hydrateFallbackElement: _jsx(_Fragment, {}), // TODO: Add hydration fallback
228
- };
182
+ let route;
183
+ let layoutPath;
184
+ // Check if the layout is coming from the file-based routing system
185
+ if ('source' in router.layout) {
186
+ const layoutNode = router.layout;
187
+ layoutPath = layoutNode.path;
188
+ route = {
189
+ path: !isRoot
190
+ ? router.useParentLayout
191
+ ? layoutNode.path.replace(parentLayoutPath + '/', '')
192
+ : layoutNode.path
193
+ : layoutNode.path,
194
+ errorElement: _jsx(ErrorBoundary, {}),
195
+ lazy: async () => {
196
+ const Layout = (await layoutNode.module()).default;
197
+ if (!Layout) {
198
+ console.warn(`Layout component is not exported by default from: ${layoutNode.source}}`);
199
+ return {
200
+ Component() {
201
+ return _jsx(Outlet, {});
202
+ },
203
+ };
204
+ }
205
+ return {
206
+ Component() {
207
+ // Default data
208
+ const defaultData = {
209
+ props: {},
210
+ };
211
+ // Get SSR data
212
+ let { props } = useLoaderData() || defaultData;
213
+ // get params
214
+ const params = useParams();
215
+ const layoutProps = {
216
+ ...props,
217
+ params,
218
+ };
219
+ // Check if the layout is the root layout and wrap it in a MetadataProvider
220
+ if (isRoot || !router.useParentLayout) {
221
+ // Generate metadata mapping
222
+ // const metadataMapping = generateMetadataMapping(router);
223
+ return (_jsx(MetadataProvider, { children: _jsx(Layout, { ...layoutProps }) }));
224
+ }
225
+ return _jsx(Layout, { ...layoutProps });
226
+ },
227
+ async loader({ params, request }) {
228
+ // Extract metadata from the layout
229
+ const metadata = {
230
+ ...Layout.metadata,
231
+ };
232
+ return createLoaderFunction({
233
+ loader: Layout.loader,
234
+ metadata,
235
+ isLayout: true,
236
+ source: layoutNode.source,
237
+ })({
238
+ params,
239
+ request,
240
+ });
241
+ },
242
+ };
243
+ },
244
+ children: [],
245
+ nested: router.useParentLayout,
246
+ hydrateFallbackElement: _jsx(_Fragment, {}),
247
+ // shouldRevalidate: ({ currentUrl, nextUrl, defaultShouldRevalidate }) => {
248
+ // // Only revalidate if navigating to a different route
249
+ // return currentUrl.pathname !== nextUrl.pathname;
250
+ // },
251
+ };
252
+ }
253
+ else {
254
+ const Layout = router.layout;
255
+ layoutPath = Layout.path;
256
+ route = {
257
+ path: !isRoot
258
+ ? router.useParentLayout
259
+ ? layoutPath.replace(parentLayoutPath + '/', '')
260
+ : layoutPath
261
+ : layoutPath,
262
+ errorElement: _jsx(ErrorBoundary, {}),
263
+ Component() {
264
+ // Default data
265
+ const defaultData = {
266
+ props: {},
267
+ };
268
+ // Get SSR data
269
+ let { props } = useLoaderData() || defaultData;
270
+ // get params
271
+ const params = useParams();
272
+ const layoutProps = {
273
+ ...props,
274
+ params,
275
+ };
276
+ // Check if the layout is the root layout and wrap it in a MetadataProvider
277
+ if (isRoot || !router.useParentLayout) {
278
+ // Generate metadata mapping
279
+ // const metadataMapping = generateMetadataMapping(router);
280
+ return (_jsx(MetadataProvider, { children: _jsx(Layout, { ...layoutProps }) }));
281
+ }
282
+ return _jsx(Layout, { ...layoutProps });
283
+ },
284
+ async loader({ params, request }) {
285
+ // Extract metadata from the layout
286
+ const metadata = {
287
+ ...Layout.metadata,
288
+ };
289
+ return createLoaderFunction({
290
+ loader: Layout.loader,
291
+ metadata,
292
+ isLayout: true,
293
+ })({
294
+ params,
295
+ request,
296
+ });
297
+ },
298
+ children: [],
299
+ nested: router.useParentLayout,
300
+ hydrateFallbackElement: _jsx(_Fragment, {}),
301
+ // hydrateFallbackElement: <>Loading...</>, // TODO: enable override
302
+ // shouldRevalidate: ({ currentUrl, nextUrl, defaultShouldRevalidate }) => {
303
+ // // Only revalidate if navigating to a different route
304
+ // return currentUrl.pathname !== nextUrl.pathname;
305
+ // },
306
+ };
307
+ }
229
308
  // Defining the page not found route
230
309
  if (isRoot || router.notFoundComponent) {
231
310
  route.children.push({
@@ -240,53 +319,134 @@ export const generateRoutes = (router, isRoot = true, parentLayout = undefined)
240
319
  });
241
320
  }
242
321
  // Get informations about pages
243
- const pages = router.pages.map((Page) => {
244
- // /home => home
245
- // / => /
246
- const pagePathFormated = Page.path.startsWith('/') && Page.path !== '/'
247
- ? Page.path.slice(1)
248
- : Page.path;
249
- // Get the path of the page
250
- const path = Page.path === '/'
251
- ? Layout.path
252
- : Layout.path.length > 1
253
- ? pagePathFormated
322
+ const pages = router.pages.map((p) => {
323
+ // Check if the page is coming from file-based routing system
324
+ if ('source' in p) {
325
+ const pageNode = p;
326
+ // /home => home
327
+ // / => /
328
+ const pagePathFormated = pageNode.path.startsWith('/') && pageNode.path !== '/'
329
+ ? pageNode.path.slice(1)
330
+ : pageNode.path;
331
+ // Get the path of the page
332
+ const path = pageNode.path === '/'
333
+ ? layoutPath
334
+ : layoutPath.length > 1
335
+ ? pagePathFormated
336
+ : pageNode.path;
337
+ return {
338
+ path: path === layoutPath ? undefined : path,
339
+ index: path === layoutPath,
340
+ async lazy() {
341
+ let Page = (await pageNode.module()).default;
342
+ if (!Page) {
343
+ console.warn(`Page component is not exported by default from: ${pageNode.source}}`);
344
+ return {
345
+ Component() {
346
+ return null;
347
+ },
348
+ };
349
+ }
350
+ // Detech if the page is a MDXPageComponent or not
351
+ if (isMDXPage(Page)) {
352
+ // Convert PageComponent to MDXPageComponent (to make ts happy)
353
+ const mdxPage = Page;
354
+ // mdxPage.metadata.path = node.path;
355
+ // mdxPage.metadata.metadata = Page.metadata;
356
+ Page = await convertMDXPageToPageComponent(mdxPage);
357
+ }
358
+ return {
359
+ Component() {
360
+ // Default data
361
+ const defaultData = {
362
+ props: {
363
+ params: {},
364
+ },
365
+ };
366
+ const loaderData = useLoaderData() || defaultData;
367
+ return (
368
+ // <Suspense fallback={<>Loading</>}>
369
+ _jsx(RasenganPageComponent, { page: Page, data: loaderData })
370
+ // </Suspense>
371
+ );
372
+ },
373
+ async loader({ params, request }) {
374
+ // Extracting metadata from the page
375
+ const metadata = {
376
+ ...Page.metadata,
377
+ };
378
+ return createLoaderFunction({
379
+ loader: Page.loader,
380
+ metadata,
381
+ source: pageNode.source,
382
+ })({
383
+ params,
384
+ request,
385
+ });
386
+ },
387
+ };
388
+ },
389
+ errorElement: _jsx(ErrorBoundary, {}),
390
+ hydrateFallbackElement: _jsx(_Fragment, {}),
391
+ // hydrateFallbackElement: <>Loading...</>,
392
+ shouldRevalidate: ({ currentUrl, nextUrl, defaultShouldRevalidate, }) => {
393
+ // Only revalidate if navigating to a different route
394
+ return currentUrl.pathname !== nextUrl.pathname;
395
+ },
396
+ };
397
+ }
398
+ else {
399
+ const Page = p;
400
+ // /home => home
401
+ // / => /
402
+ const pagePathFormated = Page.path.startsWith('/') && Page.path !== '/'
403
+ ? Page.path.slice(1)
254
404
  : Page.path;
255
- return {
256
- path: path === Layout.path ? undefined : path,
257
- index: path === Layout.path,
258
- async loader({ params, request }) {
259
- // Extracting metadata from the page
260
- const metadata = {
261
- openGraph: {
262
- url: '',
263
- image: '',
264
- },
265
- twitter: {
266
- card: 'summary_large_image',
267
- image: '',
268
- title: '',
269
- },
270
- ...Page.metadata,
271
- };
272
- return createLoaderFunction({ loader: Page.loader, metadata })({
273
- params,
274
- request,
275
- });
276
- },
277
- Component() {
278
- // Default data
279
- const defaultData = {
280
- props: {
281
- params: {},
282
- },
283
- };
284
- const loaderData = useLoaderData() || defaultData;
285
- return (_jsx(Suspense, { fallback: _jsx(_Fragment, { children: "Loading" }), children: _jsx(RasenganPageComponent, { page: Page, data: loaderData }) }));
286
- },
287
- errorElement: _jsx(ErrorBoundary, {}),
288
- hydrateFallbackElement: _jsx(_Fragment, {}), // TODO: Add hydration fallback
289
- };
405
+ // Get the path of the page
406
+ const path = Page.path === '/'
407
+ ? layoutPath
408
+ : layoutPath.length > 1
409
+ ? pagePathFormated
410
+ : Page.path;
411
+ return {
412
+ path: path === layoutPath ? undefined : path,
413
+ index: path === layoutPath,
414
+ async loader({ params, request }) {
415
+ // Extracting metadata from the page
416
+ const metadata = {
417
+ ...Page.metadata,
418
+ };
419
+ return createLoaderFunction({
420
+ loader: Page.loader,
421
+ metadata,
422
+ })({
423
+ params,
424
+ request,
425
+ });
426
+ },
427
+ Component() {
428
+ // Default data
429
+ const defaultData = {
430
+ props: {
431
+ params: {},
432
+ },
433
+ };
434
+ const loaderData = useLoaderData() || defaultData;
435
+ return (
436
+ // <Suspense fallback={<>Loading</>}>
437
+ _jsx(RasenganPageComponent, { page: Page, data: loaderData })
438
+ // </Suspense>
439
+ );
440
+ },
441
+ errorElement: _jsx(ErrorBoundary, {}),
442
+ hydrateFallbackElement: _jsx(_Fragment, {}),
443
+ // hydrateFallbackElement: <>Loading...</>,
444
+ shouldRevalidate: ({ currentUrl, nextUrl, defaultShouldRevalidate, }) => {
445
+ // Only revalidate if navigating to a different route
446
+ return currentUrl.pathname !== nextUrl.pathname;
447
+ },
448
+ };
449
+ }
290
450
  });
291
451
  // Add pages into children of the current route
292
452
  pages.forEach((page) => {
@@ -294,7 +454,7 @@ export const generateRoutes = (router, isRoot = true, parentLayout = undefined)
294
454
  });
295
455
  // Loop through imported routers in order to apply the same logic like above.
296
456
  for (const importedRouter of router.routers) {
297
- const importedRoutes = generateRoutes(importedRouter, false, Layout);
457
+ const importedRoutes = generateRoutes(importedRouter, false, layoutPath);
298
458
  for (const importedRoute of importedRoutes) {
299
459
  if (importedRoute.nested) {
300
460
  route.children.push(importedRoute);
@@ -309,62 +469,3 @@ export const generateRoutes = (router, isRoot = true, parentLayout = undefined)
309
469
  // Return the formated router
310
470
  return routes;
311
471
  };
312
- /**
313
- * This function receives a router component and return a mapping from path to metadata
314
- * @param router Represents the router component
315
- * @returns
316
- */
317
- export const generateMetadataMapping = (router, isRoot = true, parentLayout = undefined) => {
318
- const metadataMapping = {};
319
- // Get information about the layout and the path
320
- const Layout = router.layout;
321
- // Set default path layout if not provided
322
- if (!Layout.path) {
323
- throw new Error(`[rasengan] Page path is required for ${Layout.name} layout component`);
324
- }
325
- const layoutPath = !isRoot
326
- ? router.useParentLayout
327
- ? parentLayout.path +
328
- (Layout.path === '/'
329
- ? ''
330
- : Layout.path.startsWith('/') && parentLayout.path === '/'
331
- ? Layout.path.slice(1)
332
- : Layout.path)
333
- : Layout.path
334
- : Layout.path;
335
- // Get informations about pages
336
- router.pages.forEach((Page) => {
337
- // Set default page path if not provided
338
- if (!Page.path) {
339
- throw new Error(`[rasengan] Page path is required for ${Page.name} page component`);
340
- }
341
- const pagePathFormated = Page.path.startsWith('/') && Page.path !== '/' && layoutPath.endsWith('/')
342
- ? Page.path.slice(1)
343
- : Page.path;
344
- // Get the path of the page
345
- const path = Page.path === '/' ? layoutPath : layoutPath + pagePathFormated;
346
- // Get metadata
347
- metadataMapping[path] = {
348
- openGraph: {
349
- url: '',
350
- image: '',
351
- },
352
- twitter: {
353
- card: 'summary_large_image',
354
- image: '',
355
- title: '',
356
- },
357
- ...Page.metadata,
358
- };
359
- });
360
- // Loop through imported routers in order to apply the same logic like above.
361
- for (const importedRouter of router.routers) {
362
- const importedMetadataMapping = generateMetadataMapping(importedRouter, false, Layout);
363
- Object.assign(metadataMapping, importedMetadataMapping);
364
- // Add the metadata of the imported router's pages to the metadata mapping
365
- for (const [path, metadata] of Object.entries(importedMetadataMapping)) {
366
- metadataMapping[path] = metadata;
367
- }
368
- }
369
- return metadataMapping;
370
- };
@@ -23,10 +23,10 @@ export class ManifestManager {
23
23
  }
24
24
  /**
25
25
  * Resolve all assets for a given page.
26
- * @param pageName - The name of the page to resolve.
26
+ * @param source - The file path of the page to resolve.
27
27
  * @returns Resolved assets with scripts and styles.
28
28
  */
29
- resolveAssets(pageName) {
29
+ resolveAssets(source) {
30
30
  const visited = new Set();
31
31
  const assets = {
32
32
  scripts: [],
@@ -67,10 +67,22 @@ export class ManifestManager {
67
67
  collectAssets(this._manifest[importName]);
68
68
  }
69
69
  }
70
- // Collect dynamic imports
70
+ // // Collect dynamic imports
71
+ // if (entry.dynamicImports) {
72
+ // for (const dynamicImport of entry.dynamicImports) {
73
+ // collectAssets(this._manifest[dynamicImport]);
74
+ // }
75
+ // }
76
+ // Collect dynamic imports (filter by pageName)
71
77
  if (entry.dynamicImports) {
72
78
  for (const dynamicImport of entry.dynamicImports) {
73
- collectAssets(this._manifest[dynamicImport]);
79
+ const dynEntry = this._manifest[dynamicImport];
80
+ if (!dynEntry)
81
+ continue;
82
+ // Check if the dynamic import corresponds to the requested page
83
+ if (dynEntry.src?.includes(source)) {
84
+ collectAssets(dynEntry);
85
+ }
74
86
  }
75
87
  }
76
88
  };
@@ -79,11 +91,11 @@ export class ManifestManager {
79
91
  }
80
92
  /**
81
93
  * Generate meta tags for a given page.
82
- * @param pageName - The name of the page to generate meta tags for.
94
+ * @param source - The file path of the page to generate meta tags for.
83
95
  * @returns HTML string containing script and style tags.
84
96
  */
85
- generateMetaTags(pageName) {
86
- const { scripts, styles } = this.resolveAssets(pageName);
97
+ generateMetaTags(source) {
98
+ const { scripts, styles } = this.resolveAssets(source);
87
99
  const scriptTags = scripts.map((file) => (_jsx("script", { type: 'module', src: `/${file}` })));
88
100
  const styleTags = styles.map((file) => (_jsx("link", { rel: 'stylesheet', href: `/${file}` })));
89
101
  return [...scriptTags, ...styleTags];
@@ -77,7 +77,7 @@ export async function handleDocumentRequest(req, res, runner, options) {
77
77
  res.writeHead(context.statusCode, {
78
78
  ...Object.fromEntries(headers),
79
79
  });
80
- const Router = _jsx(StaticRouterProvider, { router: router, context: context });
80
+ const Router = (_jsx(StaticRouterProvider, { router: router, context: context, hydrate: true }));
81
81
  // If stream mode enabled, render the page as a plain text
82
82
  return await render(Router, res, {
83
83
  metadata,
@@ -11,7 +11,7 @@ import { getDirname, loadModuleSSR, } from '../../core/config/utils/load-modules
11
11
  import { ServerMode } from '../runtime/mode.js';
12
12
  import { handleDataRequest, handleDocumentRequest, handleSpaModeRequest, } from './handlers.js';
13
13
  import { createStaticHandler } from 'react-router';
14
- import { generateRoutes } from '../../routing/utils/generate-routes.js';
14
+ import { generateRoutes, preloadMatches, } from '../../routing/utils/generate-routes.js';
15
15
  /**
16
16
  * Handle the request for the development environment
17
17
  * @param req
@@ -28,8 +28,26 @@ async function devRequestHandler(req, res, viteDevServer, options) {
28
28
  const AppRouter = await (await runner.import(join(`${options.rootPath}/src/app/app.router`))).default;
29
29
  // Get static routes
30
30
  const staticRoutes = generateRoutes(AppRouter);
31
+ await preloadMatches(req.originalUrl, staticRoutes);
31
32
  // Create static handler
32
33
  let handler = createStaticHandler(staticRoutes);
34
+ // Get matches for the current URL
35
+ // const matches = matchRoutes(staticRoutes, req.originalUrl);
36
+ // Resolve all lazy() modules for matched routes
37
+ // const resolvedMatches = await Promise.all(
38
+ // matches?.map(async (match) => {
39
+ // if (match.route.lazy) {
40
+ // const lazyFn = match.route.lazy as unknown as () => Promise<any>;
41
+ // const resolved = await lazyFn();
42
+ // Object.assign(match.route, resolved);
43
+ // }
44
+ // return match;
45
+ // }) ?? []
46
+ // );
47
+ // console.log({
48
+ // resolvedMatches: JSON.stringify(resolvedMatches),
49
+ // url: req.originalUrl,
50
+ // });
33
51
  if (isDataRequest(req)) {
34
52
  // Handle data request
35
53
  return await handleDataRequest(req, handler);
@@ -2,7 +2,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { ManifestManager } from '../build/manifest.js';
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
- import { generateRoutes } from '../../routing/utils/index.js';
5
+ import { generateRoutes, preloadMatches,
6
+ // generateSSRRoutes,
7
+ } from '../../routing/utils/index.js';
6
8
  import { createStaticHandler, createStaticRouter, StaticRouterProvider, } from 'react-router';
7
9
  import createRasenganRequest from './utils.js';
8
10
  import { extractHeadersFromRRContext, extractMetaFromRRContext, isRedirectResponse, isStaticRedirectFromConfig, } from '../dev/utils.js';
@@ -31,6 +33,8 @@ export function createRequestHandler(options) {
31
33
  const { render, } = entry;
32
34
  // Get static routes
33
35
  const staticRoutes = generateRoutes(AppRouter);
36
+ // Preload matches
37
+ await preloadMatches(req.originalUrl, staticRoutes);
34
38
  // Create static handler
35
39
  let handler = createStaticHandler(staticRoutes);
36
40
  // Create rasengan request for static routing
@@ -46,8 +50,10 @@ export function createRequestHandler(options) {
46
50
  if (!(context instanceof Response)) {
47
51
  // Extract meta from context
48
52
  const metadata = extractMetaFromRRContext(context);
53
+ // Get the source file from the context
54
+ const source = context.loaderData.source;
49
55
  // Get assets tags
50
- const assets = manifest.generateMetaTags(''); // TODO: Add the correct path
56
+ const assets = manifest.generateMetaTags(source);
51
57
  // Create static router
52
58
  let router = createStaticRouter(handler.dataRoutes, context);
53
59
  const headers = extractHeadersFromRRContext(context);