rasengan 1.0.0-beta.60 → 1.0.0-beta.62

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 1.0.0-beta.62 (2025-04-26)
4
+
5
+ ## 1.0.0-beta.61 (2025-03-22)
6
+
3
7
  ## 1.0.0-beta.60 (2025-03-16)
4
8
 
5
9
  ## 1.0.0-beta.59 (2025-03-16)
@@ -48,7 +48,7 @@ export const createDefaultViteConfig = (rootPath, __dirname, mode, config) => {
48
48
  client: {
49
49
  build: {
50
50
  manifest: true,
51
- outDir: 'dist/client',
51
+ outDir: config.ssr ? 'dist/client' : 'dist',
52
52
  rollupOptions: {
53
53
  input: './src/index',
54
54
  },
@@ -63,7 +63,6 @@ export const createDefaultViteConfig = (rootPath, __dirname, mode, config) => {
63
63
  'app.router': './src/app/app.router',
64
64
  main: './src/main',
65
65
  template: './src/template',
66
- config: './rasengan.config.js',
67
66
  },
68
67
  },
69
68
  ssrEmitAssets: false,
@@ -95,7 +95,6 @@ export const Adapters = {
95
95
  export function rasengan({ adapter = { name: Adapters.DEFAULT, prepare: async () => { } }, }) {
96
96
  let config;
97
97
  let viteConfig;
98
- const templateFileRegex = /template\.(tsx|jsx)$/;
99
98
  const buildOptions = resolveBuildOptions({});
100
99
  return {
101
100
  name: 'vite-plugin-rasengan',
@@ -126,8 +125,11 @@ export function rasengan({ adapter = { name: Adapters.DEFAULT, prepare: async ()
126
125
  return fs.existsSync(modulePath);
127
126
  });
128
127
  const module = await this.load({ id: modulePath });
129
- // Generate the template.js file into the dist/assets
130
- fs.writeFileSync(path.posix.join(process.cwd(), buildOptions.buildDirectory, buildOptions.clientPathDirectory, buildOptions.assetPathDirectory, 'template.js'), module.code, 'utf-8');
128
+ // SPA mode only
129
+ if (!config.ssr) {
130
+ // Generate the template.js file into the dist/assets
131
+ fs.writeFileSync(path.posix.join(process.cwd(), buildOptions.buildDirectory, buildOptions.assetPathDirectory, 'template.js'), module.code, 'utf-8');
132
+ }
131
133
  },
132
134
  async closeBundle() {
133
135
  // We check here if the environment is client has been built because it's the
@@ -136,7 +138,7 @@ export function rasengan({ adapter = { name: Adapters.DEFAULT, prepare: async ()
136
138
  // Check if SPA mode is enabled
137
139
  if (!config.ssr) {
138
140
  // Load the template.js file
139
- const templatePath = path.posix.join(process.cwd(), buildOptions.buildDirectory, buildOptions.clientPathDirectory, buildOptions.assetPathDirectory, 'template.js');
141
+ const templatePath = path.posix.join(process.cwd(), buildOptions.buildDirectory, buildOptions.assetPathDirectory, 'template.js');
140
142
  const Template = (await import(templatePath)).default;
141
143
  // Render the index.html file
142
144
  await renderIndexHTML(Template, {
@@ -144,24 +146,29 @@ export function rasengan({ adapter = { name: Adapters.DEFAULT, prepare: async ()
144
146
  config,
145
147
  });
146
148
  }
147
- // Generate a config.json file into the dist/client/assets
148
- fs.writeFileSync(path.posix.join(process.cwd(), buildOptions.buildDirectory, buildOptions.clientPathDirectory, buildOptions.assetPathDirectory, 'config.json'), JSON.stringify({
149
+ // Generate a config.json file into the dist/client/assets or dist/assets
150
+ const minimizedConfig = {
149
151
  buildOptions,
150
152
  ssr: config.ssr,
151
- }), 'utf-8');
152
- // Preparing app for deployment
153
- switch (adapter.name) {
154
- case Adapters.VERCEL: {
155
- console.log('Preparing app for deployment to Vercel');
156
- await adapter.prepare();
157
- break;
158
- }
159
- default:
160
- break;
161
- }
153
+ redirects: await config.redirects(),
154
+ };
155
+ fs.writeFileSync(path.posix.join(process.cwd(), buildOptions.buildDirectory, config.ssr ? buildOptions.clientPathDirectory : '', buildOptions.assetPathDirectory, 'config.json'), JSON.stringify(minimizedConfig), 'utf-8');
156
+ // Prepare the app for deployment
157
+ await prepareToDeploy(adapter);
162
158
  }
163
159
  },
164
160
  apply: 'build',
165
161
  };
166
162
  }
163
+ const prepareToDeploy = async (adapter) => {
164
+ // Preparing app for deployment
165
+ switch (adapter.name) {
166
+ case Adapters.VERCEL: {
167
+ await adapter.prepare();
168
+ break;
169
+ }
170
+ default:
171
+ break;
172
+ }
173
+ };
167
174
  export const plugins = [loadRasenganGlobal()];
@@ -1,5 +1,5 @@
1
1
  import { CustomLink } from './components/index.js';
2
2
  export { defineRouter, defineRoutesGroup } from './utils/index.js';
3
3
  export { RouterComponent } from './interfaces.js';
4
- export { Outlet, useLocation, useNavigate, useNavigation, useParams, useSearchParams, useFetcher, useMatch, useRoutes, useResolvedPath, matchRoutes, generatePath, matchPath, createRoutesFromChildren, Navigate, } from 'react-router';
4
+ export { Outlet, ScrollRestoration, useLocation, useNavigate, useNavigation, useParams, useSearchParams, useFetcher, useMatch, useRoutes, useResolvedPath, matchRoutes, generatePath, matchPath, createRoutesFromChildren, Navigate, } from 'react-router';
5
5
  export { CustomLink as Link };
@@ -0,0 +1,42 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useLocation } from 'react-router';
3
+ import { useEffect } from 'react';
4
+ import { generateMetadata } from '../utils/generate-metadata.js';
5
+ import ReactDOMServer from 'react-dom/server';
6
+ export default function MetadataProvider({ children, metadataMapping, }) {
7
+ const { pathname } = useLocation();
8
+ useEffect(() => {
9
+ const metadata = metadataMapping[pathname];
10
+ if (!metadata)
11
+ return;
12
+ handleInjectMetadata(metadata);
13
+ }, [pathname]);
14
+ const handleInjectMetadata = (metadata) => {
15
+ if (!metadata)
16
+ return;
17
+ // Check if we are on the browser
18
+ if (typeof window !== 'undefined') {
19
+ const metaTags = generateMetadata([metadata]);
20
+ // Find all meta tags with data-rg attribute and remove them
21
+ const metaTagsToRemove = document.querySelectorAll('meta[data-rg="true"]');
22
+ metaTagsToRemove.forEach((metaTag) => {
23
+ metaTag.remove();
24
+ });
25
+ // Inject the meta tags
26
+ metaTags.forEach((metaTag) => {
27
+ // Convert React element to string
28
+ const metaTagString = ReactDOMServer.renderToStaticMarkup(metaTag);
29
+ document.head.insertAdjacentHTML('beforeend', metaTagString);
30
+ });
31
+ // Change the title of the page
32
+ document.title = metadata.title;
33
+ // Change the description of the page
34
+ const metaDescription = document.createElement('meta');
35
+ metaDescription.setAttribute('name', 'description');
36
+ metaDescription.setAttribute('content', metadata.description);
37
+ metaDescription.setAttribute('data-rg', 'true');
38
+ document.head.appendChild(metaDescription);
39
+ }
40
+ };
41
+ return _jsx(_Fragment, { children: children });
42
+ }
@@ -11,43 +11,43 @@ export const generateMetadata = (metadatas) => {
11
11
  if (openGraph) {
12
12
  const { title, description, url, image, width, height, type } = openGraph;
13
13
  if (title) {
14
- metadataElements.push(_jsx("meta", { property: "og:title", content: title }, "og:title"));
14
+ metadataElements.push(_jsx("meta", { property: "og:title", content: title, "data-rg": "true" }, "og:title"));
15
15
  }
16
16
  if (description) {
17
- metadataElements.push(_jsx("meta", { property: "og:description", content: description }, "og:description"));
17
+ metadataElements.push(_jsx("meta", { property: "og:description", content: description, "data-rg": "true" }, "og:description"));
18
18
  }
19
19
  if (url) {
20
- metadataElements.push(_jsx("meta", { property: "og:url", content: url }, "og:url"));
20
+ metadataElements.push(_jsx("meta", { property: "og:url", content: url, "data-rg": "true" }, "og:url"));
21
21
  }
22
22
  if (image) {
23
- metadataElements.push(_jsx("meta", { property: "og:image", content: image }, "og:image"));
23
+ metadataElements.push(_jsx("meta", { property: "og:image", content: image, "data-rg": "true" }, "og:image"));
24
24
  }
25
25
  if (width) {
26
- metadataElements.push(_jsx("meta", { property: "og:image:width", content: width }, "og:image:width"));
26
+ metadataElements.push(_jsx("meta", { property: "og:image:width", content: width, "data-rg": "true" }, "og:image:width"));
27
27
  }
28
28
  if (height) {
29
- metadataElements.push(_jsx("meta", { property: "og:image:height", content: height }, "og:image:height"));
29
+ metadataElements.push(_jsx("meta", { property: "og:image:height", content: height, "data-rg": "true" }, "og:image:height"));
30
30
  }
31
- metadataElements.push(_jsx("meta", { property: "og:type", content: type || 'website' }, "og:type"));
31
+ metadataElements.push(_jsx("meta", { property: "og:type", content: type || 'website', "data-rg": "true" }, "og:type"));
32
32
  }
33
33
  // Handling twitter
34
34
  if (twitter) {
35
35
  const { card, site, creator, image, title, description } = twitter;
36
- metadataElements.push(_jsx("meta", { name: "twitter:card", content: card || 'summary_large_image' }, "twitter:card"));
36
+ metadataElements.push(_jsx("meta", { name: "twitter:card", content: card || 'summary_large_image', "data-rg": "true" }, "twitter:card"));
37
37
  if (site) {
38
- metadataElements.push(_jsx("meta", { name: "twitter:site", content: site }, "twitter:site"));
38
+ metadataElements.push(_jsx("meta", { name: "twitter:site", content: site, "data-rg": "true" }, "twitter:site"));
39
39
  }
40
40
  if (creator) {
41
- metadataElements.push(_jsx("meta", { name: "twitter:creator", content: creator }, "twitter:creator"));
41
+ metadataElements.push(_jsx("meta", { name: "twitter:creator", content: creator, "data-rg": "true" }, "twitter:creator"));
42
42
  }
43
43
  if (image) {
44
- metadataElements.push(_jsx("meta", { name: "twitter:image", content: image }, "twitter:image"));
44
+ metadataElements.push(_jsx("meta", { name: "twitter:image", content: image, "data-rg": "true" }, "twitter:image"));
45
45
  }
46
46
  if (title) {
47
- metadataElements.push(_jsx("meta", { name: "twitter:title", content: title }, "twitter:title"));
47
+ metadataElements.push(_jsx("meta", { name: "twitter:title", content: title, "data-rg": "true" }, "twitter:title"));
48
48
  }
49
49
  if (description) {
50
- metadataElements.push(_jsx("meta", { name: "twitter:description", content: description }, "twitter:description"));
50
+ metadataElements.push(_jsx("meta", { name: "twitter:description", content: description, "data-rg": "true" }, "twitter:description"));
51
51
  }
52
52
  }
53
53
  // Handling links
@@ -67,7 +67,7 @@ export const generateMetadata = (metadatas) => {
67
67
  const generateLinks = (links) => {
68
68
  return links.map((link) => {
69
69
  const { rel, sizes, type, href } = link;
70
- return (_jsx("link", { rel: rel, sizes: sizes || '32x32', type: type || 'image/png', href: href }, rel));
70
+ return (_jsx("link", { rel: rel, sizes: sizes || '32x32', type: type || 'image/png', href: href, "data-rg": "true" }, rel));
71
71
  });
72
72
  };
73
73
  /**
@@ -78,6 +78,6 @@ const generateLinks = (links) => {
78
78
  const generateMetaTags = (metaTags) => {
79
79
  return metaTags.map((metaTag) => {
80
80
  const { content, name, property } = metaTag;
81
- return (_jsx("meta", { property: property ?? name, content: content }, property ?? name));
81
+ return (_jsx("meta", { property: property ?? name, content: content, "data-rg": "true" }, property ?? name));
82
82
  });
83
83
  };
@@ -2,6 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { RouterProvider, createBrowserRouter, useLoaderData, useParams, } from 'react-router';
3
3
  import { ErrorBoundary, NotFoundPageComponent, RasenganPageComponent, } from '../components/index.js';
4
4
  import { Suspense } from 'react';
5
+ import MetadataProvider from '../providers/metadata.js';
5
6
  const defaultMetadata = {
6
7
  title: 'Not Found',
7
8
  description: 'Page not found',
@@ -190,6 +191,12 @@ export const generateRoutes = (router, isRoot = true, parentLayout = undefined)
190
191
  ...props,
191
192
  params,
192
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
+ }
193
200
  return _jsx(Layout, { ...layoutProps });
194
201
  },
195
202
  async loader({ params, request }) {
@@ -299,3 +306,49 @@ export const generateRoutes = (router, isRoot = true, parentLayout = undefined)
299
306
  // Return the formated router
300
307
  return routes;
301
308
  };
309
+ /**
310
+ * This function receives a router component and return a mapping from path to metadata
311
+ * @param router Represents the router component
312
+ * @returns
313
+ */
314
+ export const generateMetadataMapping = (router, isRoot = true, parentLayout = undefined) => {
315
+ const metadataMapping = {};
316
+ // Get information about the layout and the path
317
+ const Layout = router.layout;
318
+ const layoutPath = !isRoot
319
+ ? router.useParentLayout
320
+ ? parentLayout.path + (Layout.path === '/' ? '' : Layout.path)
321
+ : Layout.path
322
+ : Layout.path;
323
+ // Get informations about pages
324
+ router.pages.forEach((Page) => {
325
+ const pagePathFormated = Page.path.startsWith('/') && Page.path !== '/'
326
+ ? Page.path.slice(1)
327
+ : Page.path;
328
+ // Get the path of the page
329
+ const path = Page.path === '/' ? layoutPath : layoutPath + pagePathFormated;
330
+ // Get metadata
331
+ metadataMapping[path] = {
332
+ openGraph: {
333
+ url: '',
334
+ image: '',
335
+ },
336
+ twitter: {
337
+ card: 'summary_large_image',
338
+ image: '',
339
+ title: '',
340
+ },
341
+ ...Page.metadata,
342
+ };
343
+ });
344
+ // Loop through imported routers in order to apply the same logic like above.
345
+ for (const importedRouter of router.routers) {
346
+ const importedMetadataMapping = generateMetadataMapping(importedRouter, false, Layout);
347
+ Object.assign(metadataMapping, importedMetadataMapping);
348
+ // Add the metadata of the imported router's pages to the metadata mapping
349
+ for (const [path, metadata] of Object.entries(importedMetadataMapping)) {
350
+ metadataMapping[path] = metadata;
351
+ }
352
+ }
353
+ return metadataMapping;
354
+ };
@@ -8,11 +8,13 @@ import fs from "node:fs/promises";
8
8
  export const renderIndexHTML = async (template, options) => {
9
9
  const { rootPath, config } = options;
10
10
  const buildOptions = resolveBuildOptions({});
11
- const manifest = new ManifestManager(path.posix.join(buildOptions.buildDirectory, buildOptions.clientPathDirectory, buildOptions.manifestPathDirectory, 'manifest.json'));
11
+ const manifest = new ManifestManager(path.posix.join(buildOptions.buildDirectory, config.ssr ? buildOptions.clientPathDirectory : '', buildOptions.manifestPathDirectory, 'manifest.json'));
12
12
  // Get assets tags
13
13
  const assets = manifest.generateMetaTags(''); // TODO: Add the correct path
14
14
  // Generate html from template
15
15
  const html = renderToString(_jsx(TemplateLayout, { Template: template, assets: assets, isSpaMode: true }));
16
16
  // Render the html into an index.html file
17
- await fs.writeFile(path.posix.join(rootPath, buildOptions.buildDirectory, buildOptions.clientPathDirectory, 'index.html'), html, 'utf-8');
17
+ await fs.writeFile(path.posix.join(rootPath, buildOptions.buildDirectory, 'index.html'), html, 'utf-8');
18
+ // Delete the dist/assets/template.js file
19
+ await fs.rm(path.posix.join(rootPath, buildOptions.buildDirectory, buildOptions.assetPathDirectory, 'template.js'));
18
20
  };
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { ManifestManager } from '../build/manifest.js';
3
+ import fs from 'node:fs';
3
4
  import path from 'node:path';
4
5
  import { generateRoutes } from '../../routing/utils/index.js';
5
6
  import { createStaticHandler, createStaticRouter, StaticRouterProvider, } from 'react-router';
6
7
  import createRasenganRequest from './utils.js';
7
8
  import { extractHeadersFromRRContext, extractMetaFromRRContext, isRedirectResponse, isStaticRedirectFromConfig, } from '../dev/utils.js';
8
9
  import { handleRedirectRequest } from '../dev/handlers.js';
9
- import { loadModuleSSR } from '../../core/config/utils/load-modules.js';
10
10
  import { resolvePath } from '../../core/config/utils/path.js';
11
11
  export function createRequestHandler(options) {
12
12
  const { build: buildOptions } = options;
@@ -18,8 +18,15 @@ export function createRequestHandler(options) {
18
18
  // Get AppRouter
19
19
  const AppRouter = await (await import(resolvePath(path.posix.join(buildOptions.buildDirectory, buildOptions.serverPathDirectory, 'app.router.js')))).default;
20
20
  // Get Config
21
- const configHandler = await (await loadModuleSSR(path.posix.join(buildOptions.buildDirectory, buildOptions.serverPathDirectory, 'config.js'))).default;
22
- const config = await configHandler();
21
+ const configPath = path.posix.join(buildOptions.buildDirectory, buildOptions.clientPathDirectory, buildOptions.assetPathDirectory, 'config.json');
22
+ const configPathExist = fs.existsSync(configPath);
23
+ if (!configPathExist) {
24
+ throw new Error('No config.json file found in dist/client/assets, please make a build again');
25
+ }
26
+ // Read the config.json file
27
+ const configData = fs.readFileSync(configPath, 'utf-8').toString();
28
+ // Parse the config.json file
29
+ const config = JSON.parse(configData);
23
30
  // extract render function
24
31
  const { render, } = entry;
25
32
  // Get static routes
@@ -29,12 +36,11 @@ export function createRequestHandler(options) {
29
36
  // Create rasengan request for static routing
30
37
  let request = createRasenganRequest(req, res);
31
38
  let context = await handler.query(request);
32
- const redirects = await config.redirects();
33
- const redirectFound = await isStaticRedirectFromConfig(req, redirects);
39
+ const redirectFound = await isStaticRedirectFromConfig(req, config.redirects);
34
40
  if (isRedirectResponse(context) || redirectFound) {
35
41
  return await handleRedirectRequest(req, res, {
36
42
  context,
37
- redirects,
43
+ redirects: config.redirects,
38
44
  });
39
45
  }
40
46
  if (!(context instanceof Response)) {
@@ -40,5 +40,8 @@ export const renderToStream = async (Component, res) => {
40
40
  };
41
41
  export const renderToString = (Component) => {
42
42
  const html = ReactDOM.renderToString(Component);
43
- return html;
43
+ return `
44
+ <!DOCTYPE html>
45
+ ${html}
46
+ `;
44
47
  };
package/lib/esm/server.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { createRequestHandler } from './server/node/index.js';
2
2
  import { resolveBuildOptions } from './server/build/index.js';
3
+ import compression from 'compression';
4
+ import express from 'express';
3
5
  export * from './server/build/manifest.js';
4
- export { createRequestHandler, resolveBuildOptions };
6
+ export { createRequestHandler, resolveBuildOptions, express, compression };
@@ -1 +1 @@
1
- {"root":["../src/client.ts","../src/index.ts","../src/plugin.ts","../src/server.ts","../src/cli/index.ts","../src/core/index.ts","../src/core/types.ts","../src/core/config/index.ts","../src/core/config/type.ts","../src/core/config/utils/define-config.ts","../src/core/config/utils/load-modules.ts","../src/core/config/utils/path.ts","../src/core/config/vite/defaults.ts","../src/core/dynamic/index.tsx","../src/core/middlewares/index.ts","../src/core/middlewares/logger.ts","../src/core/plugins/index.ts","../src/core/utils/log.ts","../src/entries/client/render.tsx","../src/entries/server/entry.server.tsx","../src/entries/server/index.tsx","../src/routing/index.ts","../src/routing/interfaces.tsx","../src/routing/types.ts","../src/routing/components/index.tsx","../src/routing/components/template.tsx","../src/routing/utils/define-router.tsx","../src/routing/utils/define-routes-group.tsx","../src/routing/utils/generate-metadata.tsx","../src/routing/utils/generate-routes.tsx","../src/routing/utils/index.tsx","../src/scripts/build-command.js","../src/scripts/generate-package-json.js","../src/scripts/utils/check-os.js","../src/scripts/utils/copy.js","../src/server/build/index.ts","../src/server/build/manifest.tsx","../src/server/build/rendering.tsx","../src/server/dev/handlers.tsx","../src/server/dev/server.ts","../src/server/dev/utils.ts","../src/server/node/index.tsx","../src/server/node/rendering.ts","../src/server/node/stream.ts","../src/server/node/utils.ts","../src/server/runtime/mode.ts","../src/server/runtime/utils.ts","../src/server/virtual/index.ts","../types/client.d.ts"],"version":"5.8.2"}
1
+ {"root":["../src/client.ts","../src/index.ts","../src/plugin.ts","../src/server.ts","../src/cli/index.ts","../src/core/index.ts","../src/core/types.ts","../src/core/config/index.ts","../src/core/config/type.ts","../src/core/config/utils/define-config.ts","../src/core/config/utils/load-modules.ts","../src/core/config/utils/path.ts","../src/core/config/vite/defaults.ts","../src/core/dynamic/index.tsx","../src/core/middlewares/index.ts","../src/core/middlewares/logger.ts","../src/core/plugins/index.ts","../src/core/utils/log.ts","../src/entries/client/render.tsx","../src/entries/server/entry.server.tsx","../src/entries/server/index.tsx","../src/routing/index.ts","../src/routing/interfaces.tsx","../src/routing/types.ts","../src/routing/components/index.tsx","../src/routing/components/template.tsx","../src/routing/providers/metadata.tsx","../src/routing/utils/define-router.tsx","../src/routing/utils/define-routes-group.tsx","../src/routing/utils/generate-metadata.tsx","../src/routing/utils/generate-routes.tsx","../src/routing/utils/index.tsx","../src/scripts/build-command.js","../src/scripts/generate-package-json.js","../src/scripts/utils/check-os.js","../src/scripts/utils/copy.js","../src/server/build/index.ts","../src/server/build/manifest.tsx","../src/server/build/rendering.tsx","../src/server/dev/handlers.tsx","../src/server/dev/server.ts","../src/server/dev/utils.ts","../src/server/node/index.tsx","../src/server/node/rendering.ts","../src/server/node/stream.ts","../src/server/node/utils.ts","../src/server/runtime/mode.ts","../src/server/runtime/utils.ts","../src/server/virtual/index.ts","../types/client.d.ts"],"version":"5.8.2"}
@@ -1 +1 @@
1
- {"root":["../src/client.ts","../src/index.ts","../src/plugin.ts","../src/server.ts","../src/cli/index.ts","../src/core/index.ts","../src/core/types.ts","../src/core/config/index.ts","../src/core/config/type.ts","../src/core/config/utils/define-config.ts","../src/core/config/utils/load-modules.ts","../src/core/config/utils/path.ts","../src/core/config/vite/defaults.ts","../src/core/dynamic/index.tsx","../src/core/middlewares/index.ts","../src/core/middlewares/logger.ts","../src/core/plugins/index.ts","../src/core/utils/log.ts","../src/entries/client/render.tsx","../src/entries/server/entry.server.tsx","../src/entries/server/index.tsx","../src/routing/index.ts","../src/routing/interfaces.tsx","../src/routing/types.ts","../src/routing/components/index.tsx","../src/routing/components/template.tsx","../src/routing/utils/define-router.tsx","../src/routing/utils/define-routes-group.tsx","../src/routing/utils/generate-metadata.tsx","../src/routing/utils/generate-routes.tsx","../src/routing/utils/index.tsx","../src/scripts/build-command.js","../src/scripts/generate-package-json.js","../src/scripts/utils/check-os.js","../src/scripts/utils/copy.js","../src/server/build/index.ts","../src/server/build/manifest.tsx","../src/server/build/rendering.tsx","../src/server/dev/handlers.tsx","../src/server/dev/server.ts","../src/server/dev/utils.ts","../src/server/node/index.tsx","../src/server/node/rendering.ts","../src/server/node/stream.ts","../src/server/node/utils.ts","../src/server/runtime/mode.ts","../src/server/runtime/utils.ts","../src/server/virtual/index.ts","../types/client.d.ts"],"version":"5.8.2"}
1
+ {"root":["../src/client.ts","../src/index.ts","../src/plugin.ts","../src/server.ts","../src/cli/index.ts","../src/core/index.ts","../src/core/types.ts","../src/core/config/index.ts","../src/core/config/type.ts","../src/core/config/utils/define-config.ts","../src/core/config/utils/load-modules.ts","../src/core/config/utils/path.ts","../src/core/config/vite/defaults.ts","../src/core/dynamic/index.tsx","../src/core/middlewares/index.ts","../src/core/middlewares/logger.ts","../src/core/plugins/index.ts","../src/core/utils/log.ts","../src/entries/client/render.tsx","../src/entries/server/entry.server.tsx","../src/entries/server/index.tsx","../src/routing/index.ts","../src/routing/interfaces.tsx","../src/routing/types.ts","../src/routing/components/index.tsx","../src/routing/components/template.tsx","../src/routing/providers/metadata.tsx","../src/routing/utils/define-router.tsx","../src/routing/utils/define-routes-group.tsx","../src/routing/utils/generate-metadata.tsx","../src/routing/utils/generate-routes.tsx","../src/routing/utils/index.tsx","../src/scripts/build-command.js","../src/scripts/generate-package-json.js","../src/scripts/utils/check-os.js","../src/scripts/utils/copy.js","../src/server/build/index.ts","../src/server/build/manifest.tsx","../src/server/build/rendering.tsx","../src/server/dev/handlers.tsx","../src/server/dev/server.ts","../src/server/dev/utils.ts","../src/server/node/index.tsx","../src/server/node/rendering.ts","../src/server/node/stream.ts","../src/server/node/utils.ts","../src/server/runtime/mode.ts","../src/server/runtime/utils.ts","../src/server/virtual/index.ts","../types/client.d.ts"],"version":"5.8.2"}
@@ -1,4 +1,5 @@
1
1
  import type * as Vite from 'vite';
2
+ import { BuildOptions } from '../../server/build';
2
3
  export interface ServerConfig {
3
4
  /**
4
5
  * Configure server in development
@@ -45,6 +46,11 @@ export type AppConfig = {
45
46
  */
46
47
  redirects?: () => Promise<Redirect[]>;
47
48
  };
49
+ export type OptimizedAppConfig = {
50
+ ssr?: AppConfig['ssr'];
51
+ redirects: Redirect[];
52
+ buildOptions: BuildOptions;
53
+ };
48
54
  export type AppConfigFunction = () => AppConfig;
49
55
  export type AppConfigFunctionAsync = () => Promise<AppConfig>;
50
56
  /**
@@ -1,6 +1,6 @@
1
1
  import { defineConfig } from './core/config/utils/define-config.js';
2
2
  export * from './routing/index.js';
3
3
  export { defineConfig };
4
- export type { AppConfig, AppConfigFunction, AppConfigFunctionAsync, } from './core/config/type.js';
4
+ export type { AppConfig, AppConfigFunction, AppConfigFunctionAsync, OptimizedAppConfig, } from './core/config/type.js';
5
5
  export type { AppProps } from './core/index.js';
6
6
  export type * from './server/build/manifest.js';
@@ -2,5 +2,5 @@ import { CustomLink } from './components/index.js';
2
2
  export type { Metadata, MetadataWithoutTitleAndDescription, LayoutComponent, PageComponent, MDXPageComponent, LoaderOptions, LoaderResponse, ReactComponentProps, TemplateProps, } from './types.js';
3
3
  export { defineRouter, defineRoutesGroup } from './utils/index.js';
4
4
  export { RouterComponent } from './interfaces.js';
5
- export { Outlet, useLocation, useNavigate, useNavigation, useParams, useSearchParams, useFetcher, useMatch, useRoutes, useResolvedPath, matchRoutes, generatePath, matchPath, createRoutesFromChildren, Navigate, } from 'react-router';
5
+ export { Outlet, ScrollRestoration, useLocation, useNavigate, useNavigation, useParams, useSearchParams, useFetcher, useMatch, useRoutes, useResolvedPath, matchRoutes, generatePath, matchPath, createRoutesFromChildren, Navigate, } from 'react-router';
6
6
  export { CustomLink as Link };
@@ -0,0 +1,5 @@
1
+ import { Metadata } from '../types.js';
2
+ export default function MetadataProvider({ children, metadataMapping, }: {
3
+ children: React.ReactNode;
4
+ metadataMapping: Record<string, Metadata>;
5
+ }): import("react/jsx-runtime.js").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { RouterComponent } from '../interfaces.js';
2
- import { RouteObject, LayoutComponent } from '../types.js';
2
+ import { RouteObject, LayoutComponent, Metadata } from '../types.js';
3
3
  /**
4
4
  * This function receives a router component and get a formated router first
5
5
  * and then return a router.
@@ -11,3 +11,9 @@ export declare const getRouter: (routerInstance: RouterComponent) => () => impor
11
11
  * @returns
12
12
  */
13
13
  export declare const generateRoutes: (router: RouterComponent, isRoot?: boolean, parentLayout?: LayoutComponent | undefined) => RouteObject[];
14
+ /**
15
+ * This function receives a router component and return a mapping from path to metadata
16
+ * @param router Represents the router component
17
+ * @returns
18
+ */
19
+ export declare const generateMetadataMapping: (router: RouterComponent, isRoot?: boolean, parentLayout?: LayoutComponent | undefined) => Record<string, Metadata>;
@@ -1,4 +1,6 @@
1
1
  import { createRequestHandler } from './server/node/index.js';
2
2
  import { resolveBuildOptions } from './server/build/index.js';
3
+ import compression from 'compression';
4
+ import express from 'express';
3
5
  export * from './server/build/manifest.js';
4
- export { createRequestHandler, resolveBuildOptions };
6
+ export { createRequestHandler, resolveBuildOptions, express, compression };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rasengan",
3
3
  "private": false,
4
- "version": "1.0.0-beta.60",
4
+ "version": "1.0.0-beta.62",
5
5
  "description": "The modern React Framework",
6
6
  "type": "module",
7
7
  "main": "lib/esm/index.js",
@@ -69,7 +69,7 @@
69
69
  "inquirer": "^9.2.12",
70
70
  "open": "^10.1.0",
71
71
  "ora": "^7.0.1",
72
- "react-router": "^7.0.0"
72
+ "react-router": "^7.5.2"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@types/node": "^18.0.0 || >=20.0.0",
@@ -79,7 +79,7 @@
79
79
  "sass": "*",
80
80
  "stylus": "*",
81
81
  "vite": "^6.0.0",
82
- "@rasenganjs/mdx": "^1.1.0-beta.1"
82
+ "@rasenganjs/mdx": "^1.1.1"
83
83
  },
84
84
  "peerDependenciesMeta": {
85
85
  "@types/node": {