@kbach/react 0.5.29 → 0.5.30

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.
@@ -3470,7 +3470,7 @@ function scanDir(dir, onFile) {
3470
3470
  try {
3471
3471
  const st = (0, import_fs.statSync)(full);
3472
3472
  if (st.isDirectory()) scanDir(full, onFile);
3473
- else if (/\.(tsx?|jsx?)$/.test(entry)) onFile((0, import_fs.readFileSync)(full, "utf-8"));
3473
+ else if (/\.(tsx?|jsx?)$/.test(entry)) onFile((0, import_fs.readFileSync)(full, "utf-8"), full);
3474
3474
  } catch {
3475
3475
  }
3476
3476
  }
@@ -3490,20 +3490,35 @@ function extractClassStrings(code) {
3490
3490
  function kbach(userConfig) {
3491
3491
  const cfg = buildConfig(userConfig ?? {});
3492
3492
  const screens = toNumericScreens(cfg.theme.screens ?? {});
3493
+ const fileTokens = /* @__PURE__ */ new Map();
3493
3494
  const tokenCSS = /* @__PURE__ */ new Map();
3494
3495
  let root = process.cwd();
3495
3496
  let mainCSSFile = null;
3496
- function processToken(token) {
3497
- if (tokenCSS.has(token)) return false;
3498
- tokenCSS.set(token, generateClassCSS(token, cfg.theme, cfg.darkMode, screens));
3499
- return true;
3500
- }
3501
- function extractFromCode(code) {
3502
- let added = false;
3497
+ function extractTokensFromCode(code) {
3498
+ const tokens = /* @__PURE__ */ new Set();
3503
3499
  for (const cls of extractClassStrings(code))
3504
3500
  for (const token of cls.split(/\s+/).filter(Boolean))
3505
- if (processToken(token)) added = true;
3506
- return added;
3501
+ tokens.add(token);
3502
+ return tokens;
3503
+ }
3504
+ function rebuildTokenCSS() {
3505
+ const live = /* @__PURE__ */ new Set();
3506
+ for (const tokens of fileTokens.values())
3507
+ for (const t of tokens) live.add(t);
3508
+ let changed = false;
3509
+ for (const token of tokenCSS.keys()) {
3510
+ if (!live.has(token)) {
3511
+ tokenCSS.delete(token);
3512
+ changed = true;
3513
+ }
3514
+ }
3515
+ for (const token of live) {
3516
+ if (!tokenCSS.has(token)) {
3517
+ tokenCSS.set(token, generateClassCSS(token, cfg.theme, cfg.darkMode, screens));
3518
+ changed = true;
3519
+ }
3520
+ }
3521
+ return changed;
3507
3522
  }
3508
3523
  function getFormattedCSS() {
3509
3524
  return formatKbachCSS(tokenCSS, cfg.theme);
@@ -3516,14 +3531,15 @@ function kbach(userConfig) {
3516
3531
  },
3517
3532
  buildStart() {
3518
3533
  for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
3519
- scanDir((0, import_path.join)(root, dir), (code) => extractFromCode(code));
3534
+ scanDir((0, import_path.join)(root, dir), (code, filePath) => fileTokens.set(filePath, extractTokensFromCode(code)));
3535
+ rebuildTokenCSS();
3520
3536
  mainCSSFile = findMainCSSFile(root);
3521
3537
  if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
3522
3538
  },
3523
3539
  transform(code, id) {
3524
- const cleanId = id.split("?")[0];
3525
- if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
3526
- extractFromCode(code);
3540
+ const filePath = id.split("?")[0];
3541
+ if (/\.(tsx?|jsx?)$/.test(filePath) && !id.includes("node_modules"))
3542
+ fileTokens.set(filePath, extractTokensFromCode(code));
3527
3543
  },
3528
3544
  resolveId(id) {
3529
3545
  if (id === VIRTUAL_ID) return RESOLVED_ID;
@@ -3534,8 +3550,8 @@ function kbach(userConfig) {
3534
3550
  handleHotUpdate({ file }) {
3535
3551
  if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
3536
3552
  try {
3537
- const added = extractFromCode((0, import_fs.readFileSync)(file, "utf-8"));
3538
- if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
3553
+ fileTokens.set(file, extractTokensFromCode((0, import_fs.readFileSync)(file, "utf-8")));
3554
+ if (rebuildTokenCSS() && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
3539
3555
  } catch {
3540
3556
  }
3541
3557
  }
@@ -128,7 +128,7 @@ function scanDir(dir, onFile) {
128
128
  try {
129
129
  const st = statSync(full);
130
130
  if (st.isDirectory()) scanDir(full, onFile);
131
- else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(readFileSync(full, "utf-8"));
131
+ else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(readFileSync(full, "utf-8"), full);
132
132
  } catch {
133
133
  }
134
134
  }
@@ -148,20 +148,35 @@ function extractClassStrings(code) {
148
148
  function kbach(userConfig) {
149
149
  const cfg = buildConfig(userConfig ?? {});
150
150
  const screens = toNumericScreens(cfg.theme.screens ?? {});
151
+ const fileTokens = /* @__PURE__ */ new Map();
151
152
  const tokenCSS = /* @__PURE__ */ new Map();
152
153
  let root = process.cwd();
153
154
  let mainCSSFile = null;
154
- function processToken(token) {
155
- if (tokenCSS.has(token)) return false;
156
- tokenCSS.set(token, generateClassCSS(token, cfg.theme, cfg.darkMode, screens));
157
- return true;
158
- }
159
- function extractFromCode(code) {
160
- let added = false;
155
+ function extractTokensFromCode(code) {
156
+ const tokens = /* @__PURE__ */ new Set();
161
157
  for (const cls of extractClassStrings(code))
162
158
  for (const token of cls.split(/\s+/).filter(Boolean))
163
- if (processToken(token)) added = true;
164
- return added;
159
+ tokens.add(token);
160
+ return tokens;
161
+ }
162
+ function rebuildTokenCSS() {
163
+ const live = /* @__PURE__ */ new Set();
164
+ for (const tokens of fileTokens.values())
165
+ for (const t of tokens) live.add(t);
166
+ let changed = false;
167
+ for (const token of tokenCSS.keys()) {
168
+ if (!live.has(token)) {
169
+ tokenCSS.delete(token);
170
+ changed = true;
171
+ }
172
+ }
173
+ for (const token of live) {
174
+ if (!tokenCSS.has(token)) {
175
+ tokenCSS.set(token, generateClassCSS(token, cfg.theme, cfg.darkMode, screens));
176
+ changed = true;
177
+ }
178
+ }
179
+ return changed;
165
180
  }
166
181
  function getFormattedCSS() {
167
182
  return formatKbachCSS(tokenCSS, cfg.theme);
@@ -174,14 +189,15 @@ function kbach(userConfig) {
174
189
  },
175
190
  buildStart() {
176
191
  for (const dir of ["src", "app", "pages", "components", "views", "layouts"])
177
- scanDir(join(root, dir), (code) => extractFromCode(code));
192
+ scanDir(join(root, dir), (code, filePath) => fileTokens.set(filePath, extractTokensFromCode(code)));
193
+ rebuildTokenCSS();
178
194
  mainCSSFile = findMainCSSFile(root);
179
195
  if (mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
180
196
  },
181
197
  transform(code, id) {
182
- const cleanId = id.split("?")[0];
183
- if (/\.(tsx?|jsx?)$/.test(cleanId) && !id.includes("node_modules"))
184
- extractFromCode(code);
198
+ const filePath = id.split("?")[0];
199
+ if (/\.(tsx?|jsx?)$/.test(filePath) && !id.includes("node_modules"))
200
+ fileTokens.set(filePath, extractTokensFromCode(code));
185
201
  },
186
202
  resolveId(id) {
187
203
  if (id === VIRTUAL_ID) return RESOLVED_ID;
@@ -192,8 +208,8 @@ function kbach(userConfig) {
192
208
  handleHotUpdate({ file }) {
193
209
  if (file.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(file)) return;
194
210
  try {
195
- const added = extractFromCode(readFileSync(file, "utf-8"));
196
- if (added && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
211
+ fileTokens.set(file, extractTokensFromCode(readFileSync(file, "utf-8")));
212
+ if (rebuildTokenCSS() && mainCSSFile) writeKbachToFile(mainCSSFile, getFormattedCSS());
197
213
  } catch {
198
214
  }
199
215
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.5.29",
3
+ "version": "0.5.30",
4
4
  "description": "React / React Native components and hooks for the Kbach framework",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./dist/index.js",