@kbach/react 0.5.20 → 0.5.22
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/vite-plugin.d.mts +1 -1
- package/dist/vite-plugin.d.ts +1 -1
- package/dist/vite-plugin.js +65 -26
- package/dist/vite-plugin.mjs +65 -26
- package/package.json +1 -1
package/dist/vite-plugin.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { F as FrameworkConfig } from './types-CV5vXnSH.mjs';
|
|
|
5
5
|
* @kbach/react/vite
|
|
6
6
|
*
|
|
7
7
|
* Vite plugin — scans source files for Kbach className/kb props and generates CSS.
|
|
8
|
-
* Zero setup: just add kbach() to your plugins array.
|
|
8
|
+
* Zero setup: just add kbach() to your plugins array.
|
|
9
9
|
* Only generates CSS for classes you actually use (like Tailwind).
|
|
10
10
|
*/
|
|
11
11
|
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { F as FrameworkConfig } from './types-CV5vXnSH.js';
|
|
|
5
5
|
* @kbach/react/vite
|
|
6
6
|
*
|
|
7
7
|
* Vite plugin — scans source files for Kbach className/kb props and generates CSS.
|
|
8
|
-
* Zero setup: just add kbach() to your plugins array.
|
|
8
|
+
* Zero setup: just add kbach() to your plugins array.
|
|
9
9
|
* Only generates CSS for classes you actually use (like Tailwind).
|
|
10
10
|
*/
|
|
11
11
|
|
package/dist/vite-plugin.js
CHANGED
|
@@ -3397,7 +3397,6 @@ function kbach(userConfig) {
|
|
|
3397
3397
|
const tokenCSS = /* @__PURE__ */ new Map();
|
|
3398
3398
|
let root = process.cwd();
|
|
3399
3399
|
let server = null;
|
|
3400
|
-
let isDev = false;
|
|
3401
3400
|
function processClassString(classStr) {
|
|
3402
3401
|
let added = false;
|
|
3403
3402
|
for (const token of classStr.split(/\s+/).filter(Boolean)) {
|
|
@@ -3423,42 +3422,82 @@ function kbach(userConfig) {
|
|
|
3423
3422
|
}
|
|
3424
3423
|
return parts.join("\n");
|
|
3425
3424
|
}
|
|
3425
|
+
function injectIntoHtml(html) {
|
|
3426
|
+
const css = getAllCSS();
|
|
3427
|
+
if (!css || html.includes("data-kbach")) return html;
|
|
3428
|
+
return html.replace("</head>", `<style data-kbach>${css}</style></head>`);
|
|
3429
|
+
}
|
|
3426
3430
|
return {
|
|
3427
3431
|
name: "kbach",
|
|
3428
3432
|
enforce: "pre",
|
|
3429
|
-
config(_c, env) {
|
|
3430
|
-
isDev = env.command === "serve";
|
|
3431
|
-
},
|
|
3432
3433
|
configResolved(resolved) {
|
|
3433
3434
|
root = resolved.root;
|
|
3434
3435
|
},
|
|
3435
|
-
configureServer(s) {
|
|
3436
|
-
server = s;
|
|
3437
|
-
},
|
|
3438
3436
|
buildStart() {
|
|
3439
3437
|
for (const dir of ["src", "app", "pages", "components", "views", "layouts"]) {
|
|
3440
3438
|
scanDir((0, import_path.join)(root, dir), (code) => extractFromCode(code));
|
|
3441
3439
|
}
|
|
3442
3440
|
},
|
|
3443
|
-
// ──
|
|
3444
|
-
// React Router v8
|
|
3445
|
-
//
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3441
|
+
// ── DEV: intercept every HTML response and inject <style data-kbach> ──────
|
|
3442
|
+
// React Router v8 uses chunked streaming SSR — </head> comes in an early
|
|
3443
|
+
// res.write() chunk, not res.end(). Buffer all writes, concatenate at end,
|
|
3444
|
+
// inject CSS into the full HTML, then send in one go.
|
|
3445
|
+
configureServer(s) {
|
|
3446
|
+
server = s;
|
|
3447
|
+
s.middlewares.use((req, res, next) => {
|
|
3448
|
+
const url = req.url ?? "";
|
|
3449
|
+
if (/\.(js|ts|jsx|tsx|css|png|jpg|svg|ico|woff2?|ttf|json|map)(\?|$)/.test(url) || url.startsWith("/@") || url.startsWith("/__")) {
|
|
3450
|
+
return next();
|
|
3451
|
+
}
|
|
3452
|
+
const origWrite = res.write.bind(res);
|
|
3453
|
+
const origEnd = res.end.bind(res);
|
|
3454
|
+
const chunks = [];
|
|
3455
|
+
let done = false;
|
|
3456
|
+
res.write = function(chunk, enc, cb) {
|
|
3457
|
+
if (done) return origWrite(chunk, enc, cb);
|
|
3458
|
+
if (chunk != null) {
|
|
3459
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk ?? "")));
|
|
3460
|
+
}
|
|
3461
|
+
if (typeof enc === "function") enc();
|
|
3462
|
+
else if (typeof cb === "function") cb();
|
|
3463
|
+
return true;
|
|
3464
|
+
};
|
|
3465
|
+
res.end = function(chunk, enc, cb) {
|
|
3466
|
+
done = true;
|
|
3467
|
+
if (typeof chunk === "function") {
|
|
3468
|
+
cb = chunk;
|
|
3469
|
+
chunk = null;
|
|
3470
|
+
enc = null;
|
|
3471
|
+
} else if (typeof enc === "function") {
|
|
3472
|
+
cb = enc;
|
|
3473
|
+
enc = null;
|
|
3474
|
+
}
|
|
3475
|
+
if (chunk != null) {
|
|
3476
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk ?? "")));
|
|
3477
|
+
}
|
|
3478
|
+
if (chunks.length > 0) {
|
|
3479
|
+
const html = Buffer.concat(chunks).toString("utf-8");
|
|
3480
|
+
if (html.includes("</head>")) {
|
|
3481
|
+
const injected = injectIntoHtml(html);
|
|
3482
|
+
const buf = Buffer.from(injected, "utf-8");
|
|
3483
|
+
try {
|
|
3484
|
+
res.removeHeader("transfer-encoding");
|
|
3485
|
+
} catch {
|
|
3486
|
+
}
|
|
3487
|
+
try {
|
|
3488
|
+
res.setHeader("content-length", buf.length);
|
|
3489
|
+
} catch {
|
|
3490
|
+
}
|
|
3491
|
+
return origEnd(buf, cb);
|
|
3492
|
+
}
|
|
3493
|
+
return origEnd(Buffer.concat(chunks), enc, cb);
|
|
3494
|
+
}
|
|
3495
|
+
return origEnd(void 0, enc, cb);
|
|
3496
|
+
};
|
|
3497
|
+
next();
|
|
3498
|
+
});
|
|
3458
3499
|
},
|
|
3459
|
-
// ──
|
|
3460
|
-
// In production, Vite extracts CSS from JS into separate .css files.
|
|
3461
|
-
// Appending to the user's CSS ensures it ends up in the final CSS bundle.
|
|
3500
|
+
// ── PROD: append to CSS files so they land in the extracted CSS bundle ────
|
|
3462
3501
|
transform(code, id) {
|
|
3463
3502
|
const cleanId = id.split("?")[0];
|
|
3464
3503
|
if (cleanId.endsWith(".css") && !id.includes("node_modules") && !id.includes("\0")) {
|
|
@@ -3483,7 +3522,7 @@ function kbach(userConfig) {
|
|
|
3483
3522
|
try {
|
|
3484
3523
|
const added = extractFromCode((0, import_fs.readFileSync)(file, "utf-8"));
|
|
3485
3524
|
if (added && server) {
|
|
3486
|
-
server.hot
|
|
3525
|
+
(server.hot ?? server.ws)?.send({ type: "full-reload" });
|
|
3487
3526
|
}
|
|
3488
3527
|
} catch {
|
|
3489
3528
|
}
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -55,7 +55,6 @@ function kbach(userConfig) {
|
|
|
55
55
|
const tokenCSS = /* @__PURE__ */ new Map();
|
|
56
56
|
let root = process.cwd();
|
|
57
57
|
let server = null;
|
|
58
|
-
let isDev = false;
|
|
59
58
|
function processClassString(classStr) {
|
|
60
59
|
let added = false;
|
|
61
60
|
for (const token of classStr.split(/\s+/).filter(Boolean)) {
|
|
@@ -81,42 +80,82 @@ function kbach(userConfig) {
|
|
|
81
80
|
}
|
|
82
81
|
return parts.join("\n");
|
|
83
82
|
}
|
|
83
|
+
function injectIntoHtml(html) {
|
|
84
|
+
const css = getAllCSS();
|
|
85
|
+
if (!css || html.includes("data-kbach")) return html;
|
|
86
|
+
return html.replace("</head>", `<style data-kbach>${css}</style></head>`);
|
|
87
|
+
}
|
|
84
88
|
return {
|
|
85
89
|
name: "kbach",
|
|
86
90
|
enforce: "pre",
|
|
87
|
-
config(_c, env) {
|
|
88
|
-
isDev = env.command === "serve";
|
|
89
|
-
},
|
|
90
91
|
configResolved(resolved) {
|
|
91
92
|
root = resolved.root;
|
|
92
93
|
},
|
|
93
|
-
configureServer(s) {
|
|
94
|
-
server = s;
|
|
95
|
-
},
|
|
96
94
|
buildStart() {
|
|
97
95
|
for (const dir of ["src", "app", "pages", "components", "views", "layouts"]) {
|
|
98
96
|
scanDir(join(root, dir), (code) => extractFromCode(code));
|
|
99
97
|
}
|
|
100
98
|
},
|
|
101
|
-
// ──
|
|
102
|
-
// React Router v8
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
99
|
+
// ── DEV: intercept every HTML response and inject <style data-kbach> ──────
|
|
100
|
+
// React Router v8 uses chunked streaming SSR — </head> comes in an early
|
|
101
|
+
// res.write() chunk, not res.end(). Buffer all writes, concatenate at end,
|
|
102
|
+
// inject CSS into the full HTML, then send in one go.
|
|
103
|
+
configureServer(s) {
|
|
104
|
+
server = s;
|
|
105
|
+
s.middlewares.use((req, res, next) => {
|
|
106
|
+
const url = req.url ?? "";
|
|
107
|
+
if (/\.(js|ts|jsx|tsx|css|png|jpg|svg|ico|woff2?|ttf|json|map)(\?|$)/.test(url) || url.startsWith("/@") || url.startsWith("/__")) {
|
|
108
|
+
return next();
|
|
109
|
+
}
|
|
110
|
+
const origWrite = res.write.bind(res);
|
|
111
|
+
const origEnd = res.end.bind(res);
|
|
112
|
+
const chunks = [];
|
|
113
|
+
let done = false;
|
|
114
|
+
res.write = function(chunk, enc, cb) {
|
|
115
|
+
if (done) return origWrite(chunk, enc, cb);
|
|
116
|
+
if (chunk != null) {
|
|
117
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk ?? "")));
|
|
118
|
+
}
|
|
119
|
+
if (typeof enc === "function") enc();
|
|
120
|
+
else if (typeof cb === "function") cb();
|
|
121
|
+
return true;
|
|
122
|
+
};
|
|
123
|
+
res.end = function(chunk, enc, cb) {
|
|
124
|
+
done = true;
|
|
125
|
+
if (typeof chunk === "function") {
|
|
126
|
+
cb = chunk;
|
|
127
|
+
chunk = null;
|
|
128
|
+
enc = null;
|
|
129
|
+
} else if (typeof enc === "function") {
|
|
130
|
+
cb = enc;
|
|
131
|
+
enc = null;
|
|
132
|
+
}
|
|
133
|
+
if (chunk != null) {
|
|
134
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk ?? "")));
|
|
135
|
+
}
|
|
136
|
+
if (chunks.length > 0) {
|
|
137
|
+
const html = Buffer.concat(chunks).toString("utf-8");
|
|
138
|
+
if (html.includes("</head>")) {
|
|
139
|
+
const injected = injectIntoHtml(html);
|
|
140
|
+
const buf = Buffer.from(injected, "utf-8");
|
|
141
|
+
try {
|
|
142
|
+
res.removeHeader("transfer-encoding");
|
|
143
|
+
} catch {
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
res.setHeader("content-length", buf.length);
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
return origEnd(buf, cb);
|
|
150
|
+
}
|
|
151
|
+
return origEnd(Buffer.concat(chunks), enc, cb);
|
|
152
|
+
}
|
|
153
|
+
return origEnd(void 0, enc, cb);
|
|
154
|
+
};
|
|
155
|
+
next();
|
|
156
|
+
});
|
|
116
157
|
},
|
|
117
|
-
// ──
|
|
118
|
-
// In production, Vite extracts CSS from JS into separate .css files.
|
|
119
|
-
// Appending to the user's CSS ensures it ends up in the final CSS bundle.
|
|
158
|
+
// ── PROD: append to CSS files so they land in the extracted CSS bundle ────
|
|
120
159
|
transform(code, id) {
|
|
121
160
|
const cleanId = id.split("?")[0];
|
|
122
161
|
if (cleanId.endsWith(".css") && !id.includes("node_modules") && !id.includes("\0")) {
|
|
@@ -141,7 +180,7 @@ function kbach(userConfig) {
|
|
|
141
180
|
try {
|
|
142
181
|
const added = extractFromCode(readFileSync(file, "utf-8"));
|
|
143
182
|
if (added && server) {
|
|
144
|
-
server.hot
|
|
183
|
+
(server.hot ?? server.ws)?.send({ type: "full-reload" });
|
|
145
184
|
}
|
|
146
185
|
} catch {
|
|
147
186
|
}
|