@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.
Files changed (62) hide show
  1. package/dist/adapter.cjs +748 -0
  2. package/dist/adapter.mjs +717 -0
  3. package/dist/adapters/entry.cjs +122 -0
  4. package/dist/adapters/entry.mjs +95 -0
  5. package/dist/adapters/platforms.cjs +311 -0
  6. package/dist/adapters/platforms.mjs +284 -0
  7. package/dist/api-RH6E5UTH.mjs +114 -0
  8. package/dist/api.cjs +145 -0
  9. package/dist/api.mjs +116 -0
  10. package/dist/commands/api-23MJFSYL.mjs +17 -0
  11. package/dist/commands/api-4IYNQRKG.mjs +16 -0
  12. package/dist/commands/api-RH6E5UTH.mjs +114 -0
  13. package/dist/commands/build.cjs +870 -0
  14. package/dist/commands/build.mjs +710 -0
  15. package/dist/commands/chunk-NS5GR2GX.mjs +115 -0
  16. package/dist/commands/chunk-OCPCK4ZJ.mjs +117 -0
  17. package/dist/commands/dev.cjs +663 -0
  18. package/dist/commands/dev.mjs +505 -0
  19. package/dist/commands/index.cjs +1138 -0
  20. package/dist/commands/index.mjs +975 -0
  21. package/dist/commands/prerender.cjs +402 -0
  22. package/dist/commands/prerender.mjs +375 -0
  23. package/dist/commands/start.cjs +461 -0
  24. package/dist/commands/start.mjs +426 -0
  25. package/dist/config.cjs +144 -0
  26. package/dist/config.mjs +108 -0
  27. package/dist/di.cjs +200 -0
  28. package/dist/di.mjs +169 -0
  29. package/dist/document.cjs +115 -0
  30. package/dist/document.mjs +86 -0
  31. package/dist/generated-api.cjs +43 -0
  32. package/dist/generated-api.mjs +18 -0
  33. package/dist/generated-server-fns.cjs +43 -0
  34. package/dist/generated-server-fns.mjs +18 -0
  35. package/dist/handler-core.cjs +211 -0
  36. package/dist/handler-core.mjs +185 -0
  37. package/dist/handler.cjs +181 -0
  38. package/dist/handler.mjs +150 -0
  39. package/dist/head.cjs +25 -0
  40. package/dist/head.mjs +4 -0
  41. package/dist/image.cjs +146 -0
  42. package/dist/image.mjs +120 -0
  43. package/dist/index.cjs +1036 -0
  44. package/dist/index.mjs +968 -0
  45. package/dist/interceptors.cjs +71 -0
  46. package/dist/interceptors.mjs +42 -0
  47. package/dist/internal.cjs +388 -0
  48. package/dist/internal.mjs +218 -0
  49. package/dist/middleware.cjs +58 -0
  50. package/dist/middleware.mjs +31 -0
  51. package/dist/preload.cjs +42 -0
  52. package/dist/preload.mjs +18 -0
  53. package/dist/router.cjs +25 -0
  54. package/dist/router.mjs +4 -0
  55. package/dist/server-fn-setup.cjs +46 -0
  56. package/dist/server-fn-setup.mjs +22 -0
  57. package/dist/server-fn.cjs +109 -0
  58. package/dist/server-fn.mjs +79 -0
  59. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  60. package/dist/ui.cjs +123 -0
  61. package/dist/ui.mjs +93 -0
  62. package/package.json +45 -25
@@ -0,0 +1,150 @@
1
+ // src/handler.ts
2
+ import { createServer as createHttpServer } from "node:http";
3
+ import { stat } from "node:fs/promises";
4
+ import { createReadStream } from "node:fs";
5
+ import { Readable } from "node:stream";
6
+ import { join, extname } from "node:path";
7
+ function streamDocument(head, body, tail) {
8
+ const enc = new TextEncoder();
9
+ const stream = new ReadableStream({
10
+ async start(controller) {
11
+ try {
12
+ controller.enqueue(enc.encode(head));
13
+ const reader = body.getReader();
14
+ for (; ; ) {
15
+ const { done, value } = await reader.read();
16
+ if (done) break;
17
+ controller.enqueue(value);
18
+ }
19
+ controller.enqueue(enc.encode(tail));
20
+ controller.close();
21
+ } catch (err) {
22
+ controller.error(err);
23
+ }
24
+ }
25
+ });
26
+ return new Response(stream, {
27
+ status: 200,
28
+ headers: { "content-type": "text/html; charset=utf-8" }
29
+ });
30
+ }
31
+ function createRequestHandler(render) {
32
+ return async (request) => {
33
+ const url = new URL(request.url);
34
+ try {
35
+ const html = await render(url.pathname + url.search, request);
36
+ return new Response(html, {
37
+ status: 200,
38
+ headers: { "content-type": "text/html; charset=utf-8" }
39
+ });
40
+ } catch (e) {
41
+ return new Response(String(e?.stack || e), {
42
+ status: 500,
43
+ headers: { "content-type": "text/plain; charset=utf-8" }
44
+ });
45
+ }
46
+ };
47
+ }
48
+ function nodeToRequest(req) {
49
+ const host = req.headers.host ?? "localhost";
50
+ const url = `http://${host}${req.url ?? "/"}`;
51
+ const headers = new Headers();
52
+ for (const [k, v] of Object.entries(req.headers)) {
53
+ if (Array.isArray(v)) v.forEach((x) => headers.append(k, x));
54
+ else if (v != null) headers.set(k, v);
55
+ }
56
+ const method = req.method ?? "GET";
57
+ const init = { method, headers };
58
+ if (method !== "GET" && method !== "HEAD") {
59
+ init.body = req;
60
+ init.duplex = "half";
61
+ }
62
+ return new Request(url, init);
63
+ }
64
+ async function sendResponse(res, response) {
65
+ res.statusCode = response.status;
66
+ response.headers.forEach((value, key) => res.setHeader(key, value));
67
+ const body = response.body;
68
+ if (!body) {
69
+ res.end(await response.text().catch(() => ""));
70
+ return;
71
+ }
72
+ const reader = body.getReader();
73
+ try {
74
+ for (; ; ) {
75
+ const { done, value } = await reader.read();
76
+ if (done) break;
77
+ res.write(value);
78
+ }
79
+ } finally {
80
+ res.end();
81
+ }
82
+ }
83
+ function toNodeHandler(handler) {
84
+ return async (req, res) => {
85
+ const response = await handler(nodeToRequest(req));
86
+ await sendResponse(res, response);
87
+ };
88
+ }
89
+ function serveNode(handler, opts = {}) {
90
+ const port = opts.port ?? 3e3;
91
+ const node = toNodeHandler(handler);
92
+ const server = createHttpServer((req, res) => {
93
+ node(req, res).catch((e) => {
94
+ res.statusCode = 500;
95
+ res.end(String(e?.stack || e));
96
+ });
97
+ });
98
+ server.listen(
99
+ port,
100
+ () => opts.onListen ? opts.onListen(port) : console.log(` fluixi → http://localhost:${port}`)
101
+ );
102
+ return server;
103
+ }
104
+ var MIME = {
105
+ ".js": "text/javascript",
106
+ ".mjs": "text/javascript",
107
+ ".css": "text/css",
108
+ ".html": "text/html",
109
+ ".json": "application/json",
110
+ ".svg": "image/svg+xml",
111
+ ".png": "image/png",
112
+ ".jpg": "image/jpeg",
113
+ ".jpeg": "image/jpeg",
114
+ ".webp": "image/webp",
115
+ ".ico": "image/x-icon",
116
+ ".woff": "font/woff",
117
+ ".woff2": "font/woff2",
118
+ ".map": "application/json"
119
+ };
120
+ function withStaticFiles(handler, dir) {
121
+ return async (request) => {
122
+ const { pathname } = new URL(request.url);
123
+ if (pathname !== "/" && extname(pathname)) {
124
+ const file = join(dir, decodeURIComponent(pathname));
125
+ try {
126
+ const s = await stat(file);
127
+ if (s.isFile()) {
128
+ const body = Readable.toWeb(createReadStream(file));
129
+ return new Response(body, {
130
+ headers: {
131
+ "content-type": MIME[extname(file).toLowerCase()] ?? "application/octet-stream",
132
+ "content-length": String(s.size)
133
+ }
134
+ });
135
+ }
136
+ } catch {
137
+ }
138
+ }
139
+ return handler(request);
140
+ };
141
+ }
142
+ export {
143
+ createRequestHandler,
144
+ nodeToRequest,
145
+ sendResponse,
146
+ serveNode,
147
+ streamDocument,
148
+ toNodeHandler,
149
+ withStaticFiles
150
+ };
package/dist/head.cjs ADDED
@@ -0,0 +1,25 @@
1
+ /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
16
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
17
+
18
+ // src/head.ts
19
+ var head_exports = {};
20
+ module.exports = __toCommonJS(head_exports);
21
+ __reExport(head_exports, require("@fluixi/head"), module.exports);
22
+ // Annotate the CommonJS export names for ESM import in node:
23
+ 0 && (module.exports = {
24
+ ...require("@fluixi/head")
25
+ });
package/dist/head.mjs ADDED
@@ -0,0 +1,4 @@
1
+ /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+
3
+ // src/head.ts
4
+ export * from "@fluixi/head";
package/dist/image.cjs ADDED
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/image.ts
21
+ var image_exports = {};
22
+ __export(image_exports, {
23
+ createImageHandler: () => createImageHandler,
24
+ imageLoader: () => imageLoader
25
+ });
26
+ module.exports = __toCommonJS(image_exports);
27
+ var import_promises = require("node:fs/promises");
28
+ var import_node_path = require("node:path");
29
+ var DEFAULT_SIZES = [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];
30
+ var MIME = {
31
+ ".jpg": "image/jpeg",
32
+ ".jpeg": "image/jpeg",
33
+ ".png": "image/png",
34
+ ".webp": "image/webp",
35
+ ".avif": "image/avif",
36
+ ".gif": "image/gif",
37
+ ".svg": "image/svg+xml"
38
+ };
39
+ var sharpModule;
40
+ async function loadSharp() {
41
+ if (sharpModule !== void 0) return sharpModule;
42
+ try {
43
+ const name = "sharp";
44
+ sharpModule = (await import(
45
+ /* @vite-ignore */
46
+ name
47
+ )).default;
48
+ } catch {
49
+ sharpModule = null;
50
+ }
51
+ return sharpModule;
52
+ }
53
+ var defaultTransform = async (input, { width, quality, format }) => {
54
+ const sharp = await loadSharp();
55
+ if (!sharp) return null;
56
+ const pipe = sharp(input).rotate().resize({ width, withoutEnlargement: true });
57
+ if (format === "avif") return { data: new Uint8Array(await pipe.avif({ quality }).toBuffer()), contentType: "image/avif" };
58
+ if (format === "webp") return { data: new Uint8Array(await pipe.webp({ quality }).toBuffer()), contentType: "image/webp" };
59
+ if (format === "png") return { data: new Uint8Array(await pipe.png().toBuffer()), contentType: "image/png" };
60
+ return { data: new Uint8Array(await pipe.jpeg({ quality, mozjpeg: true }).toBuffer()), contentType: "image/jpeg" };
61
+ };
62
+ function imageResponse(body, contentType, maxAge) {
63
+ return new Response(body, {
64
+ headers: {
65
+ "content-type": contentType,
66
+ "cache-control": `public, max-age=${maxAge}, immutable`,
67
+ vary: "Accept"
68
+ }
69
+ });
70
+ }
71
+ function createImageHandler(options = {}) {
72
+ const root = (0, import_node_path.resolve)(options.root ?? (0, import_node_path.join)(process.cwd(), "public"));
73
+ const domains = new Set((options.domains ?? []).map((d) => d.toLowerCase()));
74
+ const sizes = options.sizes ?? DEFAULT_SIZES;
75
+ const maxQuality = options.quality ?? 80;
76
+ const maxAge = options.cacheMaxAge ?? 60 * 60 * 24 * 365;
77
+ const transform = options.transform ?? defaultTransform;
78
+ const cacheMax = options.cache === false ? 0 : typeof options.cache === "number" ? options.cache : 100;
79
+ const cache = /* @__PURE__ */ new Map();
80
+ return async (request) => {
81
+ const url = new URL(request.url);
82
+ const src = url.searchParams.get("url") ?? url.searchParams.get("src");
83
+ const width = Number(url.searchParams.get("w"));
84
+ const quality = Math.min(Math.max(Number(url.searchParams.get("q")) || maxQuality, 1), 100);
85
+ if (!src) return new Response('missing "url"', { status: 400 });
86
+ if (!Number.isInteger(width) || !sizes.includes(width)) return new Response('invalid "w"', { status: 400 });
87
+ const accept = request.headers.get("accept") ?? "";
88
+ const format = accept.includes("image/avif") ? "avif" : accept.includes("image/webp") ? "webp" : "original";
89
+ const key = `${src}|${width}|${quality}|${format}`;
90
+ const hit = cache.get(key);
91
+ if (hit) return imageResponse(hit.body, hit.contentType, maxAge);
92
+ let input;
93
+ let sourceType;
94
+ if (/^https?:\/\//i.test(src)) {
95
+ let host;
96
+ try {
97
+ host = new URL(src).hostname.toLowerCase();
98
+ } catch {
99
+ return new Response("bad url", { status: 400 });
100
+ }
101
+ if (!domains.has(host)) return new Response("domain not allowed", { status: 403 });
102
+ const res = await fetch(src);
103
+ if (!res.ok) return new Response("upstream error", { status: 502 });
104
+ input = new Uint8Array(await res.arrayBuffer());
105
+ sourceType = res.headers.get("content-type") ?? "application/octet-stream";
106
+ } else {
107
+ const filePath = (0, import_node_path.resolve)(root, src.startsWith("/") ? src.slice(1) : src);
108
+ if (filePath !== root && !filePath.startsWith(root + import_node_path.sep)) return new Response("forbidden", { status: 403 });
109
+ try {
110
+ input = new Uint8Array(await (0, import_promises.readFile)(filePath));
111
+ } catch {
112
+ return new Response("not found", { status: 404 });
113
+ }
114
+ sourceType = MIME[(0, import_node_path.extname)(filePath).toLowerCase()] ?? "application/octet-stream";
115
+ }
116
+ if (sourceType === "image/svg+xml" || sourceType === "image/gif") {
117
+ return imageResponse(input, sourceType, maxAge);
118
+ }
119
+ let out = null;
120
+ try {
121
+ out = await transform(input, { width, quality, format, contentType: sourceType });
122
+ } catch {
123
+ out = null;
124
+ }
125
+ const body = out?.data ?? input;
126
+ const contentType = out?.contentType ?? sourceType;
127
+ if (cacheMax > 0) {
128
+ if (cache.size >= cacheMax) cache.delete(cache.keys().next().value);
129
+ cache.set(key, { body, contentType });
130
+ }
131
+ return imageResponse(body, contentType, maxAge);
132
+ };
133
+ }
134
+ function imageLoader(options = {}) {
135
+ const path = options.path ?? "/api/image";
136
+ return ({ src, width, quality }) => {
137
+ const params = new URLSearchParams({ url: src, w: String(width) });
138
+ if (quality != null) params.set("q", String(quality));
139
+ return `${path}?${params.toString()}`;
140
+ };
141
+ }
142
+ // Annotate the CommonJS export names for ESM import in node:
143
+ 0 && (module.exports = {
144
+ createImageHandler,
145
+ imageLoader
146
+ });
package/dist/image.mjs ADDED
@@ -0,0 +1,120 @@
1
+ // src/image.ts
2
+ import { readFile } from "node:fs/promises";
3
+ import { resolve as resolvePath, join, extname, sep } from "node:path";
4
+ var DEFAULT_SIZES = [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840];
5
+ var MIME = {
6
+ ".jpg": "image/jpeg",
7
+ ".jpeg": "image/jpeg",
8
+ ".png": "image/png",
9
+ ".webp": "image/webp",
10
+ ".avif": "image/avif",
11
+ ".gif": "image/gif",
12
+ ".svg": "image/svg+xml"
13
+ };
14
+ var sharpModule;
15
+ async function loadSharp() {
16
+ if (sharpModule !== void 0) return sharpModule;
17
+ try {
18
+ const name = "sharp";
19
+ sharpModule = (await import(
20
+ /* @vite-ignore */
21
+ name
22
+ )).default;
23
+ } catch {
24
+ sharpModule = null;
25
+ }
26
+ return sharpModule;
27
+ }
28
+ var defaultTransform = async (input, { width, quality, format }) => {
29
+ const sharp = await loadSharp();
30
+ if (!sharp) return null;
31
+ const pipe = sharp(input).rotate().resize({ width, withoutEnlargement: true });
32
+ if (format === "avif") return { data: new Uint8Array(await pipe.avif({ quality }).toBuffer()), contentType: "image/avif" };
33
+ if (format === "webp") return { data: new Uint8Array(await pipe.webp({ quality }).toBuffer()), contentType: "image/webp" };
34
+ if (format === "png") return { data: new Uint8Array(await pipe.png().toBuffer()), contentType: "image/png" };
35
+ return { data: new Uint8Array(await pipe.jpeg({ quality, mozjpeg: true }).toBuffer()), contentType: "image/jpeg" };
36
+ };
37
+ function imageResponse(body, contentType, maxAge) {
38
+ return new Response(body, {
39
+ headers: {
40
+ "content-type": contentType,
41
+ "cache-control": `public, max-age=${maxAge}, immutable`,
42
+ vary: "Accept"
43
+ }
44
+ });
45
+ }
46
+ function createImageHandler(options = {}) {
47
+ const root = resolvePath(options.root ?? join(process.cwd(), "public"));
48
+ const domains = new Set((options.domains ?? []).map((d) => d.toLowerCase()));
49
+ const sizes = options.sizes ?? DEFAULT_SIZES;
50
+ const maxQuality = options.quality ?? 80;
51
+ const maxAge = options.cacheMaxAge ?? 60 * 60 * 24 * 365;
52
+ const transform = options.transform ?? defaultTransform;
53
+ const cacheMax = options.cache === false ? 0 : typeof options.cache === "number" ? options.cache : 100;
54
+ const cache = /* @__PURE__ */ new Map();
55
+ return async (request) => {
56
+ const url = new URL(request.url);
57
+ const src = url.searchParams.get("url") ?? url.searchParams.get("src");
58
+ const width = Number(url.searchParams.get("w"));
59
+ const quality = Math.min(Math.max(Number(url.searchParams.get("q")) || maxQuality, 1), 100);
60
+ if (!src) return new Response('missing "url"', { status: 400 });
61
+ if (!Number.isInteger(width) || !sizes.includes(width)) return new Response('invalid "w"', { status: 400 });
62
+ const accept = request.headers.get("accept") ?? "";
63
+ const format = accept.includes("image/avif") ? "avif" : accept.includes("image/webp") ? "webp" : "original";
64
+ const key = `${src}|${width}|${quality}|${format}`;
65
+ const hit = cache.get(key);
66
+ if (hit) return imageResponse(hit.body, hit.contentType, maxAge);
67
+ let input;
68
+ let sourceType;
69
+ if (/^https?:\/\//i.test(src)) {
70
+ let host;
71
+ try {
72
+ host = new URL(src).hostname.toLowerCase();
73
+ } catch {
74
+ return new Response("bad url", { status: 400 });
75
+ }
76
+ if (!domains.has(host)) return new Response("domain not allowed", { status: 403 });
77
+ const res = await fetch(src);
78
+ if (!res.ok) return new Response("upstream error", { status: 502 });
79
+ input = new Uint8Array(await res.arrayBuffer());
80
+ sourceType = res.headers.get("content-type") ?? "application/octet-stream";
81
+ } else {
82
+ const filePath = resolvePath(root, src.startsWith("/") ? src.slice(1) : src);
83
+ if (filePath !== root && !filePath.startsWith(root + sep)) return new Response("forbidden", { status: 403 });
84
+ try {
85
+ input = new Uint8Array(await readFile(filePath));
86
+ } catch {
87
+ return new Response("not found", { status: 404 });
88
+ }
89
+ sourceType = MIME[extname(filePath).toLowerCase()] ?? "application/octet-stream";
90
+ }
91
+ if (sourceType === "image/svg+xml" || sourceType === "image/gif") {
92
+ return imageResponse(input, sourceType, maxAge);
93
+ }
94
+ let out = null;
95
+ try {
96
+ out = await transform(input, { width, quality, format, contentType: sourceType });
97
+ } catch {
98
+ out = null;
99
+ }
100
+ const body = out?.data ?? input;
101
+ const contentType = out?.contentType ?? sourceType;
102
+ if (cacheMax > 0) {
103
+ if (cache.size >= cacheMax) cache.delete(cache.keys().next().value);
104
+ cache.set(key, { body, contentType });
105
+ }
106
+ return imageResponse(body, contentType, maxAge);
107
+ };
108
+ }
109
+ function imageLoader(options = {}) {
110
+ const path = options.path ?? "/api/image";
111
+ return ({ src, width, quality }) => {
112
+ const params = new URLSearchParams({ url: src, w: String(width) });
113
+ if (quality != null) params.set("q", String(quality));
114
+ return `${path}?${params.toString()}`;
115
+ };
116
+ }
117
+ export {
118
+ createImageHandler,
119
+ imageLoader
120
+ };