@devlusoft/devix 0.1.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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -0
  3. package/bin/devix.js +2 -0
  4. package/dist/cli/build.d.ts +1 -0
  5. package/dist/cli/build.js +286 -0
  6. package/dist/cli/build.js.map +7 -0
  7. package/dist/cli/dev.d.ts +1 -0
  8. package/dist/cli/dev.js +361 -0
  9. package/dist/cli/dev.js.map +7 -0
  10. package/dist/cli/generate.d.ts +1 -0
  11. package/dist/cli/generate.js +389 -0
  12. package/dist/cli/generate.js.map +7 -0
  13. package/dist/cli/index.d.ts +2 -0
  14. package/dist/cli/index.js +649 -0
  15. package/dist/cli/index.js.map +7 -0
  16. package/dist/cli/start.d.ts +1 -0
  17. package/dist/cli/start.js +78 -0
  18. package/dist/cli/start.js.map +7 -0
  19. package/dist/config.d.ts +21 -0
  20. package/dist/config.js +17 -0
  21. package/dist/config.js.map +7 -0
  22. package/dist/runtime/api-context.d.ts +20 -0
  23. package/dist/runtime/api-context.js +18 -0
  24. package/dist/runtime/api-context.js.map +7 -0
  25. package/dist/runtime/client-router.d.ts +13 -0
  26. package/dist/runtime/client-router.js +59 -0
  27. package/dist/runtime/client-router.js.map +7 -0
  28. package/dist/runtime/context.d.ts +27 -0
  29. package/dist/runtime/context.js +15 -0
  30. package/dist/runtime/context.js.map +7 -0
  31. package/dist/runtime/error-boundary.d.ts +19 -0
  32. package/dist/runtime/error-boundary.js +37 -0
  33. package/dist/runtime/error-boundary.js.map +7 -0
  34. package/dist/runtime/head.d.ts +3 -0
  35. package/dist/runtime/head.js +69 -0
  36. package/dist/runtime/head.js.map +7 -0
  37. package/dist/runtime/index.d.ts +5 -0
  38. package/dist/runtime/index.js +300 -0
  39. package/dist/runtime/index.js.map +7 -0
  40. package/dist/runtime/link.d.ts +8 -0
  41. package/dist/runtime/link.js +43 -0
  42. package/dist/runtime/link.js.map +7 -0
  43. package/dist/runtime/metadata.d.ts +10 -0
  44. package/dist/runtime/metadata.js +22 -0
  45. package/dist/runtime/metadata.js.map +7 -0
  46. package/dist/runtime/router-provider.d.ts +22 -0
  47. package/dist/runtime/router-provider.js +259 -0
  48. package/dist/runtime/router-provider.js.map +7 -0
  49. package/dist/server/api-router.d.ts +21 -0
  50. package/dist/server/api-router.js +64 -0
  51. package/dist/server/api-router.js.map +7 -0
  52. package/dist/server/api.d.ts +2 -0
  53. package/dist/server/api.js +123 -0
  54. package/dist/server/api.js.map +7 -0
  55. package/dist/server/collect-css.d.ts +2 -0
  56. package/dist/server/collect-css.js +15 -0
  57. package/dist/server/collect-css.js.map +7 -0
  58. package/dist/server/index.d.ts +6 -0
  59. package/dist/server/index.js +133 -0
  60. package/dist/server/index.js.map +7 -0
  61. package/dist/server/pages-router.d.ts +21 -0
  62. package/dist/server/pages-router.js +64 -0
  63. package/dist/server/pages-router.js.map +7 -0
  64. package/dist/server/render.d.ts +34 -0
  65. package/dist/server/render.js +306 -0
  66. package/dist/server/render.js.map +7 -0
  67. package/dist/server/routes.d.ts +11 -0
  68. package/dist/server/routes.js +42 -0
  69. package/dist/server/routes.js.map +7 -0
  70. package/dist/server/types.d.ts +49 -0
  71. package/dist/server/types.js +1 -0
  72. package/dist/server/types.js.map +7 -0
  73. package/dist/types.d.ts +35 -0
  74. package/dist/types.js +1 -0
  75. package/dist/types.js.map +7 -0
  76. package/dist/utils/async.d.ts +1 -0
  77. package/dist/utils/async.js +14 -0
  78. package/dist/utils/async.js.map +7 -0
  79. package/dist/utils/banner.d.ts +1 -0
  80. package/dist/utils/banner.js +34 -0
  81. package/dist/utils/banner.js.map +7 -0
  82. package/dist/utils/duration.d.ts +1 -0
  83. package/dist/utils/duration.js +22 -0
  84. package/dist/utils/duration.js.map +7 -0
  85. package/dist/utils/html.d.ts +2 -0
  86. package/dist/utils/html.js +12 -0
  87. package/dist/utils/html.js.map +7 -0
  88. package/dist/utils/patterns.d.ts +1 -0
  89. package/dist/utils/patterns.js +8 -0
  90. package/dist/utils/patterns.js.map +7 -0
  91. package/dist/vite/codegen/api.d.ts +6 -0
  92. package/dist/vite/codegen/api.js +23 -0
  93. package/dist/vite/codegen/api.js.map +7 -0
  94. package/dist/vite/codegen/client-routes.d.ts +6 -0
  95. package/dist/vite/codegen/client-routes.js +36 -0
  96. package/dist/vite/codegen/client-routes.js.map +7 -0
  97. package/dist/vite/codegen/context.d.ts +1 -0
  98. package/dist/vite/codegen/context.js +10 -0
  99. package/dist/vite/codegen/context.js.map +7 -0
  100. package/dist/vite/codegen/entry-client.d.ts +5 -0
  101. package/dist/vite/codegen/entry-client.js +64 -0
  102. package/dist/vite/codegen/entry-client.js.map +7 -0
  103. package/dist/vite/codegen/render.d.ts +6 -0
  104. package/dist/vite/codegen/render.js +31 -0
  105. package/dist/vite/codegen/render.js.map +7 -0
  106. package/dist/vite/index.d.ts +3 -0
  107. package/dist/vite/index.js +225 -0
  108. package/dist/vite/index.js.map +7 -0
  109. package/package.json +77 -0
@@ -0,0 +1,361 @@
1
+ // src/cli/dev.ts
2
+ import { createServer } from "node:http";
3
+ import { createServer as createViteServer } from "vite";
4
+ import { getRequestListener } from "@hono/node-server";
5
+ import { Hono } from "hono";
6
+
7
+ // src/vite/index.ts
8
+ import { mergeConfig } from "vite";
9
+ import react from "@vitejs/plugin-react";
10
+ import { fileURLToPath } from "node:url";
11
+ import { dirname, resolve } from "node:path";
12
+
13
+ // src/vite/codegen/entry-client.ts
14
+ function generateEntryClient({ cssUrls }) {
15
+ const cssImports = cssUrls.map((u) => `import '${u}'`).join("\n");
16
+ return `
17
+ ${cssImports}
18
+ import "@vitejs/plugin-react/preamble"
19
+ import React from "react"
20
+ import {hydrateRoot, createRoot} from 'react-dom/client'
21
+ import {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'
22
+ import {RouterProvider} from '@devlusoft/devix'
23
+
24
+ const root = document.getElementById('devix-root')
25
+
26
+ if (!window.__DEVIX__) {
27
+ const ErrorPage = getDefaultErrorPage()
28
+ createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))
29
+ } else {
30
+ const {metadata, viewport, clientEntry} = window.__DEVIX__
31
+ const loaderData = window.__LOADER_DATA__
32
+ const layoutsData = window.__LAYOUTS_DATA__ ?? []
33
+
34
+ const matched = matchClientRoute(window.location.pathname)
35
+
36
+ if (matched) {
37
+ const [pageMod, ...layoutMods] = await Promise.all([
38
+ matched.load(),
39
+ ...matched.loadLayouts.map(l => l()),
40
+ ])
41
+ hydrateRoot(
42
+ root,
43
+ React.createElement(RouterProvider, {
44
+ clientEntry,
45
+ initialData: loaderData,
46
+ initialParams: matched.params,
47
+ initialPage: pageMod.default,
48
+ initialLayouts: layoutMods.map(m => m.default),
49
+ initialLayoutsData: layoutsData,
50
+ initialMeta: metadata,
51
+ initialViewport: viewport,
52
+ })
53
+ )
54
+ } else {
55
+ const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()
56
+ createRoot(root).render(
57
+ React.createElement(RouterProvider, {
58
+ clientEntry,
59
+ initialData: null,
60
+ initialParams: {},
61
+ initialPage: () => null,
62
+ initialLayouts: [],
63
+ initialLayoutsData: [],
64
+ initialMeta: null,
65
+ initialError: {statusCode: 404, message: 'Not found'},
66
+ initialErrorPage: ErrorPage,
67
+ })
68
+ )
69
+ }
70
+ }
71
+ `;
72
+ }
73
+
74
+ // src/vite/codegen/client-routes.ts
75
+ function generateClientRoutes({ pagesDir, matcherPath }) {
76
+ return `
77
+ import React from 'react'
78
+ import { createMatcher } from '${matcherPath}'
79
+ const pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
80
+ const layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')
81
+ const errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')
82
+
83
+ export const matchClientRoute = createMatcher(pageFiles, layoutFiles)
84
+
85
+ export async function loadErrorPage() {
86
+ const key = Object.keys(errorFiles)[0]
87
+ if (!key) return null
88
+ const mod = await errorFiles[key]()
89
+ return mod?.default ?? null
90
+ }
91
+
92
+ export function getDefaultErrorPage() {
93
+ return function DefaultError({ statusCode, message }) {
94
+ return React.createElement('main', {
95
+ style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column',
96
+ alignItems: 'center', justifyContent: 'center', gap: '8px',
97
+ fontFamily: 'system-ui, sans-serif' }
98
+ },
99
+ React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),
100
+ React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),
101
+ )
102
+ }
103
+ }
104
+ `;
105
+ }
106
+
107
+ // src/vite/codegen/render.ts
108
+ function generateRender({ pagesDir, renderPath }) {
109
+ return `
110
+ import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'
111
+
112
+ const _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
113
+ const _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')
114
+
115
+ const _glob = {
116
+ pages: _pages,
117
+ layouts: _layouts,
118
+ pagesDir: '/${pagesDir}',
119
+ }
120
+
121
+ export function render(url, request, options) {
122
+ return _render(url, request, _glob, options)
123
+ }
124
+
125
+ export function runLoader(url, request, options) {
126
+ return _runLoader(url, request, _glob, options)
127
+ }
128
+
129
+ export function getStaticRoutes() {
130
+ return _getStaticRoutes(_glob)
131
+ }
132
+ `;
133
+ }
134
+
135
+ // src/vite/codegen/api.ts
136
+ function generateApi({ apiPath, appDir }) {
137
+ return `
138
+ import { handleApiRequest as _handleApiRequest } from '${apiPath}'
139
+
140
+ const _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])
141
+ const _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')
142
+
143
+ const _glob = {
144
+ routes: _routes,
145
+ middlewares: _middlewares,
146
+ apiDir: '/${appDir}/api',
147
+ }
148
+
149
+ export function handleApiRequest(url, request) {
150
+ return _handleApiRequest(url, request, _glob)
151
+ }
152
+ `;
153
+ }
154
+
155
+ // src/server/pages-router.ts
156
+ var cache = null;
157
+ function invalidatePagesCache() {
158
+ cache = null;
159
+ }
160
+
161
+ // src/server/api-router.ts
162
+ var cache2 = null;
163
+ function invalidateApiCache() {
164
+ cache2 = null;
165
+ }
166
+
167
+ // src/vite/codegen/context.ts
168
+ function generateContext() {
169
+ return `
170
+ export {RouterContext} from '@devlusoft/devix/runtime/context'
171
+ `;
172
+ }
173
+
174
+ // src/vite/index.ts
175
+ var __dirname = dirname(fileURLToPath(import.meta.url));
176
+ var VIRTUAL_ENTRY_CLIENT = "virtual:devix/entry-client";
177
+ var VIRTUAL_CLIENT_ROUTES = "virtual:devix/client-routes";
178
+ var VIRTUAL_RENDER = "virtual:devix/render";
179
+ var VIRTUAL_API = "virtual:devix/api";
180
+ var VIRTUAL_CONTEXT = "virtual:devix/context";
181
+ function devix(config2) {
182
+ const appDir = config2.appDir ?? "app";
183
+ const pagesDir = `${appDir}/pages`;
184
+ const cssUrls = (config2.css ?? []).map((u) => u.startsWith("/") ? u : `/${u.replace(/^\.\//, "")}`);
185
+ const renderPath = resolve(__dirname, "../server/render.js").replace(/\\/g, "/");
186
+ const apiPath = resolve(__dirname, "../server/api.js").replace(/\\/g, "/");
187
+ const matcherPath = resolve(__dirname, "../runtime/client-router.js").replace(/\\/g, "/");
188
+ const virtualPlugin = {
189
+ name: "devix",
190
+ enforce: "pre",
191
+ resolveId(id) {
192
+ if (id === VIRTUAL_ENTRY_CLIENT) return `\0${VIRTUAL_ENTRY_CLIENT}`;
193
+ if (id === VIRTUAL_CLIENT_ROUTES) return `\0${VIRTUAL_CLIENT_ROUTES}`;
194
+ if (id === VIRTUAL_RENDER) return `\0${VIRTUAL_RENDER}`;
195
+ if (id === VIRTUAL_API) return `\0${VIRTUAL_API}`;
196
+ if (id === VIRTUAL_CONTEXT) return `\0${VIRTUAL_CONTEXT}`;
197
+ },
198
+ load(id) {
199
+ if (id === `\0${VIRTUAL_ENTRY_CLIENT}`)
200
+ return generateEntryClient({ cssUrls });
201
+ if (id === `\0${VIRTUAL_CLIENT_ROUTES}`)
202
+ return generateClientRoutes({ pagesDir, matcherPath });
203
+ if (id === `\0${VIRTUAL_RENDER}`)
204
+ return generateRender({ pagesDir, renderPath });
205
+ if (id === `\0${VIRTUAL_API}`)
206
+ return generateApi({ apiPath, appDir });
207
+ if (id === `\0${VIRTUAL_CONTEXT}`)
208
+ return generateContext();
209
+ },
210
+ configureServer(server) {
211
+ server.watcher.on("add", (file) => {
212
+ if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache();
213
+ if (file.includes(`${appDir}/api`)) invalidateApiCache();
214
+ });
215
+ server.watcher.on("unlink", (file) => {
216
+ if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache();
217
+ if (file.includes(`${appDir}/api`)) invalidateApiCache();
218
+ });
219
+ }
220
+ };
221
+ const base = {
222
+ plugins: [react(), virtualPlugin],
223
+ ssr: { noExternal: ["@devlusoft/devix"] },
224
+ ...config2.envPrefix ? { envPrefix: config2.envPrefix } : {}
225
+ };
226
+ return mergeConfig(base, config2.vite ?? {});
227
+ }
228
+
229
+ // src/server/routes.ts
230
+ function registerApiRoutes(app2, { apiModule: apiModule2, renderModule: renderModule2, loaderTimeout }) {
231
+ app2.all("/api/*", async (c) => {
232
+ try {
233
+ return await apiModule2.handleApiRequest(c.req.url, c.req.raw);
234
+ } catch (e) {
235
+ console.error(e);
236
+ return c.json({ error: "internal error" }, 500);
237
+ }
238
+ });
239
+ app2.get("/_data/*", async (c) => {
240
+ try {
241
+ const { pathname, search } = new URL(c.req.url, "http://localhost");
242
+ const url = pathname.replace(/^\/_data/, "") + search;
243
+ const data = await renderModule2.runLoader(url, c.req.raw, { loaderTimeout });
244
+ return c.json(data);
245
+ } catch (e) {
246
+ console.error(e);
247
+ return c.json({ error: "internal error" }, 500);
248
+ }
249
+ });
250
+ }
251
+
252
+ // src/utils/banner.ts
253
+ import pc from "picocolors";
254
+ import { networkInterfaces } from "node:os";
255
+ import { createRequire } from "node:module";
256
+ function getNetworkUrl(port2) {
257
+ const nets = networkInterfaces();
258
+ for (const interfaces of Object.values(nets)) {
259
+ for (const net of interfaces ?? []) {
260
+ if (net.family === "IPv4" && !net.internal) {
261
+ return `http://${net.address}:${port2}/`;
262
+ }
263
+ }
264
+ }
265
+ return null;
266
+ }
267
+ function printDevBanner(port2) {
268
+ const req = createRequire(import.meta.url);
269
+ const version = req("../../package.json").version;
270
+ const networkUrl = getNetworkUrl(port2);
271
+ console.log();
272
+ console.log(` ${pc.bold(pc.yellow("devix"))} ${pc.dim(`v${version}`)}`);
273
+ console.log();
274
+ console.log(` ${pc.green("\u279C")} ${pc.bold("Local:")} ${pc.cyan(`http://localhost:${port2}/`)}`);
275
+ if (networkUrl) {
276
+ console.log(` ${pc.green("\u279C")} ${pc.bold("Network:")} ${pc.cyan(networkUrl)}`);
277
+ } else {
278
+ console.log(` ${pc.green("\u279C")} ${pc.bold("Network:")} ${pc.dim("use --host to expose")}`);
279
+ }
280
+ console.log();
281
+ }
282
+
283
+ // src/server/collect-css.ts
284
+ async function collectCss(vite2) {
285
+ const cssUrls = /* @__PURE__ */ new Set();
286
+ for (const [, mod] of vite2.moduleGraph.idToModuleMap) {
287
+ if (!mod.id) continue;
288
+ if (mod.id.endsWith(".css") || mod.id.includes(".css?")) {
289
+ cssUrls.add(mod.url);
290
+ }
291
+ }
292
+ return [...cssUrls];
293
+ }
294
+
295
+ // src/utils/duration.ts
296
+ function parseDuration(value) {
297
+ if (typeof value === "number") return value;
298
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);
299
+ if (!match) throw new Error(`[devix] Invalid duration: "${value}". Use a number (ms) or a string like "5s", "2m", "500ms".`);
300
+ const n = parseFloat(match[1]);
301
+ switch (match[2]) {
302
+ case "h":
303
+ return n * 36e5;
304
+ case "m":
305
+ return n * 6e4;
306
+ case "s":
307
+ return n * 1e3;
308
+ case "ms":
309
+ default:
310
+ return n;
311
+ }
312
+ }
313
+
314
+ // src/cli/dev.ts
315
+ var VIRTUAL_RENDER2 = "virtual:devix/render";
316
+ var VIRTUAL_API2 = "virtual:devix/api";
317
+ var config = (await import(`${process.cwd()}/devix.config.ts`)).default;
318
+ var port = Number(process.env.PORT) || config.port || 3e3;
319
+ var host = typeof config.host === "string" ? config.host : config.host ? "0.0.0.0" : "localhost";
320
+ var vite = await createViteServer({
321
+ ...devix(config),
322
+ configFile: false,
323
+ appType: "custom",
324
+ server: { middlewareMode: true }
325
+ });
326
+ var renderModule = {
327
+ render: async (...args) => (await vite.ssrLoadModule(VIRTUAL_RENDER2)).render(...args),
328
+ runLoader: async (...args) => (await vite.ssrLoadModule(VIRTUAL_RENDER2)).runLoader(...args)
329
+ };
330
+ var apiModule = {
331
+ handleApiRequest: async (...args) => (await vite.ssrLoadModule(VIRTUAL_API2)).handleApiRequest(...args)
332
+ };
333
+ var app = new Hono();
334
+ registerApiRoutes(app, { renderModule, apiModule });
335
+ app.get("*", async (c) => {
336
+ try {
337
+ const { html, statusCode, headers } = await renderModule.render(c.req.url, c.req.raw, { loaderTimeout: parseDuration(config.loaderTimeout ?? 1e4) });
338
+ const cssUrls = await collectCss(vite);
339
+ const cssLinks = cssUrls.map((url) => `<link rel="stylesheet" href="${url}">`).join("\n");
340
+ const htmlWithCss = cssLinks ? html.replace("</head>", `${cssLinks}
341
+ </head>`) : html;
342
+ const transformed = await vite.transformIndexHtml(c.req.url, `<!DOCTYPE html>${htmlWithCss}`);
343
+ const res = c.html(transformed, statusCode);
344
+ for (const [key, value] of Object.entries(headers)) {
345
+ res.headers.set(key, value);
346
+ }
347
+ return res;
348
+ } catch (e) {
349
+ vite.ssrFixStacktrace(e);
350
+ console.error(e);
351
+ return c.text("Internal Server Error", 500);
352
+ }
353
+ });
354
+ var honoHandler = getRequestListener(app.fetch);
355
+ createServer(async (req, res) => {
356
+ await new Promise((resolve2) => vite.middlewares(req, res, resolve2));
357
+ if (!res.writableEnded) await honoHandler(req, res);
358
+ }).listen(port, host, () => {
359
+ printDevBanner(port);
360
+ });
361
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/cli/dev.ts", "../../src/vite/index.ts", "../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/server/pages-router.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/context.ts", "../../src/server/routes.ts", "../../src/utils/banner.ts", "../../src/server/collect-css.ts", "../../src/utils/duration.ts"],
4
+ "sourcesContent": ["import {createServer} from 'node:http'\nimport {createServer as createViteServer} from 'vite'\nimport {getRequestListener} from '@hono/node-server'\nimport {Hono} from 'hono'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {registerApiRoutes} from '../server/routes'\nimport {printDevBanner} from \"../utils/banner\";\nimport {collectCss} from \"../server/collect-css\";\nimport {parseDuration} from \"../utils/duration\";\n\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst port = Number(process.env.PORT) || config.port || 3000\nconst host = typeof config.host === 'string' ? config.host : config.host ? '0.0.0.0' : 'localhost'\n\nconst vite = await createViteServer({\n ...devix(config),\n configFile: false,\n appType: 'custom',\n server: {middlewareMode: true},\n})\n\nconst renderModule = {\n render: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).render(...args),\n runLoader: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).runLoader(...args),\n}\n\nconst apiModule = {\n handleApiRequest: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_API)).handleApiRequest(...args),\n}\n\nconst app = new Hono()\n\nregisterApiRoutes(app, {renderModule, apiModule})\n\napp.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000)})\n\n const cssUrls = await collectCss(vite)\n const cssLinks = cssUrls.map(url => `<link rel=\"stylesheet\" href=\"${url}\">`).join('\\n')\n\n const htmlWithCss = cssLinks ? html.replace('</head>', `${cssLinks}\\n</head>`) : html\n const transformed = await vite.transformIndexHtml(c.req.url, `<!DOCTYPE html>${htmlWithCss}`)\n\n const res = c.html(transformed, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n vite.ssrFixStacktrace(e as Error)\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n})\n\nconst honoHandler = getRequestListener(app.fetch)\n\ncreateServer(async (req, res) => {\n await new Promise<void>(resolve => vite.middlewares(req, res, resolve))\n if (!res.writableEnded) await honoHandler(req, res)\n}).listen(port, host, () => {\n printDevBanner(port)\n})\n\nexport {}", "import {UserConfig, Plugin, mergeConfig} from 'vite'\nimport type {DevixConfig} from '../config'\nimport react from '@vitejs/plugin-react'\nimport {fileURLToPath} from 'node:url'\nimport {dirname, resolve} from 'node:path'\nimport {generateEntryClient} from './codegen/entry-client'\nimport {generateClientRoutes} from './codegen/client-routes'\nimport {generateRender} from './codegen/render'\nimport {generateApi} from './codegen/api'\nimport {invalidatePagesCache} from \"../server/pages-router\";\nimport {invalidateApiCache} from \"../server/api-router\";\nimport {generateContext} from \"./codegen/context\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\nexport function devix(config: DevixConfig): UserConfig {\n const appDir = config.appDir ?? 'app'\n const pagesDir = `${appDir}/pages`\n const cssUrls = (config.css ?? []).map(u => u.startsWith('/') ? u : `/${u.replace(/^\\.\\//, '')}`)\n\n const renderPath = resolve(__dirname, '../server/render.js').replace(/\\\\/g, '/')\n const apiPath = resolve(__dirname, '../server/api.js').replace(/\\\\/g, '/')\n const matcherPath = resolve(__dirname, '../runtime/client-router.js').replace(/\\\\/g, '/')\n\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({cssUrls})\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({pagesDir, matcherPath})\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({pagesDir, renderPath})\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({apiPath, appDir})\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n configureServer(server) {\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) invalidateApiCache()\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) invalidateApiCache()\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n ssr: {noExternal: ['@devlusoft/devix']},\n ...(config.envPrefix ? {envPrefix: config.envPrefix} : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\n}", "interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({cssUrls}: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}", "interface ClientRoutesOptions {\n pagesDir: string\n matcherPath: string\n}\n\nexport function generateClientRoutes({pagesDir, matcherPath}: ClientRoutesOptions) {\n return `\nimport React from 'react'\nimport { createMatcher } from '${matcherPath}'\nconst pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')\nconst errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')\n\nexport const matchClientRoute = createMatcher(pageFiles, layoutFiles)\n\nexport async function loadErrorPage() {\n const key = Object.keys(errorFiles)[0]\n if (!key) return null\n const mod = await errorFiles[key]()\n return mod?.default ?? null\n}\n\nexport function getDefaultErrorPage() {\n return function DefaultError({ statusCode, message }) {\n return React.createElement('main', {\n style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column', \n alignItems: 'center', justifyContent: 'center', gap: '8px',\n fontFamily: 'system-ui, sans-serif' }\n },\n React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),\n React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),\n )\n }\n}\n`\n}", "interface RenderOptions {\n pagesDir: string\n renderPath: string\n}\n\nexport function generateRender({pagesDir, renderPath}: RenderOptions): string {\n return `\nimport { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'\n\nconst _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')\n\nconst _glob = {\n pages: _pages,\n layouts: _layouts,\n pagesDir: '/${pagesDir}',\n}\n\nexport function render(url, request, options) {\n return _render(url, request, _glob, options)\n}\n\nexport function runLoader(url, request, options) {\n return _runLoader(url, request, _glob, options)\n}\n\nexport function getStaticRoutes() {\n return _getStaticRoutes(_glob)\n}\n`\n}\n", "interface ApiOptions {\n apiPath: string\n appDir: string\n}\n\nexport function generateApi({apiPath, appDir}: ApiOptions): string {\n return `\nimport { handleApiRequest as _handleApiRequest } from '${apiPath}'\n\nconst _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])\nconst _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')\n\nconst _glob = {\n routes: _routes,\n middlewares: _middlewares,\n apiDir: '/${appDir}/api',\n}\n\nexport function handleApiRequest(url, request) {\n return _handleApiRequest(url, request, _glob)\n}\n`\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nfunction keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import pc from 'picocolors'\nimport {networkInterfaces} from 'node:os'\nimport {createRequire} from 'node:module'\n\nfunction getNetworkUrl(port: number): string | null {\n const nets = networkInterfaces()\n for (const interfaces of Object.values(nets)) {\n for (const net of interfaces ?? []) {\n if (net.family === 'IPv4' && !net.internal) {\n return `http://${net.address}:${port}/`\n }\n }\n }\n return null\n}\n\nexport function printDevBanner(port: number) {\n const req = createRequire(import.meta.url)\n const version = req('../../package.json').version\n const networkUrl = getNetworkUrl(port)\n\n console.log()\n console.log(` ${pc.bold(pc.yellow('devix'))} ${pc.dim(`v${version}`)}`)\n console.log()\n console.log(` ${pc.green('\u279C')} ${pc.bold('Local:')} ${pc.cyan(`http://localhost:${port}/`)}`)\n if (networkUrl) {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.cyan(networkUrl)}`)\n } else {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.dim('use --host to expose')}`)\n }\n console.log()\n}", "import type {ViteDevServer} from 'vite'\n\nexport async function collectCss(vite: ViteDevServer): Promise<string[]> {\n const cssUrls = new Set<string>()\n\n for (const [, mod] of vite.moduleGraph.idToModuleMap) {\n if (!mod.id) continue\n if (mod.id.endsWith('.css') || mod.id.includes('.css?')) {\n cssUrls.add(mod.url)\n }\n }\n\n return [...cssUrls]\n}", "export function parseDuration(value: number | string): number {\n if (typeof value === 'number') return value\n const match = value.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/)\n if (!match) throw new Error(`[devix] Invalid duration: \"${value}\". Use a number (ms) or a string like \"5s\", \"2m\", \"500ms\".`)\n const n = parseFloat(match[1])\n switch (match[2]) {\n case 'h': return n * 3_600_000\n case 'm': return n * 60_000\n case 's': return n * 1_000\n case 'ms':\n default: return n\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["cache", "config", "app", "apiModule", "renderModule", "port", "vite", "VIRTUAL_RENDER", "VIRTUAL_API", "resolve"]
7
+ }
@@ -0,0 +1 @@
1
+ export {};