@fluixi/start 0.1.0-alpha.73 → 0.1.0-alpha.74
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/dist/adapter.cjs +748 -0
- package/dist/adapter.mjs +717 -0
- package/dist/adapters/entry.cjs +122 -0
- package/dist/adapters/entry.mjs +95 -0
- package/dist/adapters/platforms.cjs +311 -0
- package/dist/adapters/platforms.mjs +284 -0
- package/dist/api-RH6E5UTH.mjs +114 -0
- package/dist/api.cjs +145 -0
- package/dist/api.mjs +116 -0
- package/dist/commands/api-23MJFSYL.mjs +17 -0
- package/dist/commands/api-4IYNQRKG.mjs +16 -0
- package/dist/commands/api-RH6E5UTH.mjs +114 -0
- package/dist/commands/build.cjs +870 -0
- package/dist/commands/build.mjs +710 -0
- package/dist/commands/chunk-NS5GR2GX.mjs +115 -0
- package/dist/commands/chunk-OCPCK4ZJ.mjs +117 -0
- package/dist/commands/dev.cjs +663 -0
- package/dist/commands/dev.mjs +505 -0
- package/dist/commands/index.cjs +1138 -0
- package/dist/commands/index.mjs +975 -0
- package/dist/commands/prerender.cjs +402 -0
- package/dist/commands/prerender.mjs +375 -0
- package/dist/commands/start.cjs +461 -0
- package/dist/commands/start.mjs +426 -0
- package/dist/config.cjs +144 -0
- package/dist/config.mjs +108 -0
- package/dist/di.cjs +200 -0
- package/dist/di.mjs +169 -0
- package/dist/document.cjs +115 -0
- package/dist/document.mjs +86 -0
- package/dist/generated-api.cjs +43 -0
- package/dist/generated-api.mjs +18 -0
- package/dist/generated-server-fns.cjs +43 -0
- package/dist/generated-server-fns.mjs +18 -0
- package/dist/handler-core.cjs +211 -0
- package/dist/handler-core.mjs +185 -0
- package/dist/handler.cjs +181 -0
- package/dist/handler.mjs +150 -0
- package/dist/head.cjs +25 -0
- package/dist/head.mjs +4 -0
- package/dist/image.cjs +146 -0
- package/dist/image.mjs +120 -0
- package/dist/index.cjs +1036 -0
- package/dist/index.mjs +968 -0
- package/dist/interceptors.cjs +71 -0
- package/dist/interceptors.mjs +42 -0
- package/dist/internal.cjs +388 -0
- package/dist/internal.mjs +218 -0
- package/dist/middleware.cjs +58 -0
- package/dist/middleware.mjs +31 -0
- package/dist/preload.cjs +42 -0
- package/dist/preload.mjs +18 -0
- package/dist/router.cjs +25 -0
- package/dist/router.mjs +4 -0
- package/dist/server-fn-setup.cjs +46 -0
- package/dist/server-fn-setup.mjs +22 -0
- package/dist/server-fn.cjs +109 -0
- package/dist/server-fn.mjs +79 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/ui.cjs +123 -0
- package/dist/ui.mjs +93 -0
- package/package.json +45 -25
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/commands/start.ts
|
|
31
|
+
var start_exports = {};
|
|
32
|
+
__export(start_exports, {
|
|
33
|
+
start: () => start
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(start_exports);
|
|
36
|
+
var import_node_path4 = require("node:path");
|
|
37
|
+
|
|
38
|
+
// src/config.ts
|
|
39
|
+
var import_node_path = require("node:path");
|
|
40
|
+
function resolveConfig(config = {}) {
|
|
41
|
+
const root = (0, import_node_path.resolve)(config.root ?? process.cwd());
|
|
42
|
+
return {
|
|
43
|
+
root,
|
|
44
|
+
ssr: config.ssr ?? true,
|
|
45
|
+
port: config.port ?? 3e3,
|
|
46
|
+
serverEntry: config.serverEntry ?? "src/entry-server.ts",
|
|
47
|
+
clientEntry: config.clientEntry ?? "src/entry-client.ts",
|
|
48
|
+
template: config.template ?? "index.html",
|
|
49
|
+
mountId: config.mountId ?? "root",
|
|
50
|
+
routesDir: config.routesDir ?? "src/routes",
|
|
51
|
+
apiDir: config.apiDir ?? "src/api",
|
|
52
|
+
middleware: config.middleware ?? "src/middleware.ts",
|
|
53
|
+
ssrNoExternal: config.ssrNoExternal ?? [],
|
|
54
|
+
resolve: config.resolve ?? [],
|
|
55
|
+
adapter: config.adapter,
|
|
56
|
+
i18n: resolveI18n(config.i18n),
|
|
57
|
+
prerender: resolvePrerender(config.prerender)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function resolvePrerender(prerender) {
|
|
61
|
+
if (!prerender) return false;
|
|
62
|
+
const opts = typeof prerender === "object" ? prerender : {};
|
|
63
|
+
return {
|
|
64
|
+
routes: opts.routes?.length ? opts.routes : ["/"],
|
|
65
|
+
crawl: opts.crawl ?? true
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function resolveI18n(i18n) {
|
|
69
|
+
if (i18n === false) return false;
|
|
70
|
+
const opts = typeof i18n === "object" ? i18n : {};
|
|
71
|
+
return {
|
|
72
|
+
dir: opts.dir ?? "src/i18n",
|
|
73
|
+
defaultLocale: opts.defaultLocale,
|
|
74
|
+
locales: opts.locales
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/document.ts
|
|
79
|
+
var import_head = require("@fluixi/head");
|
|
80
|
+
function injectApp(template, appHtml, mountId = "root") {
|
|
81
|
+
const mount = new RegExp(`<div id=["']${mountId}["']\\s*>\\s*</div>`);
|
|
82
|
+
if (mount.test(template)) {
|
|
83
|
+
return template.replace(mount, `<div id="${mountId}">${appHtml}</div>`);
|
|
84
|
+
}
|
|
85
|
+
if (template.includes("<!--ssr-outlet-->")) {
|
|
86
|
+
return template.replace("<!--ssr-outlet-->", appHtml);
|
|
87
|
+
}
|
|
88
|
+
return template.replace("</body>", `<div id="${mountId}">${appHtml}</div></body>`);
|
|
89
|
+
}
|
|
90
|
+
function splitTemplate(template, mountId = "root") {
|
|
91
|
+
const mount = new RegExp(`<div id=["']${mountId}["']\\s*>\\s*</div>`);
|
|
92
|
+
const m = template.match(mount);
|
|
93
|
+
if (m && m.index !== void 0) {
|
|
94
|
+
return {
|
|
95
|
+
head: template.slice(0, m.index) + `<div id="${mountId}">`,
|
|
96
|
+
tail: `</div>` + template.slice(m.index + m[0].length)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const outlet = template.indexOf("<!--ssr-outlet-->");
|
|
100
|
+
if (outlet !== -1) {
|
|
101
|
+
return {
|
|
102
|
+
head: template.slice(0, outlet),
|
|
103
|
+
tail: template.slice(outlet + "<!--ssr-outlet-->".length)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const body = template.indexOf("</body>");
|
|
107
|
+
if (body !== -1) {
|
|
108
|
+
return {
|
|
109
|
+
head: template.slice(0, body) + `<div id="${mountId}">`,
|
|
110
|
+
tail: `</div>` + template.slice(body)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { head: template, tail: "" };
|
|
114
|
+
}
|
|
115
|
+
function injectPreload(template, files) {
|
|
116
|
+
const tags = files.filter((file) => !template.includes(file)).map(
|
|
117
|
+
(file) => file.endsWith(".css") ? `<link rel="stylesheet" href="${file}">` : (
|
|
118
|
+
// `modulepreload` also fetches the chunk's own static imports.
|
|
119
|
+
`<link rel="modulepreload" href="${file}">`
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
if (tags.length === 0) return template;
|
|
123
|
+
const head = template.indexOf("</head>");
|
|
124
|
+
if (head === -1) return template;
|
|
125
|
+
return template.slice(0, head) + tags.join("") + template.slice(head);
|
|
126
|
+
}
|
|
127
|
+
function setHtmlAttr(html, name, value) {
|
|
128
|
+
const existing = new RegExp(`(<html\\b[^>]*?)\\s${name}="[^"]*"`, "i");
|
|
129
|
+
if (existing.test(html)) return html.replace(existing, `$1 ${name}="${value}"`);
|
|
130
|
+
return html.replace(/<html\b/i, `<html ${name}="${value}"`);
|
|
131
|
+
}
|
|
132
|
+
function injectAppAndHead(template, rendered, mountId = "root") {
|
|
133
|
+
const { head, body } = (0, import_head.extractHeadMarker)(rendered);
|
|
134
|
+
let html = injectApp(template, body, mountId);
|
|
135
|
+
if (head) {
|
|
136
|
+
if (head.headHtml) {
|
|
137
|
+
if (/<title[\s>]/i.test(head.headHtml)) html = html.replace(/<title>[\s\S]*?<\/title>/i, "");
|
|
138
|
+
html = html.replace("</head>", `${head.headHtml}</head>`);
|
|
139
|
+
}
|
|
140
|
+
for (const [k, v] of Object.entries(head.htmlAttrs)) html = setHtmlAttr(html, k, v);
|
|
141
|
+
}
|
|
142
|
+
return html;
|
|
143
|
+
}
|
|
144
|
+
function guardHandler(handler, onError) {
|
|
145
|
+
return async (request) => {
|
|
146
|
+
try {
|
|
147
|
+
return await handler(request);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
onError?.(e);
|
|
150
|
+
return new Response(String(e?.stack || e), {
|
|
151
|
+
status: 500,
|
|
152
|
+
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/internal.ts
|
|
159
|
+
async function loadServerEnv(root, mode) {
|
|
160
|
+
const { loadEnv } = await import("vite");
|
|
161
|
+
const env = loadEnv(mode, root, "");
|
|
162
|
+
for (const [k, v] of Object.entries(env)) {
|
|
163
|
+
if (process.env[k] === void 0) process.env[k] = v;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var _guardsInstalled = false;
|
|
167
|
+
function installCrashGuards() {
|
|
168
|
+
if (_guardsInstalled) return;
|
|
169
|
+
_guardsInstalled = true;
|
|
170
|
+
process.on(
|
|
171
|
+
"unhandledRejection",
|
|
172
|
+
(reason) => console.warn("[fluixi] unhandled rejection (backend likely down) —", reason?.message || reason)
|
|
173
|
+
);
|
|
174
|
+
process.on(
|
|
175
|
+
"uncaughtException",
|
|
176
|
+
(err) => console.warn("[fluixi] uncaught exception —", err?.message || err)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/adapter.ts
|
|
181
|
+
var import_promises2 = require("node:fs/promises");
|
|
182
|
+
var import_node_fs2 = require("node:fs");
|
|
183
|
+
var import_node_path3 = require("node:path");
|
|
184
|
+
var import_node_url = require("node:url");
|
|
185
|
+
|
|
186
|
+
// src/handler.ts
|
|
187
|
+
var import_node_http = require("node:http");
|
|
188
|
+
var import_promises = require("node:fs/promises");
|
|
189
|
+
var import_node_fs = require("node:fs");
|
|
190
|
+
var import_node_stream = require("node:stream");
|
|
191
|
+
var import_node_path2 = require("node:path");
|
|
192
|
+
function streamDocument(head, body, tail) {
|
|
193
|
+
const enc = new TextEncoder();
|
|
194
|
+
const stream = new ReadableStream({
|
|
195
|
+
async start(controller) {
|
|
196
|
+
try {
|
|
197
|
+
controller.enqueue(enc.encode(head));
|
|
198
|
+
const reader = body.getReader();
|
|
199
|
+
for (; ; ) {
|
|
200
|
+
const { done, value } = await reader.read();
|
|
201
|
+
if (done) break;
|
|
202
|
+
controller.enqueue(value);
|
|
203
|
+
}
|
|
204
|
+
controller.enqueue(enc.encode(tail));
|
|
205
|
+
controller.close();
|
|
206
|
+
} catch (err) {
|
|
207
|
+
controller.error(err);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return new Response(stream, {
|
|
212
|
+
status: 200,
|
|
213
|
+
headers: { "content-type": "text/html; charset=utf-8" }
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function createRequestHandler(render) {
|
|
217
|
+
return async (request) => {
|
|
218
|
+
const url = new URL(request.url);
|
|
219
|
+
try {
|
|
220
|
+
const html = await render(url.pathname + url.search, request);
|
|
221
|
+
return new Response(html, {
|
|
222
|
+
status: 200,
|
|
223
|
+
headers: { "content-type": "text/html; charset=utf-8" }
|
|
224
|
+
});
|
|
225
|
+
} catch (e) {
|
|
226
|
+
return new Response(String(e?.stack || e), {
|
|
227
|
+
status: 500,
|
|
228
|
+
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function nodeToRequest(req) {
|
|
234
|
+
const host = req.headers.host ?? "localhost";
|
|
235
|
+
const url = `http://${host}${req.url ?? "/"}`;
|
|
236
|
+
const headers = new Headers();
|
|
237
|
+
for (const [k, v] of Object.entries(req.headers)) {
|
|
238
|
+
if (Array.isArray(v)) v.forEach((x) => headers.append(k, x));
|
|
239
|
+
else if (v != null) headers.set(k, v);
|
|
240
|
+
}
|
|
241
|
+
const method = req.method ?? "GET";
|
|
242
|
+
const init = { method, headers };
|
|
243
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
244
|
+
init.body = req;
|
|
245
|
+
init.duplex = "half";
|
|
246
|
+
}
|
|
247
|
+
return new Request(url, init);
|
|
248
|
+
}
|
|
249
|
+
async function sendResponse(res, response) {
|
|
250
|
+
res.statusCode = response.status;
|
|
251
|
+
response.headers.forEach((value, key) => res.setHeader(key, value));
|
|
252
|
+
const body = response.body;
|
|
253
|
+
if (!body) {
|
|
254
|
+
res.end(await response.text().catch(() => ""));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const reader = body.getReader();
|
|
258
|
+
try {
|
|
259
|
+
for (; ; ) {
|
|
260
|
+
const { done, value } = await reader.read();
|
|
261
|
+
if (done) break;
|
|
262
|
+
res.write(value);
|
|
263
|
+
}
|
|
264
|
+
} finally {
|
|
265
|
+
res.end();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function toNodeHandler(handler) {
|
|
269
|
+
return async (req, res) => {
|
|
270
|
+
const response = await handler(nodeToRequest(req));
|
|
271
|
+
await sendResponse(res, response);
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function serveNode(handler, opts = {}) {
|
|
275
|
+
const port = opts.port ?? 3e3;
|
|
276
|
+
const node = toNodeHandler(handler);
|
|
277
|
+
const server = (0, import_node_http.createServer)((req, res) => {
|
|
278
|
+
node(req, res).catch((e) => {
|
|
279
|
+
res.statusCode = 500;
|
|
280
|
+
res.end(String(e?.stack || e));
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
server.listen(
|
|
284
|
+
port,
|
|
285
|
+
() => opts.onListen ? opts.onListen(port) : console.log(` fluixi → http://localhost:${port}`)
|
|
286
|
+
);
|
|
287
|
+
return server;
|
|
288
|
+
}
|
|
289
|
+
var MIME = {
|
|
290
|
+
".js": "text/javascript",
|
|
291
|
+
".mjs": "text/javascript",
|
|
292
|
+
".css": "text/css",
|
|
293
|
+
".html": "text/html",
|
|
294
|
+
".json": "application/json",
|
|
295
|
+
".svg": "image/svg+xml",
|
|
296
|
+
".png": "image/png",
|
|
297
|
+
".jpg": "image/jpeg",
|
|
298
|
+
".jpeg": "image/jpeg",
|
|
299
|
+
".webp": "image/webp",
|
|
300
|
+
".ico": "image/x-icon",
|
|
301
|
+
".woff": "font/woff",
|
|
302
|
+
".woff2": "font/woff2",
|
|
303
|
+
".map": "application/json"
|
|
304
|
+
};
|
|
305
|
+
function withStaticFiles(handler, dir) {
|
|
306
|
+
return async (request) => {
|
|
307
|
+
const { pathname } = new URL(request.url);
|
|
308
|
+
if (pathname !== "/" && (0, import_node_path2.extname)(pathname)) {
|
|
309
|
+
const file = (0, import_node_path2.join)(dir, decodeURIComponent(pathname));
|
|
310
|
+
try {
|
|
311
|
+
const s = await (0, import_promises.stat)(file);
|
|
312
|
+
if (s.isFile()) {
|
|
313
|
+
const body = import_node_stream.Readable.toWeb((0, import_node_fs.createReadStream)(file));
|
|
314
|
+
return new Response(body, {
|
|
315
|
+
headers: {
|
|
316
|
+
"content-type": MIME[(0, import_node_path2.extname)(file).toLowerCase()] ?? "application/octet-stream",
|
|
317
|
+
"content-length": String(s.size)
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
} catch {
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return handler(request);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// src/middleware.ts
|
|
329
|
+
function normalizeMiddleware(mod) {
|
|
330
|
+
const def = mod?.default ?? mod;
|
|
331
|
+
if (def == null) return [];
|
|
332
|
+
if (Array.isArray(def)) return def.filter((m) => typeof m === "function");
|
|
333
|
+
return typeof def === "function" ? [def] : [];
|
|
334
|
+
}
|
|
335
|
+
function composeMiddleware(middlewares, core) {
|
|
336
|
+
if (middlewares.length === 0) return core;
|
|
337
|
+
return (request) => {
|
|
338
|
+
let lastCalled = -1;
|
|
339
|
+
const dispatch = (i) => {
|
|
340
|
+
if (i <= lastCalled) {
|
|
341
|
+
return Promise.reject(new Error("middleware called next() more than once"));
|
|
342
|
+
}
|
|
343
|
+
lastCalled = i;
|
|
344
|
+
const mw = middlewares[i];
|
|
345
|
+
if (!mw) return Promise.resolve(core(request));
|
|
346
|
+
return Promise.resolve(mw(request, () => dispatch(i + 1)));
|
|
347
|
+
};
|
|
348
|
+
return dispatch(0);
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/handler-core.ts
|
|
353
|
+
function createHandlerFrom({ template, mod, cfg, middleware, preload }) {
|
|
354
|
+
const withPreload = (html, pathname) => preload ? injectPreload(html, preload(pathname)) : html;
|
|
355
|
+
let core;
|
|
356
|
+
if (!cfg.ssr) {
|
|
357
|
+
core = createRequestHandler(async (url) => withPreload(template, url.split("?")[0]));
|
|
358
|
+
} else if (typeof mod.renderStream === "function") {
|
|
359
|
+
core = async (request) => {
|
|
360
|
+
const url = new URL(request.url);
|
|
361
|
+
const { head, tail } = splitTemplate(withPreload(template, url.pathname), cfg.mountId);
|
|
362
|
+
const body = await mod.renderStream(url.pathname + url.search, request);
|
|
363
|
+
return streamDocument(head, body, tail);
|
|
364
|
+
};
|
|
365
|
+
} else {
|
|
366
|
+
const render = mod.render ?? mod.default;
|
|
367
|
+
core = createRequestHandler(
|
|
368
|
+
async (url, request) => (
|
|
369
|
+
// `url` here is `pathname + search`; matching only ever wants the path.
|
|
370
|
+
injectAppAndHead(withPreload(template, url.split("?")[0]), await render(url, request), cfg.mountId)
|
|
371
|
+
)
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
if (typeof mod.handleServerFn === "function" && typeof mod.isServerFnRequest === "function") {
|
|
375
|
+
const render = core;
|
|
376
|
+
core = async (request) => mod.isServerFnRequest(request) ? mod.handleServerFn(request) : render(request);
|
|
377
|
+
}
|
|
378
|
+
if (typeof mod.handleApiRequest === "function" && typeof mod.isApiRequest === "function") {
|
|
379
|
+
const next = core;
|
|
380
|
+
core = async (request) => mod.isApiRequest(request) ? mod.handleApiRequest(request) : next(request);
|
|
381
|
+
}
|
|
382
|
+
if (!middleware) return guardHandler(core);
|
|
383
|
+
return guardHandler(composeMiddleware(normalizeMiddleware(middleware), core));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/preload.ts
|
|
387
|
+
var import_router = require("@fluixi/core/router");
|
|
388
|
+
function createPreloader(assets) {
|
|
389
|
+
const patterns = Object.keys(assets ?? {});
|
|
390
|
+
if (!patterns.length) return () => [];
|
|
391
|
+
const routes = patterns.map((path) => ({ path, meta: { path } }));
|
|
392
|
+
return (pathname) => {
|
|
393
|
+
const matched = (0, import_router.matchRoutes)(routes, pathname)?.matched;
|
|
394
|
+
const leaf = matched?.[matched.length - 1];
|
|
395
|
+
const pattern = leaf?.route.meta?.path;
|
|
396
|
+
return pattern ? assets[pattern] ?? [] : [];
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/adapter.ts
|
|
401
|
+
async function createProdHandler(config = {}) {
|
|
402
|
+
const cfg = resolveConfig(config);
|
|
403
|
+
const clientDir = (0, import_node_path3.resolve)(cfg.root, "dist/client");
|
|
404
|
+
const template = await readTemplate(clientDir, (0, import_node_path3.resolve)(cfg.root, "dist/server"));
|
|
405
|
+
const serverEntry = (0, import_node_path3.resolve)(cfg.root, "dist/server", "entry-server.js");
|
|
406
|
+
const mod = (0, import_node_fs2.existsSync)(serverEntry) ? await import(
|
|
407
|
+
/* @vite-ignore */
|
|
408
|
+
(0, import_node_url.pathToFileURL)(serverEntry).href
|
|
409
|
+
) : {};
|
|
410
|
+
const mwFile = (0, import_node_path3.resolve)(cfg.root, "dist/server", "middleware.js");
|
|
411
|
+
const middleware = (0, import_node_fs2.existsSync)(mwFile) ? await import(
|
|
412
|
+
/* @vite-ignore */
|
|
413
|
+
(0, import_node_url.pathToFileURL)(mwFile).href
|
|
414
|
+
) : void 0;
|
|
415
|
+
return createHandlerFrom({ template, mod, cfg, middleware, preload: await loadPreloader(cfg) });
|
|
416
|
+
}
|
|
417
|
+
async function readTemplate(clientDir, serverDir) {
|
|
418
|
+
const stashed = (0, import_node_path3.join)(serverDir, "template.html");
|
|
419
|
+
return (0, import_promises2.readFile)((0, import_node_fs2.existsSync)(stashed) ? stashed : (0, import_node_path3.join)(clientDir, "index.html"), "utf-8");
|
|
420
|
+
}
|
|
421
|
+
async function loadPreloader(cfg) {
|
|
422
|
+
const file = (0, import_node_path3.resolve)(cfg.root, "dist/server", "route-assets.json");
|
|
423
|
+
if (!(0, import_node_fs2.existsSync)(file)) return void 0;
|
|
424
|
+
try {
|
|
425
|
+
return createPreloader(JSON.parse(await (0, import_promises2.readFile)(file, "utf-8")));
|
|
426
|
+
} catch {
|
|
427
|
+
return void 0;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
var nodeAdapter = {
|
|
431
|
+
name: "node",
|
|
432
|
+
// A Node server runs from the app directory, so node_modules is right there: keep the
|
|
433
|
+
// framework as imports instead of copying it into the bundle.
|
|
434
|
+
bundle: "external",
|
|
435
|
+
async serve({ handler, cfg, clientDir }) {
|
|
436
|
+
serveNode(withStaticFiles(handler, clientDir), {
|
|
437
|
+
port: cfg.port,
|
|
438
|
+
onListen: (p) => console.log(` fluixi start (node) → http://localhost:${p}`)
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
// src/commands/start.ts
|
|
444
|
+
async function start(config = {}) {
|
|
445
|
+
const cfg = resolveConfig(config);
|
|
446
|
+
installCrashGuards();
|
|
447
|
+
await loadServerEnv(cfg.root, "production");
|
|
448
|
+
const clientDir = (0, import_node_path4.resolve)(cfg.root, "dist/client");
|
|
449
|
+
const handler = await createProdHandler(cfg);
|
|
450
|
+
const adapter = cfg.adapter ?? nodeAdapter;
|
|
451
|
+
const served = await adapter.serve({ handler, cfg, clientDir });
|
|
452
|
+
if (served && typeof served === "object" && "fetch" in served) {
|
|
453
|
+
console.log(
|
|
454
|
+
` fluixi: the "${adapter.name}" adapter exports a fetch handler — there is no server to start. Deploy dist/ and let the platform invoke it, or run \`fluixi start\` with a filesystem adapter (nodeAdapter).`
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
459
|
+
0 && (module.exports = {
|
|
460
|
+
start
|
|
461
|
+
});
|