@adonisjs/inertia 1.0.0-12 → 1.0.0-14

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.
@@ -1,13 +1,101 @@
1
+ // src/server_renderer.ts
2
+ var styleFileRE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\?)/;
3
+ var ServerRenderer = class {
4
+ constructor(config, vite) {
5
+ this.config = config;
6
+ this.vite = vite;
7
+ }
8
+ /**
9
+ * If the module is a style module
10
+ */
11
+ #isStyle(mod) {
12
+ if (styleFileRE.test(mod.url) || mod.id && /\?vue&type=style/.test(mod.id)) {
13
+ return true;
14
+ }
15
+ return false;
16
+ }
17
+ /**
18
+ * Collect CSS files from the module graph recursively
19
+ */
20
+ #collectCss(mod, styleUrls, visitedModules, importer) {
21
+ if (!mod.url)
22
+ return;
23
+ if (visitedModules.has(mod.url))
24
+ return;
25
+ visitedModules.add(mod.url);
26
+ if (this.#isStyle(mod) && (!importer || !this.#isStyle(importer))) {
27
+ if (mod.url.startsWith("/")) {
28
+ styleUrls.add(mod.url);
29
+ } else if (mod.url.startsWith("\0")) {
30
+ styleUrls.add(`/@id/__x00__${mod.url.substring(1)}`);
31
+ } else {
32
+ styleUrls.add(`/@id/${mod.url}`);
33
+ }
34
+ }
35
+ mod.importedModules.forEach((dep) => this.#collectCss(dep, styleUrls, visitedModules, mod));
36
+ }
37
+ /**
38
+ * Generate the preload tag for a CSS file
39
+ */
40
+ #getPreloadTag(href) {
41
+ return `<link rel="stylesheet" href="${href}" />`;
42
+ }
43
+ /**
44
+ * Find a page module from the entrypoint module
45
+ *
46
+ * The implementation is dumb, we are just looking for the first module
47
+ * imported by the entrypoint module that matches the regex
48
+ */
49
+ #findPageModule(entryMod, pageObject) {
50
+ const pattern = `${pageObject.component.replace(/\//g, "\\/")}.(tsx|vue|svelte|jsx|ts|js)$`;
51
+ const regex = new RegExp(pattern);
52
+ return [...entryMod?.ssrImportedModules || []].find((dep) => regex.test(dep.url));
53
+ }
54
+ /**
55
+ * Render the page on the server
56
+ *
57
+ * On development, we use the Vite Runtime API
58
+ * On production, we just import and use the SSR bundle generated by Vite
59
+ */
60
+ async render(pageObject) {
61
+ let render;
62
+ let preloadTags = [];
63
+ if (this.vite) {
64
+ const devServer = this.vite.getDevServer();
65
+ const runtime = await this.vite.createRuntime();
66
+ render = await runtime.executeEntrypoint(this.config.ssr.entrypoint);
67
+ const entryMod = devServer.moduleGraph.getModuleById(this.config.entrypoint);
68
+ const pageMod = this.#findPageModule(entryMod, pageObject);
69
+ if (pageMod)
70
+ await runtime.executeUrl(pageMod.url);
71
+ const preloadUrls = /* @__PURE__ */ new Set();
72
+ const visitedModules = /* @__PURE__ */ new Set();
73
+ if (pageMod)
74
+ this.#collectCss(pageMod, preloadUrls, visitedModules);
75
+ if (entryMod)
76
+ this.#collectCss(entryMod, preloadUrls, visitedModules);
77
+ preloadTags = Array.from(preloadUrls).map(this.#getPreloadTag);
78
+ } else {
79
+ render = await import(this.config.ssr.bundle);
80
+ }
81
+ const result = await render.default(pageObject);
82
+ const head = preloadTags.concat(result.head);
83
+ return { head, body: result.body };
84
+ }
85
+ };
86
+
1
87
  // src/inertia.ts
2
88
  var kLazySymbol = Symbol("lazy");
3
89
  var Inertia = class {
4
- constructor(ctx, config, viteRuntime) {
90
+ constructor(ctx, config, vite) {
5
91
  this.ctx = ctx;
6
92
  this.config = config;
7
- this.viteRuntime = viteRuntime;
93
+ this.vite = vite;
8
94
  this.#sharedData = config.sharedData;
95
+ this.#serverRenderer = new ServerRenderer(config, vite);
9
96
  }
10
97
  #sharedData = {};
98
+ #serverRenderer;
11
99
  /**
12
100
  * Check if a value is a lazy prop
13
101
  */
@@ -71,21 +159,12 @@ var Inertia = class {
71
159
  }
72
160
  /**
73
161
  * Render the page on the server
74
- *
75
- * On development, we use the Vite Runtime API
76
- * On production, we just import and use the SSR bundle generated by Vite
77
162
  */
78
163
  async #renderOnServer(pageObject, viewProps) {
79
- let render;
80
- if (this.viteRuntime) {
81
- render = await this.viteRuntime.executeEntrypoint(this.config.ssr.entrypoint);
82
- } else {
83
- render = await import(this.config.ssr.bundle);
84
- }
85
- const result = await render.default(pageObject);
164
+ const { head, body } = await this.#serverRenderer.render(pageObject);
86
165
  return this.ctx.view.render(this.config.rootView, {
87
166
  ...viewProps,
88
- page: { ssrHead: result.head, ssrBody: result.body, ...pageObject }
167
+ page: { ssrHead: head, ssrBody: body, ...pageObject }
89
168
  });
90
169
  }
91
170
  /**
@@ -137,12 +216,11 @@ var Inertia = class {
137
216
  var InertiaMiddleware = class {
138
217
  constructor(config, vite) {
139
218
  this.config = config;
140
- this.#runtime = vite?.getRuntime();
219
+ this.vite = vite;
141
220
  }
142
- #runtime;
143
221
  async handle(ctx, next) {
144
222
  const { response, request } = ctx;
145
- ctx.inertia = new Inertia(ctx, this.config, this.#runtime);
223
+ ctx.inertia = new Inertia(ctx, this.config, this.vite);
146
224
  await next();
147
225
  const isInertiaRequest = !!request.header("x-inertia");
148
226
  if (!isInertiaRequest)
package/build/index.js CHANGED
@@ -225,20 +225,76 @@ var VersionCache = class {
225
225
  }
226
226
  };
227
227
 
228
+ // src/files_detector.ts
229
+ import { locatePath } from "locate-path";
230
+ var FilesDetector = class {
231
+ constructor(app) {
232
+ this.app = app;
233
+ }
234
+ /**
235
+ * Try to locate the entrypoint file based
236
+ * on the conventional locations
237
+ */
238
+ async detectEntrypoint(defaultPath) {
239
+ const possiblesLocations = [
240
+ "./resources/app.ts",
241
+ "./resources/app.tsx",
242
+ "./resources/application/app.ts",
243
+ "./resources/application/app.tsx",
244
+ "./resources/app.jsx",
245
+ "./resources/app.js",
246
+ "./resources/application/app.jsx",
247
+ "./resources/application/app.js"
248
+ ];
249
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
250
+ return this.app.makePath(path || defaultPath);
251
+ }
252
+ /**
253
+ * Try to locate the SSR entrypoint file based
254
+ * on the conventional locations
255
+ */
256
+ async detectSsrEntrypoint(defaultPath) {
257
+ const possiblesLocations = [
258
+ "./resources/ssr.ts",
259
+ "./resources/ssr.tsx",
260
+ "./resources/application/ssr.ts",
261
+ "./resources/application/ssr.tsx",
262
+ "./resources/ssr.jsx",
263
+ "./resources/ssr.js",
264
+ "./resources/application/ssr.jsx",
265
+ "./resources/application/ssr.js"
266
+ ];
267
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
268
+ return this.app.makePath(path || defaultPath);
269
+ }
270
+ /**
271
+ * Try to locate the SSR bundle file based
272
+ * on the conventional locations
273
+ */
274
+ async detectSsrBundle(defaultPath) {
275
+ const possiblesLocations = ["./ssr/ssr.js", "./ssr/ssr.mjs"];
276
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
277
+ return this.app.makePath(path || defaultPath);
278
+ }
279
+ };
280
+
228
281
  // src/define_config.ts
282
+ import { slash } from "@poppinss/utils";
229
283
  function defineConfig(config) {
230
284
  return configProvider.create(async (app) => {
285
+ const detector = new FilesDetector(app);
231
286
  const versionCache = new VersionCache(app.appRoot, config.assetsVersion);
232
287
  await versionCache.computeVersion();
233
288
  return {
289
+ versionCache,
234
290
  rootView: config.rootView ?? "root",
235
291
  sharedData: config.sharedData || {},
236
- versionCache,
292
+ entrypoint: slash(config.entrypoint ?? await detector.detectEntrypoint("resources/app.ts")),
237
293
  ssr: {
238
294
  enabled: config.ssr?.enabled ?? false,
239
295
  pages: config.ssr?.pages,
240
- entrypoint: config.ssr?.entrypoint ?? app.makePath("resources/ssr.ts"),
241
- bundle: config.ssr?.bundle ?? app.makePath("ssr/ssr.js")
296
+ entrypoint: config.ssr?.entrypoint ?? await detector.detectSsrEntrypoint("resources/ssr.ts"),
297
+ bundle: config.ssr?.bundle ?? await detector.detectSsrBundle("ssr/ssr.js")
242
298
  }
243
299
  };
244
300
  });
@@ -19,7 +19,13 @@ declare class InertiaProvider {
19
19
  * Registers edge plugin when edge is installed
20
20
  */
21
21
  protected registerEdgePlugin(): Promise<void>;
22
+ /**
23
+ * Register inertia middleware
24
+ */
22
25
  register(): Promise<void>;
26
+ /**
27
+ * Register edge plugin and brisk route macro
28
+ */
23
29
  boot(): Promise<void>;
24
30
  }
25
31
 
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  InertiaMiddleware
3
- } from "../chunk-RTJXBXWZ.js";
3
+ } from "../chunk-NVJNYWGW.js";
4
4
 
5
5
  // providers/inertia_provider.ts
6
6
  import { configProvider } from "@adonisjs/core";
7
- import { RuntimeException } from "@poppinss/utils";
8
7
  import { BriskRoute } from "@adonisjs/core/http";
8
+ import { RuntimeException } from "@poppinss/utils";
9
9
  var InertiaProvider = class {
10
10
  constructor(app) {
11
11
  this.app = app;
@@ -20,6 +20,9 @@ var InertiaProvider = class {
20
20
  const { edgePluginInertia } = await import("../src/plugins/edge/plugin.js");
21
21
  edgeExports.default.use(edgePluginInertia());
22
22
  }
23
+ /**
24
+ * Register inertia middleware
25
+ */
23
26
  async register() {
24
27
  this.app.container.singleton(InertiaMiddleware, async () => {
25
28
  const inertiaConfigProvider = this.app.config.get("inertia");
@@ -33,6 +36,9 @@ var InertiaProvider = class {
33
36
  return new InertiaMiddleware(config, vite);
34
37
  });
35
38
  }
39
+ /**
40
+ * Register edge plugin and brisk route macro
41
+ */
36
42
  async boot() {
37
43
  await this.registerEdgePlugin();
38
44
  BriskRoute.macro("renderInertia", function(template, props, viewProps) {
@@ -5,6 +5,7 @@ import './css/app.css';
5
5
 
6
6
  import { createRoot } from 'react-dom/client';
7
7
  import { createInertiaApp } from '@inertiajs/react';
8
+ import { resolvePageComponent } from '@adonisjs/inertia/helpers'
8
9
 
9
10
  const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
10
11
 
@@ -14,8 +15,10 @@ createInertiaApp({
14
15
  title: (title) => {{ '`${title} - ${appName}`' }},
15
16
 
16
17
  resolve: (name) => {
17
- const pages = import.meta.glob('./pages/**/*.tsx', { eager: true })
18
- {{ 'return pages[`./pages/${name}.tsx`]' }}
18
+ return resolvePageComponent(
19
+ {{ '`./pages/${name}.tsx`' }},
20
+ import.meta.glob<DefineComponent>('./pages/**/*.tsx'),
21
+ )
19
22
  },
20
23
 
21
24
  setup({ el, App, props }) {
@@ -11,7 +11,7 @@
11
11
  <title inertia>AdonisJS x Inertia x React</title>
12
12
 
13
13
  @viteReactRefresh()
14
- @vite(['resources/app.tsx'])
14
+ {{ "@vite(['resources/app.tsx', `resources/pages/${page.component}.tsx`])" }}
15
15
  @inertiaHead()
16
16
  </head>
17
17
 
@@ -5,6 +5,7 @@ import './css/app.css'
5
5
 
6
6
  import { render } from 'solid-js/web'
7
7
  import { createInertiaApp } from 'inertia-adapter-solid'
8
+ import { resolvePageComponent } from '@adonisjs/inertia/helpers'
8
9
 
9
10
  const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
10
11
 
@@ -13,9 +14,11 @@ createInertiaApp({
13
14
 
14
15
  title: (title) => {{ '`${title} - ${appName}`' }},
15
16
 
16
- resolve(name) {
17
- const pages = import.meta.glob('./pages/**/*.tsx', { eager: true })
18
- {{ 'return pages[`./pages/${name}.tsx`]' }}
17
+ resolve: (name) => {
18
+ return resolvePageComponent(
19
+ {{ '`./pages/${name}.tsx`' }},
20
+ import.meta.glob<DefineComponent>('./pages/**/*.tsx'),
21
+ )
19
22
  },
20
23
 
21
24
  setup({ el, App, props }) {
@@ -10,7 +10,7 @@
10
10
 
11
11
  <title inertia>AdonisJS x Inertia x SolidJS</title>
12
12
 
13
- @vite(['resources/app.tsx'])
13
+ {{ "@vite(['resources/app.tsx', `resources/pages/${page.component}.tsx`])" }}
14
14
  @inertiaHead()
15
15
  </head>
16
16
 
@@ -1,7 +1,6 @@
1
1
  import { Vite } from '@adonisjs/vite';
2
2
  import { HttpContext } from '@adonisjs/core/http';
3
3
  import { NextFn } from '@adonisjs/core/types/http';
4
- import { ViteRuntime } from 'vite/runtime';
5
4
  import { ResolvedConfig, Data, PageProps, PageObject, MaybePromise } from './types.js';
6
5
 
7
6
  /**
@@ -15,8 +14,8 @@ declare class Inertia {
15
14
  #private;
16
15
  protected ctx: HttpContext;
17
16
  protected config: ResolvedConfig;
18
- protected viteRuntime?: ViteRuntime | undefined;
19
- constructor(ctx: HttpContext, config: ResolvedConfig, viteRuntime?: ViteRuntime | undefined);
17
+ protected vite?: Vite | undefined;
18
+ constructor(ctx: HttpContext, config: ResolvedConfig, vite?: Vite | undefined);
20
19
  /**
21
20
  * Share data for the current request.
22
21
  * This data will override any shared data defined in the config.
@@ -59,9 +58,9 @@ declare module '@adonisjs/core/http' {
59
58
  * set appropriate headers/status
60
59
  */
61
60
  declare class InertiaMiddleware {
62
- #private;
63
61
  protected config: ResolvedConfig;
64
- constructor(config: ResolvedConfig, vite?: Vite);
62
+ protected vite?: Vite | undefined;
63
+ constructor(config: ResolvedConfig, vite?: Vite | undefined);
65
64
  handle(ctx: HttpContext, next: NextFn): Promise<void>;
66
65
  }
67
66
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  InertiaMiddleware
3
- } from "../chunk-RTJXBXWZ.js";
3
+ } from "../chunk-NVJNYWGW.js";
4
4
  export {
5
5
  InertiaMiddleware as default
6
6
  };
@@ -47,6 +47,10 @@ interface InertiaConfig {
47
47
  * @default root (resources/views/root.edge)
48
48
  */
49
49
  rootView?: string;
50
+ /**
51
+ * Path to your client-side entrypoint file.
52
+ */
53
+ entrypoint?: string;
50
54
  /**
51
55
  * The version of your assets. Every client request will be checked against this version.
52
56
  * If the version is not the same, the client will do a full reload.
@@ -85,6 +89,7 @@ interface ResolvedConfig {
85
89
  rootView: string;
86
90
  versionCache: VersionCache;
87
91
  sharedData: SharedData;
92
+ entrypoint: string;
88
93
  ssr: {
89
94
  enabled: boolean;
90
95
  entrypoint: string;
@@ -6,6 +6,7 @@ import './css/app.css';
6
6
  import { createApp, h } from 'vue'
7
7
  import type { DefineComponent } from 'vue'
8
8
  import { createInertiaApp } from '@inertiajs/vue3'
9
+ import { resolvePageComponent } from '@adonisjs/inertia/helpers'
9
10
 
10
11
  const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
11
12
 
@@ -15,8 +16,10 @@ createInertiaApp({
15
16
  title: (title) => {{ '`${title} - ${appName}`' }},
16
17
 
17
18
  resolve: (name) => {
18
- const pages = import.meta.glob<DefineComponent>('./pages/**/*.vue', { eager: true })
19
- {{ 'return pages[`./pages/${name}.vue`]' }}
19
+ return resolvePageComponent(
20
+ {{ '`./pages/${name}.vue`' }},
21
+ import.meta.glob<DefineComponent>('./pages/**/*.vue'),
22
+ )
20
23
  },
21
24
 
22
25
  setup({ el, App, props, plugin }) {
@@ -10,7 +10,7 @@
10
10
 
11
11
  <title inertia>AdonisJS x Inertia x VueJS</title>
12
12
 
13
- @vite(['resources/app.ts'])
13
+ {{ "@vite(['resources/app.ts', `resources/pages/${page.component}.vue`])" }}
14
14
  @inertiaHead()
15
15
  </head>
16
16
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonisjs/inertia",
3
3
  "description": "Official Inertia.js adapter for AdonisJS",
4
- "version": "1.0.0-12",
4
+ "version": "1.0.0-14",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },
@@ -44,7 +44,7 @@
44
44
  "@adonisjs/prettier-config": "^1.2.2",
45
45
  "@adonisjs/session": "7.1.1",
46
46
  "@adonisjs/tsconfig": "^1.2.2",
47
- "@adonisjs/vite": "^3.0.0-4",
47
+ "@adonisjs/vite": "^3.0.0-6",
48
48
  "@japa/api-client": "^2.0.2",
49
49
  "@japa/assert": "2.1.0",
50
50
  "@japa/expect-type": "^2.0.1",
@@ -78,12 +78,13 @@
78
78
  "crc-32": "^1.2.2",
79
79
  "edge-error": "^4.0.1",
80
80
  "html-entities": "^2.4.0",
81
+ "locate-path": "^7.2.0",
81
82
  "qs": "^6.11.2"
82
83
  },
83
84
  "peerDependencies": {
84
85
  "@adonisjs/core": "^6.2.0",
85
86
  "@adonisjs/session": "^7.0.0",
86
- "@adonisjs/vite": "^3.0.0-4",
87
+ "@adonisjs/vite": "^3.0.0-6",
87
88
  "@japa/api-client": "^2.0.0",
88
89
  "edge.js": "^6.0.0"
89
90
  },