@apex-stack/core 0.1.9 → 0.1.11

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.
@@ -0,0 +1,127 @@
1
+ import {
2
+ loadComponents
3
+ } from "./chunk-4VG3CZ6H.js";
4
+ import {
5
+ createApiHandler,
6
+ createMcpHandler,
7
+ loadApiRoutes
8
+ } from "./chunk-DSUIB3JH.js";
9
+ import {
10
+ matchRoute,
11
+ renderIslandsPage,
12
+ renderPage,
13
+ scanPages
14
+ } from "./chunk-PAMD24NK.js";
15
+
16
+ // src/dev/server.ts
17
+ import { createServer as createHttpServer } from "http";
18
+ import { createRequire } from "module";
19
+ import { fileURLToPath } from "url";
20
+ import { apex } from "@apex-stack/vite";
21
+ import {
22
+ createApp,
23
+ defineEventHandler,
24
+ fromNodeMiddleware,
25
+ setResponseHeader,
26
+ setResponseStatus,
27
+ toNodeListener
28
+ } from "h3";
29
+ import { createServer as createViteServer } from "vite";
30
+ async function startDevServer(options) {
31
+ const port = options.port ?? 3e3;
32
+ const pageId = options.pageId ?? "/pages/index.alpine";
33
+ const req = createRequire(import.meta.url);
34
+ const tryResolve = (spec) => {
35
+ try {
36
+ return req.resolve(spec);
37
+ } catch {
38
+ return void 0;
39
+ }
40
+ };
41
+ const alpine = tryResolve("alpinejs");
42
+ const kit = tryResolve("@apex-stack/kit");
43
+ const coreClient = fileURLToPath(new URL("./client.js", import.meta.url));
44
+ const alias = { "@apex-stack/core/client": coreClient };
45
+ if (alpine) alias.alpinejs = alpine;
46
+ if (kit) alias["@apex-stack/kit"] = kit;
47
+ const vite = await createViteServer({
48
+ root: options.root,
49
+ appType: "custom",
50
+ server: { middlewareMode: true, fs: { strict: false } },
51
+ resolve: { alias },
52
+ // User apps depend on `@apex-stack/core`, so the client module imports the runtime
53
+ // from `@apex-stack/core/client` (a re-export) rather than the internal kit package.
54
+ plugins: [apex({ clientRuntime: "@apex-stack/core/client" })],
55
+ optimizeDeps: { include: ["alpinejs"] }
56
+ });
57
+ const app = createApp();
58
+ app.use(fromNodeMiddleware(vite.middlewares));
59
+ const loadEntries = () => loadApiRoutes(options.root, (id) => vite.ssrLoadModule(id));
60
+ app.use("/api", defineEventHandler((event) => loadEntries().then((e) => createApiHandler(e)(event))));
61
+ app.use("/mcp", defineEventHandler((event) => loadEntries().then((e) => createMcpHandler(e)(event))));
62
+ app.use(
63
+ defineEventHandler(async (event) => {
64
+ const url = event.path || "/";
65
+ try {
66
+ const routes = scanPages(options.root);
67
+ const matched = routes.length ? matchRoute(routes, url) : { pageId, params: {} };
68
+ if (!matched) {
69
+ setResponseStatus(event, 404);
70
+ setResponseHeader(event, "Content-Type", "text/html");
71
+ return notFoundPage(url, routes);
72
+ }
73
+ const { registry, css: componentCss } = await loadComponents(
74
+ options.root,
75
+ (id) => vite.ssrLoadModule(id)
76
+ );
77
+ const render = options.islands ? renderIslandsPage : renderPage;
78
+ const html = await render({
79
+ loadModule: (id) => vite.ssrLoadModule(id),
80
+ pageId: matched.pageId,
81
+ params: matched.params,
82
+ url,
83
+ registry,
84
+ componentCss,
85
+ transformHtml: (u, doc) => vite.transformIndexHtml(u, doc)
86
+ });
87
+ setResponseHeader(event, "Content-Type", "text/html");
88
+ return html;
89
+ } catch (err) {
90
+ const error = err;
91
+ vite.ssrFixStacktrace(error);
92
+ setResponseStatus(event, 500);
93
+ setResponseHeader(event, "Content-Type", "text/html");
94
+ return `<pre>${escapeHtml(error.stack ?? error.message)}</pre>`;
95
+ }
96
+ })
97
+ );
98
+ const server = createHttpServer(toNodeListener(app));
99
+ await new Promise((resolve) => server.listen(port, resolve));
100
+ return {
101
+ vite,
102
+ server,
103
+ port,
104
+ close: async () => {
105
+ await vite.close();
106
+ await new Promise(
107
+ (resolve, reject) => server.close((e) => e ? reject(e) : resolve())
108
+ );
109
+ }
110
+ };
111
+ }
112
+ function escapeHtml(s) {
113
+ return s.replace(/[&<>]/g, (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&gt;");
114
+ }
115
+ function notFoundPage(url, routes) {
116
+ const list = routes.map((r) => `<li><code>${escapeHtml(r.pattern)}</code></li>`).join("");
117
+ return `<!DOCTYPE html><html><head><title>404 \u2014 Apex JS</title></head>
118
+ <body style="font-family: system-ui, sans-serif; max-width: 40rem; margin: 3rem auto;">
119
+ <h1>404 \u2014 no route for <code>${escapeHtml(url)}</code></h1>
120
+ <p>Available routes:</p>
121
+ <ul>${list || "<li>(no pages found \u2014 add <code>pages/index.alpine</code>)</li>"}</ul>
122
+ </body></html>`;
123
+ }
124
+
125
+ export {
126
+ startDevServer
127
+ };