@barocss/browser 0.8.1 → 0.8.2

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/index.es.js CHANGED
@@ -1,767 +1,593 @@
1
- import { parseClassName as y, upperBound as b, ruleSortKey as m, compareKeys as S, createContext as p, IncrementalParser as C, clearAstCache as x } from "@barocss/kit";
2
- class d {
3
- constructor(t, e = 50, s = "barocss-style-partition-", i = (r) => y(r).utility?.category) {
4
- this.partitions = [], this.categoryPartitions = /* @__PURE__ */ new Map(), this.partitionCounter = 0, this.maxRulesPerPartition = 50, this.classToPartitionMap = /* @__PURE__ */ new Map(), this.classToCategoryPartitionMap = /* @__PURE__ */ new Map(), this.styleIdPrefix = "barocss-style-partition-", this.insertionPoint = t, this.maxRulesPerPartition = e, this.styleIdPrefix = s, this.getCategory = i, this.initializeDefaultPartition();
5
- }
6
- /**
7
- * Insert `rule` at its Tailwind variant position within `partition` (#254):
8
- * one insertRule at a binary-searched index, no sheet rewrite.
9
- */
10
- insertSorted(t, e, s) {
11
- const i = t.keys ??= [], r = b(i, s), n = t.styleElement.sheet;
12
- n && n.cssRules.length === i.length ? (n.insertRule(this.escapeCssRule(e), r), t.styles.splice(r, 0, e)) : (t.styles.splice(r, 0, e), t.styleElement.textContent = t.styles.join(`
13
- `) + `
14
- `), i.splice(r, 0, s);
15
- }
16
- initializeDefaultPartition() {
17
- this.createNewPartition();
18
- }
19
- createNewCategoryPartition(t, e = !1) {
20
- const s = {
21
- id: this.styleIdPrefix + `-${t}`,
22
- styles: [],
23
- styleElement: document.createElement("style")
24
- };
25
- s.styleElement.id = s.id, s.styleElement.setAttribute("data-barocss", "partition"), s.styleElement.setAttribute("data-category", t);
26
- const i = this.insertionPoint.ownerDocument?.head;
27
- return e && i ? i.insertBefore(s.styleElement, i.firstChild) : this.insertionPoint.appendChild(s.styleElement), this.categoryPartitions.set(t, s), s;
28
- }
29
- createNewPartition() {
30
- const t = {
31
- id: this.styleIdPrefix + `-${this.partitionCounter++}`,
32
- styles: [],
33
- styleElement: document.createElement("style")
34
- };
35
- return this.partitions.push(t), t.styleElement.id = t.id, t.styleElement.setAttribute("data-barocss", "partition"), t.styleElement.setAttribute(
36
- "data-partition-index",
37
- this.partitionCounter.toString()
38
- ), this.insertionPoint.appendChild(t.styleElement), t;
39
- }
40
- hasRule(t) {
41
- return this.classToPartitionMap.has(t);
42
- }
43
- hasCategoryRule(t, e) {
44
- return this.classToCategoryPartitionMap.get(t) === e;
45
- }
46
- setRuleCache(t, e) {
47
- this.classToPartitionMap.set(t, e);
48
- }
49
- setCategoryRuleCache(t, e) {
50
- this.classToCategoryPartitionMap.set(t, e);
51
- }
52
- get currentPartition() {
53
- return this.partitions[this.partitions.length - 1];
54
- }
55
- getCategoryPartition(t) {
56
- return this.categoryPartitions.get(t);
57
- }
58
- hasDetachedPartitions() {
59
- return [...this.partitions, ...this.categoryPartitions.values()].some((t) => !t.styleElement.isConnected);
60
- }
61
- /**
62
- * Escape CSS rule text
63
- * - Properly escape special characters
64
- * - Prevent CSS syntax errors
65
- */
66
- escapeCssRule(t) {
67
- return t.replace(/\\\//g, "\\/");
68
- }
69
- addRule(t) {
70
- if (this.hasRule(t))
71
- return !1;
72
- const e = m(t);
73
- let s = this.partitions.findIndex((r) => {
74
- const n = r.keys;
75
- return !!n && n.length > 0 && S(n[n.length - 1], e) > 0;
76
- });
77
- s === -1 && (this.currentPartition.styles.length >= this.maxRulesPerPartition && this.createNewPartition(), s = this.partitions.length - 1);
78
- const i = this.partitions[s];
79
- try {
80
- return this.insertSorted(i, t, e), this.setRuleCache(t, s), !0;
81
- } catch (r) {
82
- return console.warn(
83
- `[StylePartitionManager] Failed to insert rule: ${t}`,
84
- r
85
- ), !1;
86
- }
87
- }
88
- addCategoryRule(t, e) {
89
- if (this.hasCategoryRule(t, e))
90
- return !1;
91
- let s = this.getCategoryPartition(e);
92
- s || (s = this.createNewCategoryPartition(e));
93
- try {
94
- this.insertSorted(s, t, m(t));
95
- } catch (i) {
96
- return console.warn(
97
- `[StylePartitionManager] Failed to insert rule in category: ${e} ${t}`,
98
- i
99
- ), !1;
100
- }
101
- return this.setCategoryRuleCache(t, e), !0;
102
- }
103
- addRootRules(t) {
104
- let e = this.getCategoryPartition("root");
105
- e || (e = this.createNewCategoryPartition("root"));
106
- try {
107
- const s = e.styleElement.sheet;
108
- for (const i of t)
109
- s ? s.insertRule(this.escapeCssRule(i), s.cssRules.length) : e.styleElement.textContent += i + `
110
- `;
111
- } catch (s) {
112
- return console.warn(
113
- `[StylePartitionManager] Failed to insert rule in category: root ${t.join(`
114
- `)}`,
115
- s
116
- ), { success: 0, failed: t.length };
117
- }
118
- return { success: t.length, failed: 0 };
119
- }
120
- addRules(t) {
121
- let e = 0, s = 0;
122
- for (const i of t) {
123
- const r = this.getCategory(i.cls);
124
- if (r)
125
- for (const n of i.cssList)
126
- this.addCategoryRule(n, r);
127
- else
128
- for (const n of i.cssList)
129
- this.addRule(n) ? e++ : s++;
130
- }
131
- return { success: e, failed: s };
132
- }
133
- /**
134
- * Remove one generated rule (#269 GC). Keeps `styles`, the #254 `keys` and the
135
- * sheet's cssRules parallel: one deleteRule at the rule's index, or a text
136
- * rebuild when the sheet isn't solely ours / has no CSSOM. Returns whether
137
- * the rule was found.
138
- */
139
- removeRule(t, e) {
140
- let s;
141
- if (e) {
142
- if (this.classToCategoryPartitionMap.get(t) !== e) return !1;
143
- s = this.categoryPartitions.get(e);
144
- } else {
145
- const o = this.classToPartitionMap.get(t);
146
- s = o === void 0 ? void 0 : this.partitions[o];
147
- }
148
- if (!s) return !1;
149
- const i = s.styles.indexOf(t);
150
- if (i === -1) return !1;
151
- const r = s.styleElement.sheet, n = !!r && r.cssRules.length === s.styles.length;
152
- return s.styles.splice(i, 1), s.keys?.splice(i, 1), n && r ? r.deleteRule(i) : s.styleElement.textContent = s.styles.length ? s.styles.join(`
153
- `) + `
154
- ` : "", e ? this.classToCategoryPartitionMap.delete(t) : this.classToPartitionMap.delete(t), !0;
155
- }
156
- /** Number of generated (non-root, non-preflight) rules currently held. */
157
- get ruleCount() {
158
- return this.classToPartitionMap.size + this.classToCategoryPartitionMap.size;
159
- }
160
- /**
161
- * 특정 규칙이 어느 파티션에 있는지 찾기
162
- */
163
- findRulePartition(t) {
164
- const e = this.classToPartitionMap.get(t);
165
- if (e !== void 0 && this.partitions[e])
166
- return this.partitions[e];
167
- const s = this.classToCategoryPartitionMap.get(t);
168
- return s !== void 0 && this.categoryPartitions.get(s) || null;
169
- }
170
- updateRuleContent(t, e, s = !1) {
171
- const i = this.getCategoryPartition(t);
172
- if (i)
173
- i.styleElement.textContent = e;
174
- else {
175
- const r = this.createNewCategoryPartition(t, s);
176
- console.log(`[StylePartitionManager] Created new partition for category: ${t}`), r.styleElement.textContent = e;
177
- }
178
- }
179
- /**
180
- * 모든 파티션 정리
181
- */
182
- cleanup() {
183
- this.partitions.forEach((t) => {
184
- t.styleElement.parentNode && t.styleElement.parentNode.removeChild(t.styleElement);
185
- }), this.categoryPartitions.forEach((t) => {
186
- t.styleElement.parentNode && t.styleElement.parentNode.removeChild(t.styleElement);
187
- }), this.partitions = [], this.categoryPartitions.clear(), this.partitionCounter = 0, this.classToPartitionMap.clear(), this.classToCategoryPartitionMap.clear();
188
- }
189
- }
190
- function w(a) {
191
- return a ? typeof a == "object" && typeof a.baseVal == "string" ? a.baseVal : a.toString() : "";
192
- }
193
- function u(a) {
194
- return a ? w(a).split(/\s+/).filter(Boolean) : [];
195
- }
196
- class E {
197
- /**
198
- * Create a new ChangeDetector instance
199
- *
200
- * @param incrementalParser - IncrementalParser instance for class processing
201
- * @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
202
- */
203
- constructor(t, e, s = (i) => y(i).utility?.category) {
204
- this.observer = null, this.gc = null, this.incrementalParser = t, this.BrowserRuntime = e, this.getCategory = s;
205
- }
206
- setGc(t) {
207
- this.gc = t;
208
- }
209
- setParser(t) {
210
- this.incrementalParser = t;
211
- }
212
- /**
213
- * Starts observing DOM changes for new CSS classes
214
- *
215
- * This method sets up a MutationObserver that monitors:
216
- * - Attribute changes (specifically class attribute modifications)
217
- * - Child list changes (new elements being added)
218
- * - Subtree changes (changes in descendant elements)
219
- *
220
- * The observer automatically processes any new classes it discovers
221
- * by adding them to the IncrementalParser's pending queue.
222
- *
223
- * @param root - The root element to observe (defaults to document.body)
224
- * @param options - Configuration options including initial scan and onReady callback
225
- * @returns The MutationObserver instance for external control
226
- */
227
- observe(t = document.body, e) {
228
- return typeof window > "u" ? new MutationObserver(() => {
229
- }) : (this.observer && this.observer.disconnect(), this.gc?.setRoot(t), this.observer = new MutationObserver((s) => {
230
- const i = /* @__PURE__ */ new Set(), r = this.gc;
231
- if (s.forEach((n) => {
232
- if (r && (n.type === "attributes" ? r.reconcile(n.target) : n.type === "childList" && (n.removedNodes.forEach((o) => r.reconcileTree(o)), n.addedNodes.forEach((o) => r.reconcileTree(o)))), n.type === "attributes" && n.attributeName === "class" && t.contains(n.target)) {
233
- const o = n.target;
234
- o.className && u(o.className).forEach((l) => {
235
- this.incrementalParser.isProcessed(l) || i.add(l);
236
- });
237
- }
238
- n.type === "childList" && n.addedNodes.forEach((o) => {
239
- if (o.nodeType === Node.ELEMENT_NODE && t.contains(o)) {
240
- const c = o;
241
- this.processElement(c, i), c.querySelectorAll("[class]").forEach((l) => {
242
- this.processElement(l, i);
243
- });
244
- }
245
- });
246
- }), i.size > 0) {
247
- const n = Array.from(i), o = this.incrementalParser.processClasses(n);
248
- this.BrowserRuntime?.applyParseResults(o);
249
- } else
250
- this.BrowserRuntime?.applyParseResults([]);
251
- r?.afterBatch();
252
- }), this.observer.observe(t, {
253
- attributes: !0,
254
- subtree: !0,
255
- attributeFilter: ["class"],
256
- childList: !0
257
- }), e?.scan && this.scanExistingClasses(t, e), this.observer);
258
- }
259
- /**
260
- * Scan existing classes in the DOM and process them
261
- */
262
- scanExistingClasses(t, e) {
263
- const s = /* @__PURE__ */ new Set();
264
- t.className && u(t.className).forEach((n) => {
265
- this.incrementalParser.isProcessed(n) || s.add(n);
266
- });
267
- const i = t.querySelectorAll("[class]");
268
- for (const r of i)
269
- if (r.className) {
270
- const n = u(r.className);
271
- for (const o of n)
272
- this.incrementalParser.isProcessed(o) || s.add(o);
273
- }
274
- if (s.size > 0) {
275
- const r = Array.from(s), n = this.incrementalParser.processClasses(r), o = n.filter((l) => this.getCategory(l.cls) === "layout"), c = n.filter((l) => this.getCategory(l.cls) !== "layout");
276
- this.BrowserRuntime?.applyParseResults(o), e?.onReady?.(), this.BrowserRuntime?.applyParseResults(c);
277
- } else
278
- e?.onReady?.();
279
- }
280
- /**
281
- * Processes an individual element and extracts new classes
282
- *
283
- * This method is called for each element discovered during DOM mutations.
284
- * It:
285
- * - Extracts all class names from the element's className
286
- * - Filters out already processed classes
287
- * - Adds new classes to the collection for batch processing
288
- *
289
- * @param element - The HTML element to process
290
- * @param newClasses - Set to collect newly discovered class names
291
- */
292
- processElement(t, e) {
293
- t.className && u(t.className).forEach((i) => {
294
- this.incrementalParser.isProcessed(i) || e.add(i);
295
- });
296
- }
297
- /**
298
- * Stops observing DOM changes and cleans up resources
299
- *
300
- * This method disconnects the MutationObserver and clears the
301
- * observer reference to prevent memory leaks and allow the
302
- * ChangeDetector to be properly garbage collected.
303
- */
304
- disconnect() {
305
- this.observer && (this.observer.disconnect(), this.observer = null);
306
- }
307
- }
308
- function M(a) {
309
- return a.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g, (t, e, s) => e ? String.fromCodePoint(parseInt(e, 16)) : s);
1
+ import { IncrementalParser as e, clearAstCache as t, compareKeys as n, createContext as r, isDebug as i, parseClassName as a, ruleSortKey as o, upperBound as s } from "@barocss/kit";
2
+ //#region src/style-partition-manager.ts
3
+ var c = class {
4
+ insertSorted(e, t, n) {
5
+ let r = e.keys ??= [], i = s(r, n), a = e.styleElement.sheet;
6
+ a && a.cssRules.length === r.length ? (a.insertRule(this.escapeCssRule(t), i), e.styles.splice(i, 0, t)) : (e.styles.splice(i, 0, t), e.styleElement.textContent = e.styles.join("\n") + "\n"), r.splice(i, 0, n);
7
+ }
8
+ constructor(e, t = 50, n = "barocss-style-partition-", r = (e) => a(e).utility?.category) {
9
+ this.partitions = [], this.categoryPartitions = /* @__PURE__ */ new Map(), this.partitionCounter = 0, this.maxRulesPerPartition = 50, this.classToPartitionMap = /* @__PURE__ */ new Map(), this.classToCategoryPartitionMap = /* @__PURE__ */ new Map(), this.styleIdPrefix = "barocss-style-partition-", this.insertionPoint = e, this.maxRulesPerPartition = t, this.styleIdPrefix = n, this.getCategory = r, this.initializeDefaultPartition();
10
+ }
11
+ initializeDefaultPartition() {
12
+ this.createNewPartition();
13
+ }
14
+ createNewCategoryPartition(e, t = !1) {
15
+ let n = {
16
+ id: this.styleIdPrefix + `-${e}`,
17
+ styles: [],
18
+ styleElement: document.createElement("style")
19
+ };
20
+ n.styleElement.id = n.id, n.styleElement.setAttribute("data-barocss", "partition"), n.styleElement.setAttribute("data-category", e);
21
+ let r = this.insertionPoint.ownerDocument?.head;
22
+ return t && r ? r.insertBefore(n.styleElement, r.firstChild) : this.insertionPoint.appendChild(n.styleElement), this.categoryPartitions.set(e, n), n;
23
+ }
24
+ createNewPartition() {
25
+ let e = {
26
+ id: this.styleIdPrefix + `-${this.partitionCounter++}`,
27
+ styles: [],
28
+ styleElement: document.createElement("style")
29
+ };
30
+ return this.partitions.push(e), e.styleElement.id = e.id, e.styleElement.setAttribute("data-barocss", "partition"), e.styleElement.setAttribute("data-partition-index", this.partitionCounter.toString()), this.insertionPoint.appendChild(e.styleElement), e;
31
+ }
32
+ hasRule(e) {
33
+ return this.classToPartitionMap.has(e);
34
+ }
35
+ hasCategoryRule(e, t) {
36
+ return this.classToCategoryPartitionMap.get(e) === t;
37
+ }
38
+ setRuleCache(e, t) {
39
+ this.classToPartitionMap.set(e, t);
40
+ }
41
+ setCategoryRuleCache(e, t) {
42
+ this.classToCategoryPartitionMap.set(e, t);
43
+ }
44
+ get currentPartition() {
45
+ return this.partitions[this.partitions.length - 1];
46
+ }
47
+ getCategoryPartition(e) {
48
+ return this.categoryPartitions.get(e);
49
+ }
50
+ hasDetachedPartitions() {
51
+ return [...this.partitions, ...this.categoryPartitions.values()].some((e) => !e.styleElement.isConnected);
52
+ }
53
+ escapeCssRule(e) {
54
+ return e.replace(/\\\//g, "\\/");
55
+ }
56
+ addRule(e) {
57
+ if (this.hasRule(e)) return !1;
58
+ let t = o(e), r = this.partitions.findIndex((e) => {
59
+ let r = e.keys;
60
+ return !!r && r.length > 0 && n(r[r.length - 1], t) > 0;
61
+ });
62
+ r === -1 && (this.currentPartition.styles.length >= this.maxRulesPerPartition && this.createNewPartition(), r = this.partitions.length - 1);
63
+ let a = this.partitions[r];
64
+ try {
65
+ return this.insertSorted(a, e, t), this.setRuleCache(e, r), !0;
66
+ } catch (t) {
67
+ return i() && console.warn(`[StylePartitionManager] Failed to insert rule: ${e}`, t), !1;
68
+ }
69
+ }
70
+ addCategoryRule(e, t) {
71
+ if (this.hasCategoryRule(e, t)) return !1;
72
+ let n = this.getCategoryPartition(t);
73
+ n ||= this.createNewCategoryPartition(t);
74
+ try {
75
+ this.insertSorted(n, e, o(e));
76
+ } catch (n) {
77
+ return i() && console.warn(`[StylePartitionManager] Failed to insert rule in category: ${t} ${e}`, n), !1;
78
+ }
79
+ return this.setCategoryRuleCache(e, t), !0;
80
+ }
81
+ addRootRules(e) {
82
+ let t = this.getCategoryPartition("root");
83
+ t ||= this.createNewCategoryPartition("root");
84
+ try {
85
+ let n = t.styleElement.sheet;
86
+ for (let r of e) n ? n.insertRule(this.escapeCssRule(r), n.cssRules.length) : t.styleElement.textContent += r + "\n";
87
+ } catch (t) {
88
+ return i() && console.warn(`[StylePartitionManager] Failed to insert rule in category: root ${e.join("\n")}`, t), {
89
+ success: 0,
90
+ failed: e.length
91
+ };
92
+ }
93
+ return {
94
+ success: e.length,
95
+ failed: 0
96
+ };
97
+ }
98
+ addRules(e) {
99
+ let t = 0, n = 0;
100
+ for (let r of e) {
101
+ let e = this.getCategory(r.cls);
102
+ if (e) for (let t of r.cssList) this.addCategoryRule(t, e);
103
+ else for (let e of r.cssList) this.addRule(e) ? t++ : n++;
104
+ }
105
+ return {
106
+ success: t,
107
+ failed: n
108
+ };
109
+ }
110
+ removeRule(e, t) {
111
+ let n;
112
+ if (t) {
113
+ if (this.classToCategoryPartitionMap.get(e) !== t) return !1;
114
+ n = this.categoryPartitions.get(t);
115
+ } else {
116
+ let t = this.classToPartitionMap.get(e);
117
+ n = t === void 0 ? void 0 : this.partitions[t];
118
+ }
119
+ if (!n) return !1;
120
+ let r = n.styles.indexOf(e);
121
+ if (r === -1) return !1;
122
+ let i = n.styleElement.sheet, a = !!i && i.cssRules.length === n.styles.length;
123
+ return n.styles.splice(r, 1), n.keys?.splice(r, 1), a && i ? i.deleteRule(r) : n.styleElement.textContent = n.styles.length ? n.styles.join("\n") + "\n" : "", t ? this.classToCategoryPartitionMap.delete(e) : this.classToPartitionMap.delete(e), !0;
124
+ }
125
+ get ruleCount() {
126
+ return this.classToPartitionMap.size + this.classToCategoryPartitionMap.size;
127
+ }
128
+ findRulePartition(e) {
129
+ let t = this.classToPartitionMap.get(e);
130
+ if (t !== void 0 && this.partitions[t]) return this.partitions[t];
131
+ let n = this.classToCategoryPartitionMap.get(e);
132
+ return n === void 0 ? null : this.categoryPartitions.get(n) || null;
133
+ }
134
+ updateRuleContent(e, t, n = !1) {
135
+ let r = this.getCategoryPartition(e);
136
+ if (r) r.styleElement.textContent = t;
137
+ else {
138
+ let r = this.createNewCategoryPartition(e, n);
139
+ i() && console.log(`[StylePartitionManager] Created new partition for category: ${e}`), r.styleElement.textContent = t;
140
+ }
141
+ }
142
+ cleanup() {
143
+ this.partitions.forEach((e) => {
144
+ e.styleElement.parentNode && e.styleElement.parentNode.removeChild(e.styleElement);
145
+ }), this.categoryPartitions.forEach((e) => {
146
+ e.styleElement.parentNode && e.styleElement.parentNode.removeChild(e.styleElement);
147
+ }), this.partitions = [], this.categoryPartitions.clear(), this.partitionCounter = 0, this.classToPartitionMap.clear(), this.classToCategoryPartitionMap.clear();
148
+ }
149
+ };
150
+ //#endregion
151
+ //#region src/utils.ts
152
+ function l(e) {
153
+ return e ? typeof e == "object" && typeof e.baseVal == "string" ? e.baseVal : e.toString() : "";
310
154
  }
311
- const v = /^\s*(?::(?:where|is)\(\s*)?\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;
312
- function A(a) {
313
- const t = [];
314
- let e = 0, s = 0;
315
- for (let i = 0; i < a.length; i++) {
316
- const r = a[i];
317
- r === "\\" ? i++ : r === "(" || r === "[" ? e++ : r === ")" || r === "]" ? e-- : r === "," && e === 0 && (t.push(a.slice(s, i)), s = i + 1);
318
- }
319
- return t.push(a.slice(s)), t;
155
+ function u(e) {
156
+ return e ? l(e).split(/\s+/).filter(Boolean) : [];
320
157
  }
321
- function P(a, t = /* @__PURE__ */ new Set()) {
322
- for (const e of Array.from(a)) {
323
- if (e.type === 7 && typeof e.name == "string") {
324
- t.add(e.name);
325
- continue;
326
- }
327
- const s = e.cssRules;
328
- s && s.length && P(s, t);
329
- }
330
- return t;
158
+ //#endregion
159
+ //#region src/change-detector.ts
160
+ var d = class {
161
+ constructor(e, t, n = (e) => a(e).utility?.category) {
162
+ this.observer = null, this.gc = null, this.incrementalParser = e, this.BrowserRuntime = t, this.getCategory = n;
163
+ }
164
+ setGc(e) {
165
+ this.gc = e;
166
+ }
167
+ setParser(e) {
168
+ this.incrementalParser = e;
169
+ }
170
+ observe(e = document.body, t) {
171
+ return typeof window > "u" ? new MutationObserver(() => {}) : (this.observer && this.observer.disconnect(), this.gc?.setRoot(e), this.observer = new MutationObserver((t) => {
172
+ let n = /* @__PURE__ */ new Set(), r = this.gc;
173
+ if (t.forEach((t) => {
174
+ if (r && (t.type === "attributes" ? r.reconcile(t.target) : t.type === "childList" && (t.removedNodes.forEach((e) => r.reconcileTree(e)), t.addedNodes.forEach((e) => r.reconcileTree(e)))), t.type === "attributes" && t.attributeName === "class" && e.contains(t.target)) {
175
+ let e = t.target;
176
+ e.className && u(e.className).forEach((e) => {
177
+ this.incrementalParser.isProcessed(e) || n.add(e);
178
+ });
179
+ }
180
+ t.type === "childList" && t.addedNodes.forEach((t) => {
181
+ if (t.nodeType === Node.ELEMENT_NODE && e.contains(t)) {
182
+ let e = t;
183
+ this.processElement(e, n), e.querySelectorAll("[class]").forEach((e) => {
184
+ this.processElement(e, n);
185
+ });
186
+ }
187
+ });
188
+ }), n.size > 0) {
189
+ let e = Array.from(n), t = this.incrementalParser.processClasses(e);
190
+ this.BrowserRuntime?.applyParseResults(t);
191
+ } else this.BrowserRuntime?.applyParseResults([]);
192
+ r?.afterBatch();
193
+ }), this.observer.observe(e, {
194
+ attributes: !0,
195
+ subtree: !0,
196
+ attributeFilter: ["class"],
197
+ childList: !0
198
+ }), t?.scan && this.scanExistingClasses(e, t), this.observer);
199
+ }
200
+ scanExistingClasses(e, t) {
201
+ let n = /* @__PURE__ */ new Set();
202
+ e.className && u(e.className).forEach((e) => {
203
+ this.incrementalParser.isProcessed(e) || n.add(e);
204
+ });
205
+ let r = e.querySelectorAll("[class]");
206
+ for (let e of r) if (e.className) {
207
+ let t = u(e.className);
208
+ for (let e of t) this.incrementalParser.isProcessed(e) || n.add(e);
209
+ }
210
+ if (n.size > 0) {
211
+ let e = Array.from(n), r = this.incrementalParser.processClasses(e), i = r.filter((e) => this.getCategory(e.cls) === "layout"), a = r.filter((e) => this.getCategory(e.cls) !== "layout");
212
+ this.BrowserRuntime?.applyParseResults(i), t?.onReady?.(), this.BrowserRuntime?.applyParseResults(a);
213
+ } else t?.onReady?.();
214
+ }
215
+ processElement(e, t) {
216
+ e.className && u(e.className).forEach((e) => {
217
+ this.incrementalParser.isProcessed(e) || t.add(e);
218
+ });
219
+ }
220
+ disconnect() {
221
+ this.observer &&= (this.observer.disconnect(), null);
222
+ }
223
+ };
224
+ //#endregion
225
+ //#region src/existing-classes.ts
226
+ function f(e) {
227
+ return e.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g, (e, t, n) => t ? String.fromCodePoint(parseInt(t, 16)) : n);
331
228
  }
332
- function g(a, t = /* @__PURE__ */ new Set()) {
333
- for (const e of Array.from(a)) {
334
- const s = e.selectorText;
335
- if (typeof s == "string")
336
- for (const r of A(s)) {
337
- const n = v.exec(r);
338
- n && t.add(M(n[1]));
339
- }
340
- const i = e.cssRules;
341
- i && i.length && g(i, t);
342
- }
343
- return t;
229
+ var p = /^\s*(?::(?:where|is)\(\s*)?\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;
230
+ function m(e) {
231
+ let t = [], n = 0, r = 0;
232
+ for (let i = 0; i < e.length; i++) {
233
+ let a = e[i];
234
+ a === "\\" ? i++ : a === "(" || a === "[" ? n++ : a === ")" || a === "]" ? n-- : a === "," && n === 0 && (t.push(e.slice(r, i)), r = i + 1);
235
+ }
236
+ return t.push(e.slice(r)), t;
344
237
  }
345
- class T {
346
- constructor(t, e, s, i = () => Date.now()) {
347
- this.host = t, this.graceMs = e, this.maxRules = s, this.now = i, this.counts = /* @__PURE__ */ new Map(), this.counted = /* @__PURE__ */ new WeakMap(), this.candidates = /* @__PURE__ */ new Map(), this.timer = null, this.root = null;
348
- }
349
- /** Start counting for a new root: count every element currently inside it. */
350
- setRoot(t) {
351
- this.counts.clear(), this.counted = /* @__PURE__ */ new WeakMap(), this.candidates.clear(), this.cancel(), this.root = t, this.reconcileTree(t);
352
- }
353
- count(t) {
354
- return this.counts.get(t) ?? 0;
355
- }
356
- /** Re-count `el` and (optionally) all its descendants from their current state. */
357
- reconcileTree(t) {
358
- if (t.nodeType !== 1) return;
359
- const e = t;
360
- this.reconcile(e), e.querySelectorAll("[class]").forEach((s) => this.reconcile(s));
361
- }
362
- reconcile(t) {
363
- const e = this.root, i = !!e && e.contains(t) ? Array.from(new Set(u(t.getAttribute("class")))) : [], r = this.counted.get(t);
364
- if (!r && i.length === 0) return;
365
- const n = new Set(r ?? []), o = new Set(i);
366
- for (const c of o) {
367
- if (n.has(c)) continue;
368
- const l = (this.counts.get(c) ?? 0) + 1;
369
- this.counts.set(c, l), this.candidates.delete(c);
370
- }
371
- for (const c of n) {
372
- if (o.has(c)) continue;
373
- const l = (this.counts.get(c) ?? 0) - 1;
374
- l > 0 ? this.counts.set(c, l) : (this.counts.delete(c), this.candidates.delete(c), this.candidates.set(c, this.now()));
375
- }
376
- i.length ? this.counted.set(t, i) : this.counted.delete(t);
377
- }
378
- /** Call after a mutation batch has been counted and its classes inserted. */
379
- afterBatch() {
380
- this.candidates.size !== 0 && (this.host.cachedCount() > this.maxRules ? this.schedule(0) : this.schedule(this.graceMs));
381
- }
382
- schedule(t) {
383
- if (this.timer !== null) {
384
- if (t > 0) return;
385
- clearTimeout(this.timer);
386
- }
387
- this.timer = setTimeout(() => {
388
- this.timer = null, this.sweep();
389
- }, t);
390
- }
391
- /** Reclaim candidates whose grace period elapsed (plus LRU overflow). Public for tests. */
392
- sweep() {
393
- const t = this.now(), e = Math.max(0, this.host.cachedCount() - this.maxRules), s = [];
394
- let i = 0;
395
- for (const [r, n] of this.candidates) {
396
- const o = t - n >= this.graceMs;
397
- !o && i >= e || (this.candidates.delete(r), !(this.count(r) > 0 || this.inDom(r) || this.host.isPermanent(r)) && (s.push(r), o || i++));
398
- }
399
- s.length && this.host.reclaim(s), this.candidates.size && this.schedule(this.graceMs);
400
- }
401
- inDom(t) {
402
- const e = this.root;
403
- if (!e) return !1;
404
- const s = e.ownerDocument ?? document;
405
- return e.classList.contains(t) || s.documentElement.classList.contains(t) || s.getElementsByClassName(t).length > 0;
406
- }
407
- cancel() {
408
- this.timer !== null && clearTimeout(this.timer), this.timer = null;
409
- }
410
- stats() {
411
- return { trackedClasses: this.counts.size, candidates: this.candidates.size };
412
- }
238
+ function h(e, t = /* @__PURE__ */ new Set()) {
239
+ for (let n of Array.from(e)) {
240
+ if (n.type === 7 && typeof n.name == "string") {
241
+ t.add(n.name);
242
+ continue;
243
+ }
244
+ let e = n.cssRules;
245
+ e && e.length && h(e, t);
246
+ }
247
+ return t;
413
248
  }
414
- const D = "style[data-barocss-ssr]", L = "@layer theme, base, components, utilities;";
415
- class N {
416
- constructor(t = {}) {
417
- this.cache = /* @__PURE__ */ new Map(), this.rootCache = /* @__PURE__ */ new Set(), this.isDestroyed = !1, this.existing = null, this.existingKeyframes = /* @__PURE__ */ new Set(), this.existingSheetCount = -1, this.pinned = /* @__PURE__ */ new Set(), this.gc = null, this.reclaimedCount = 0, this.ssrRules = [], this.ssrClasses = /* @__PURE__ */ new Set(), this.observedOnce = !1, this.getCategory = (s) => y(s, this.context).utility?.category;
418
- const e = {};
419
- this.options = {
420
- config: t.config || e,
421
- styleId: t.styleId || "barocss-runtime",
422
- insertionPoint: t.insertionPoint || "head",
423
- maxRulesPerPartition: t.maxRulesPerPartition || 50,
424
- skipExisting: t.skipExisting ?? !1,
425
- gc: t.gc ?? !0,
426
- gcGraceMs: t.gcGraceMs ?? 3e3,
427
- maxRules: t.maxRules ?? 1 / 0
428
- }, this.context = p(this.options.config), this.incrementalParser = new C(this.context), this.changeDetector = new E(this.incrementalParser, this, this.getCategory), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.options.gc && (this.gc = new T({
429
- reclaim: (s) => this.reclaim(s),
430
- isPermanent: (s) => this.isPermanent(s),
431
- cachedCount: () => this.cache.size
432
- }, this.options.gcGraceMs, this.options.maxRules), this.changeDetector.setGc(this.gc)), this.init();
433
- }
434
- // Debugging and logging helpers
435
- /**
436
- * Add debug logs (by level)
437
- */
438
- debugLog(t, e, s) {
439
- (console[t] || console.log)(`[BrowserRuntime:${t.toUpperCase()}] ${e}`, s || "");
440
- }
441
- init() {
442
- console.log("[BrowserRuntime] init"), this.injectPreflightCSS(), this.ensureCssVars(), this.adoptSsrSheets();
443
- }
444
- /**
445
- * #268: adopt the class rules of server-rendered `<style data-barocss-ssr>` sheets in <head>, at startup
446
- * (constructor and the first observe()). Each rule moves
447
- * (same task, so no paint in between) into the partition its class would get if generated here, at
448
- * its #254 sorted position, so a later client `sm:` rule lands before a server `lg:` rule. Its classes
449
- * are never regenerated and never reclaimed. `:root`, `@property` and `@keyframes` stay in the sheet.
450
- */
451
- adoptSsrSheets() {
452
- if (typeof document > "u") return;
453
- const t = [];
454
- if (document.head) {
455
- for (const e of Array.from(document.head.querySelectorAll(`${D}:not([data-barocss-adopted])`))) {
456
- const s = e.sheet;
457
- if (!s) continue;
458
- e.setAttribute("data-barocss-adopted", "");
459
- const i = [];
460
- for (let r = s.cssRules.length - 1; r >= 0; r--) {
461
- const n = s.cssRules[r], o = g([n]);
462
- o.size !== 0 && (o.forEach((c) => this.ssrClasses.add(c)), i.unshift({ css: n.cssText, cls: o.values().next().value }), s.deleteRule(r));
463
- }
464
- t.push(...i);
465
- }
466
- t.length !== 0 && (this.ssrRules.push(...t), this.insertSsrRules(t));
467
- }
468
- }
469
- insertSsrRules(t) {
470
- for (const { css: e, cls: s } of t) {
471
- const i = this.getCategory(s);
472
- i ? this.stylePartitionManager.addCategoryRule(e, i) : this.stylePartitionManager.addRule(e);
473
- }
474
- }
475
- injectPreflightCSS() {
476
- const t = this.options.config.preflight ?? !0;
477
- if (t) {
478
- const e = this.context.getPreflightCSS(t);
479
- this.stylePartitionManager.updateRuleContent(
480
- "preflight",
481
- `${L}
482
- @layer base {
483
- ${e}
484
- }`,
485
- !0
486
- );
487
- }
488
- }
489
- ensureCssVars() {
490
- if (this.isDestroyed) return;
491
- const t = this.context.themeToCssVars ? this.context.themeToCssVars() : ":root { /* CSS Variables will be generated here */ }";
492
- this.stylePartitionManager.updateRuleContent("css-vars", t);
493
- }
494
- getInsertionPoint() {
495
- if (typeof this.options.insertionPoint != "string")
496
- return this.options.insertionPoint;
497
- switch (this.options.insertionPoint) {
498
- case "body":
499
- return document.body || document.head;
500
- case "head":
501
- default:
502
- return document.head;
503
- }
504
- }
505
- /**
506
- * Dynamically add one or more class names and generate/insert CSS
507
- */
508
- addClass(t) {
509
- if (this.isDestroyed) return;
510
- const e = this.normalizeClasses(t).filter(Boolean);
511
- e.forEach((s) => this.pinned.add(s)), this.processClasses(e);
512
- }
513
- /**
514
- * Process classes
515
- */
516
- processClasses(t) {
517
- this.processClassesIncremental(t);
518
- }
519
- /**
520
- * Process classes using incremental parsing
521
- */
522
- processClassesIncremental(t) {
523
- const e = typeof window < "u", s = this.incrementalParser.processClasses(t);
524
- console.log("[BrowserRuntime] results", s, ...t), this.applyParseResults(s, { isBrowser: e });
525
- }
526
- /**
527
- * Public method to apply parser results, update internal caches, and inject CSS
528
- */
529
- applyParseResults(t, e) {
530
- if (this.isDestroyed) return;
531
- if (this.getInsertionPoint().isConnected && this.stylePartitionManager.hasDetachedPartitions()) {
532
- const n = Array.from(this.cache.values());
533
- this.reset(), t = [...n, ...t], t.forEach((o) => this.incrementalParser.markProcessed(o.cls));
534
- }
535
- if (this.ssrClasses.size > 0 && (t = t.filter((n) => !this.ssrClasses.has(n.cls))), this.options.skipExisting && t.length > 0 && typeof document < "u") {
536
- const n = this.getExistingClasses();
537
- t = t.filter((o) => !n.has(o.cls));
538
- }
539
- if (t.length === 0) return;
540
- const s = [], i = [], r = this.options.skipExisting && typeof document < "u" ? (this.getExistingClasses(), this.existingKeyframes) : null;
541
- for (const n of t)
542
- if (n.css && Array.isArray(n.cssList) && (s.push(n), this.cache.set(n.cls, n)), n.rootCss && Array.isArray(n.rootCssList))
543
- for (const o of n.rootCssList) {
544
- if (r?.size) {
545
- const c = /^\s*@keyframes\s+([^\s{]+)/.exec(o)?.[1];
546
- if (c && r.has(c)) continue;
547
- }
548
- this.rootCache.has(o) || (this.rootCache.add(o), i.push(o));
549
- }
550
- i.length > 0 && this.stylePartitionManager.addRootRules(i.filter(Boolean)), s.length > 0 && this.stylePartitionManager.addRules(s), this.debugLog("info", `Applied ${t.length} parser results`, {
551
- cssRuleCount: s.length,
552
- rootCssCount: i.length
553
- });
554
- }
555
- /** #269: a class that must never be reclaimed. */
556
- isPermanent(t) {
557
- return this.pinned.has(t) || this.ssrClasses.has(t) || typeof document > "u" ? !0 : this.getExistingClasses().has(t);
558
- }
559
- /**
560
- * #269: delete the generated rules of classes no live element uses. Root/@property/@keyframes rules stay
561
- * (they are shared and harmless); a rule text another cached class still emits is kept.
562
- */
563
- reclaim(t) {
564
- if (this.isDestroyed) return;
565
- const e = t.filter((r) => this.cache.has(r));
566
- if (e.length === 0) return;
567
- const s = e.map((r) => this.cache.get(r));
568
- e.forEach((r) => {
569
- this.cache.delete(r), this.incrementalParser.unmarkProcessed(r);
570
- });
571
- const i = /* @__PURE__ */ new Set();
572
- for (const r of this.cache.values()) r.cssList.forEach((n) => i.add(n));
573
- for (const r of s) {
574
- const n = this.getCategory(r.cls);
575
- for (const o of r.cssList)
576
- i.has(o) || this.stylePartitionManager.removeRule(o, n);
577
- }
578
- this.reclaimedCount += e.length;
579
- }
580
- /** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
581
- getExistingClasses() {
582
- const t = new Set(Array.from(document.querySelectorAll("style[data-barocss]"), (r) => r.sheet)), e = Array.from(document.styleSheets).filter((r) => {
583
- if (t.has(r)) return !1;
584
- const n = r.ownerNode;
585
- return !(n && typeof n.hasAttribute == "function" && (n.hasAttribute("data-barocss") || (n.id || "").startsWith(this.options.styleId)));
586
- });
587
- if (this.existing && e.length === this.existingSheetCount) return this.existing;
588
- const s = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
589
- for (const r of e) {
590
- let n;
591
- try {
592
- n = r.cssRules;
593
- } catch {
594
- continue;
595
- }
596
- g(n, s), P(n, i);
597
- }
598
- return this.existingKeyframes = i, this.existing = s, this.existingSheetCount = e.length, s;
599
- }
600
- /**
601
- * MutationObserver instance method to automatically call addClass when class attributes change in DOM
602
- */
603
- observe(t = document.body, e) {
604
- return this.observedOnce || (this.observedOnce = !0, this.adoptSsrSheets()), this.changeDetector.observe(t, e);
605
- }
606
- normalizeClasses(t) {
607
- return Array.isArray(t) ? t.flatMap((e) => e.split(/\s+/)) : t.split(/\s+/);
608
- }
609
- has(t) {
610
- return this.cache.has(t);
611
- }
612
- getCss(t) {
613
- return this.cache.get(t)?.cssList.join(`
614
- `);
615
- }
616
- getAllCss() {
617
- return [...this.rootCache, ...Array.from(this.cache.values()).flatMap((e) => e.cssList)].join(`
618
- `);
619
- }
620
- getClasses() {
621
- return Array.from(this.cache.keys());
622
- }
623
- /**
624
- * Get comprehensive cache statistics
625
- */
626
- getCacheStats() {
627
- const t = this.incrementalParser.getStats();
628
- return {
629
- runtime: {
630
- cachedClasses: this.cache.size,
631
- rootCacheSize: this.rootCache.size,
632
- ruleCount: this.stylePartitionManager.ruleCount,
633
- reclaimedClasses: this.reclaimedCount,
634
- gc: this.gc?.stats() ?? null
635
- },
636
- ast: t.cacheStats.ast,
637
- incremental: t
638
- };
639
- }
640
- /**
641
- * Clear all caches (useful for debugging or memory management)
642
- */
643
- clearCaches() {
644
- this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), x(this.context), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars(), this.insertSsrRules(this.ssrRules));
645
- }
646
- reset() {
647
- this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars(), this.insertSsrRules(this.ssrRules));
648
- }
649
- updateConfig(t) {
650
- if (this.isDestroyed) return;
651
- const e = Array.from(this.cache.keys());
652
- this.options.config = t, this.context = p(t), this.incrementalParser = new C(this.context), this.changeDetector.setParser(this.incrementalParser), this.reset(), e.length > 0 && this.addClass(e);
653
- }
654
- removeClass(t) {
655
- if (this.isDestroyed) return;
656
- const e = new Set(this.normalizeClasses(t)), s = Array.from(this.cache.values()).filter((i) => !e.has(i.cls));
657
- s.length !== this.cache.size && (this.reset(), s.forEach((i) => this.incrementalParser.markProcessed(i.cls)), this.applyParseResults(s));
658
- }
659
- destroy() {
660
- this.isDestroyed || (this.changeDetector.disconnect(), this.gc?.cancel(), this.stylePartitionManager.cleanup(), this.cache.clear(), this.rootCache.clear(), this.isDestroyed = !0);
661
- }
662
- getStats() {
663
- return {
664
- cachedClasses: this.cache.size,
665
- styleElementId: this.options.styleId,
666
- isDestroyed: this.isDestroyed,
667
- config: this.options.config,
668
- cacheStats: this.getCacheStats()
669
- };
670
- }
249
+ function g(e, t = /* @__PURE__ */ new Set()) {
250
+ for (let n of Array.from(e)) {
251
+ let e = n.selectorText;
252
+ if (typeof e == "string") for (let n of m(e)) {
253
+ let e = p.exec(n);
254
+ e && t.add(f(e[1]));
255
+ }
256
+ let r = n.cssRules;
257
+ r && r.length && g(r, t);
258
+ }
259
+ return t;
671
260
  }
672
- let h = null, f;
673
- function I(a = {}) {
674
- return !h || h.getStats().isDestroyed ? (h = new N(a), f = a.config) : a.config && a.config !== f && (h.updateConfig(a.config), f = a.config), h;
261
+ //#endregion
262
+ //#region src/class-gc.ts
263
+ var _ = class {
264
+ constructor(e, t, n, r = () => Date.now()) {
265
+ this.host = e, this.graceMs = t, this.maxRules = n, this.now = r, this.counts = /* @__PURE__ */ new Map(), this.counted = /* @__PURE__ */ new WeakMap(), this.candidates = /* @__PURE__ */ new Map(), this.timer = null, this.root = null;
266
+ }
267
+ setRoot(e) {
268
+ this.counts.clear(), this.counted = /* @__PURE__ */ new WeakMap(), this.candidates.clear(), this.cancel(), this.root = e, this.reconcileTree(e);
269
+ }
270
+ count(e) {
271
+ return this.counts.get(e) ?? 0;
272
+ }
273
+ reconcileTree(e) {
274
+ if (e.nodeType !== 1) return;
275
+ let t = e;
276
+ this.reconcile(t), t.querySelectorAll("[class]").forEach((e) => this.reconcile(e));
277
+ }
278
+ reconcile(e) {
279
+ let t = this.root, n = t && t.contains(e) ? Array.from(new Set(u(e.getAttribute("class")))) : [], r = this.counted.get(e);
280
+ if (!r && n.length === 0) return;
281
+ let i = new Set(r ?? []), a = new Set(n);
282
+ for (let e of a) {
283
+ if (i.has(e)) continue;
284
+ let t = (this.counts.get(e) ?? 0) + 1;
285
+ this.counts.set(e, t), this.candidates.delete(e);
286
+ }
287
+ for (let e of i) {
288
+ if (a.has(e)) continue;
289
+ let t = (this.counts.get(e) ?? 0) - 1;
290
+ t > 0 ? this.counts.set(e, t) : (this.counts.delete(e), this.candidates.delete(e), this.candidates.set(e, this.now()));
291
+ }
292
+ n.length ? this.counted.set(e, n) : this.counted.delete(e);
293
+ }
294
+ afterBatch() {
295
+ this.candidates.size !== 0 && (this.host.cachedCount() > this.maxRules ? this.schedule(0) : this.schedule(this.graceMs));
296
+ }
297
+ schedule(e) {
298
+ if (this.timer !== null) {
299
+ if (e > 0) return;
300
+ clearTimeout(this.timer);
301
+ }
302
+ this.timer = setTimeout(() => {
303
+ this.timer = null, this.sweep();
304
+ }, e);
305
+ }
306
+ sweep() {
307
+ let e = this.now(), t = Math.max(0, this.host.cachedCount() - this.maxRules), n = [], r = 0;
308
+ for (let [i, a] of this.candidates) {
309
+ let o = e - a >= this.graceMs;
310
+ !o && r >= t || (this.candidates.delete(i), !(this.count(i) > 0 || this.inDom(i) || this.host.isPermanent(i)) && (n.push(i), o || r++));
311
+ }
312
+ n.length && this.host.reclaim(n), this.candidates.size && this.schedule(this.graceMs);
313
+ }
314
+ inDom(e) {
315
+ let t = this.root;
316
+ if (!t) return !1;
317
+ let n = t.ownerDocument ?? document;
318
+ return t.classList.contains(e) || n.documentElement.classList.contains(e) || n.getElementsByClassName(e).length > 0;
319
+ }
320
+ cancel() {
321
+ this.timer !== null && clearTimeout(this.timer), this.timer = null;
322
+ }
323
+ stats() {
324
+ return {
325
+ trackedClasses: this.counts.size,
326
+ candidates: this.candidates.size
327
+ };
328
+ }
329
+ }, v = "style[data-barocss-ssr]", y = "@layer theme, base, components, utilities;", b = class {
330
+ constructor(t = {}) {
331
+ this.cache = /* @__PURE__ */ new Map(), this.rootCache = /* @__PURE__ */ new Set(), this.isDestroyed = !1, this.existing = null, this.existingKeyframes = /* @__PURE__ */ new Set(), this.existingSheetCount = -1, this.pinned = /* @__PURE__ */ new Set(), this.gc = null, this.reclaimedCount = 0, this.ssrRules = [], this.ssrClasses = /* @__PURE__ */ new Set(), this.observedOnce = !1, this.getCategory = (e) => a(e, this.context).utility?.category;
332
+ let n = {};
333
+ this.options = {
334
+ config: t.config || n,
335
+ styleId: t.styleId || "barocss-runtime",
336
+ insertionPoint: t.insertionPoint || "head",
337
+ maxRulesPerPartition: t.maxRulesPerPartition || 50,
338
+ skipExisting: t.skipExisting ?? !1,
339
+ gc: t.gc ?? !0,
340
+ gcGraceMs: t.gcGraceMs ?? 3e3,
341
+ maxRules: t.maxRules ?? Infinity
342
+ }, this.context = r(this.options.config), this.incrementalParser = new e(this.context), this.changeDetector = new d(this.incrementalParser, this, this.getCategory), this.stylePartitionManager = new c(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.options.gc && (this.gc = new _({
343
+ reclaim: (e) => this.reclaim(e),
344
+ isPermanent: (e) => this.isPermanent(e),
345
+ cachedCount: () => this.cache.size
346
+ }, this.options.gcGraceMs, this.options.maxRules), this.changeDetector.setGc(this.gc)), this.init();
347
+ }
348
+ debugLog(e, t, n) {
349
+ i() && (console[e] || console.log)(`[BrowserRuntime:${e.toUpperCase()}] ${t}`, n || "");
350
+ }
351
+ init() {
352
+ this.debugLog("debug", "init"), this.injectPreflightCSS(), this.ensureCssVars(), this.adoptSsrSheets();
353
+ }
354
+ adoptSsrSheets() {
355
+ if (typeof document > "u") return;
356
+ let e = [];
357
+ if (document.head) {
358
+ for (let t of Array.from(document.head.querySelectorAll(`${v}:not([data-barocss-adopted])`))) {
359
+ let n = t.sheet;
360
+ if (!n) continue;
361
+ t.setAttribute("data-barocss-adopted", "");
362
+ let r = [];
363
+ for (let e = n.cssRules.length - 1; e >= 0; e--) {
364
+ let t = n.cssRules[e], i = g([t]);
365
+ i.size !== 0 && (i.forEach((e) => this.ssrClasses.add(e)), r.unshift({
366
+ css: t.cssText,
367
+ cls: i.values().next().value
368
+ }), n.deleteRule(e));
369
+ }
370
+ e.push(...r);
371
+ }
372
+ e.length !== 0 && (this.ssrRules.push(...e), this.insertSsrRules(e));
373
+ }
374
+ }
375
+ insertSsrRules(e) {
376
+ for (let { css: t, cls: n } of e) {
377
+ let e = this.getCategory(n);
378
+ e ? this.stylePartitionManager.addCategoryRule(t, e) : this.stylePartitionManager.addRule(t);
379
+ }
380
+ }
381
+ injectPreflightCSS() {
382
+ let e = this.options.config.preflight ?? !0;
383
+ if (e) {
384
+ let t = this.context.getPreflightCSS(e);
385
+ this.stylePartitionManager.updateRuleContent("preflight", `${y}\n@layer base {\n${t}\n}`, !0);
386
+ }
387
+ }
388
+ ensureCssVars() {
389
+ if (this.isDestroyed) return;
390
+ let e = this.context.themeToCssVars ? this.context.themeToCssVars() : ":root { /* CSS Variables will be generated here */ }";
391
+ this.stylePartitionManager.updateRuleContent("css-vars", e);
392
+ }
393
+ getInsertionPoint() {
394
+ if (typeof this.options.insertionPoint != "string") return this.options.insertionPoint;
395
+ switch (this.options.insertionPoint) {
396
+ case "body": return document.body || document.head;
397
+ default: return document.head;
398
+ }
399
+ }
400
+ addClass(e) {
401
+ if (this.isDestroyed) return;
402
+ let t = this.normalizeClasses(e).filter(Boolean);
403
+ t.forEach((e) => this.pinned.add(e)), this.processClasses(t);
404
+ }
405
+ processClasses(e) {
406
+ this.processClassesIncremental(e);
407
+ }
408
+ processClassesIncremental(e) {
409
+ let t = typeof window < "u", n = this.incrementalParser.processClasses(e);
410
+ this.debugLog("debug", "results", {
411
+ results: n,
412
+ classList: e
413
+ }), this.applyParseResults(n, { isBrowser: t });
414
+ }
415
+ applyParseResults(e, t) {
416
+ if (this.isDestroyed) return;
417
+ if (this.getInsertionPoint().isConnected && this.stylePartitionManager.hasDetachedPartitions()) {
418
+ let t = Array.from(this.cache.values());
419
+ this.reset(), e = [...t, ...e], e.forEach((e) => this.incrementalParser.markProcessed(e.cls));
420
+ }
421
+ if (this.ssrClasses.size > 0 && (e = e.filter((e) => !this.ssrClasses.has(e.cls))), this.options.skipExisting && e.length > 0 && typeof document < "u") {
422
+ let t = this.getExistingClasses();
423
+ e = e.filter((e) => !t.has(e.cls));
424
+ }
425
+ if (e.length === 0) return;
426
+ let n = [], r = [], i = this.options.skipExisting && typeof document < "u" ? (this.getExistingClasses(), this.existingKeyframes) : null;
427
+ for (let t of e) if (t.css && Array.isArray(t.cssList) && (n.push(t), this.cache.set(t.cls, t)), t.rootCss && Array.isArray(t.rootCssList)) for (let e of t.rootCssList) {
428
+ if (i?.size) {
429
+ let t = /^\s*@keyframes\s+([^\s{]+)/.exec(e)?.[1];
430
+ if (t && i.has(t)) continue;
431
+ }
432
+ this.rootCache.has(e) || (this.rootCache.add(e), r.push(e));
433
+ }
434
+ r.length > 0 && this.stylePartitionManager.addRootRules(r.filter(Boolean)), n.length > 0 && this.stylePartitionManager.addRules(n), this.debugLog("info", `Applied ${e.length} parser results`, {
435
+ cssRuleCount: n.length,
436
+ rootCssCount: r.length
437
+ });
438
+ }
439
+ isPermanent(e) {
440
+ return this.pinned.has(e) || this.ssrClasses.has(e) || typeof document > "u" ? !0 : this.getExistingClasses().has(e);
441
+ }
442
+ reclaim(e) {
443
+ if (this.isDestroyed) return;
444
+ let t = e.filter((e) => this.cache.has(e));
445
+ if (t.length === 0) return;
446
+ let n = t.map((e) => this.cache.get(e));
447
+ t.forEach((e) => {
448
+ this.cache.delete(e), this.incrementalParser.unmarkProcessed(e);
449
+ });
450
+ let r = /* @__PURE__ */ new Set();
451
+ for (let e of this.cache.values()) e.cssList.forEach((e) => r.add(e));
452
+ for (let e of n) {
453
+ let t = this.getCategory(e.cls);
454
+ for (let n of e.cssList) r.has(n) || this.stylePartitionManager.removeRule(n, t);
455
+ }
456
+ this.reclaimedCount += t.length;
457
+ }
458
+ getExistingClasses() {
459
+ let e = new Set(Array.from(document.querySelectorAll("style[data-barocss]"), (e) => e.sheet)), t = Array.from(document.styleSheets).filter((t) => {
460
+ if (e.has(t)) return !1;
461
+ let n = t.ownerNode;
462
+ return !(n && typeof n.hasAttribute == "function" && (n.hasAttribute("data-barocss") || (n.id || "").startsWith(this.options.styleId)));
463
+ });
464
+ if (this.existing && t.length === this.existingSheetCount) return this.existing;
465
+ let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
466
+ for (let e of t) {
467
+ let t;
468
+ try {
469
+ t = e.cssRules;
470
+ } catch {
471
+ continue;
472
+ }
473
+ g(t, n), h(t, r);
474
+ }
475
+ return this.existingKeyframes = r, this.existing = n, this.existingSheetCount = t.length, n;
476
+ }
477
+ observe(e = document.body, t) {
478
+ return this.observedOnce || (this.observedOnce = !0, this.adoptSsrSheets()), this.changeDetector.observe(e, t);
479
+ }
480
+ normalizeClasses(e) {
481
+ return Array.isArray(e) ? e.flatMap((e) => e.split(/\s+/)) : e.split(/\s+/);
482
+ }
483
+ has(e) {
484
+ return this.cache.has(e);
485
+ }
486
+ getCss(e) {
487
+ return this.cache.get(e)?.cssList.join("\n");
488
+ }
489
+ getAllCss() {
490
+ return [...this.rootCache, ...Array.from(this.cache.values()).flatMap((e) => e.cssList)].join("\n");
491
+ }
492
+ getClasses() {
493
+ return Array.from(this.cache.keys());
494
+ }
495
+ getCacheStats() {
496
+ let e = this.incrementalParser.getStats();
497
+ return {
498
+ runtime: {
499
+ cachedClasses: this.cache.size,
500
+ rootCacheSize: this.rootCache.size,
501
+ ruleCount: this.stylePartitionManager.ruleCount,
502
+ reclaimedClasses: this.reclaimedCount,
503
+ gc: this.gc?.stats() ?? null
504
+ },
505
+ ast: e.cacheStats.ast,
506
+ incremental: e
507
+ };
508
+ }
509
+ clearCaches() {
510
+ this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), t(this.context), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new c(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars(), this.insertSsrRules(this.ssrRules));
511
+ }
512
+ reset() {
513
+ this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new c(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars(), this.insertSsrRules(this.ssrRules));
514
+ }
515
+ updateConfig(t) {
516
+ if (this.isDestroyed) return;
517
+ let n = Array.from(this.cache.keys());
518
+ this.options.config = t, this.context = r(t), this.incrementalParser = new e(this.context), this.changeDetector.setParser(this.incrementalParser), this.reset(), n.length > 0 && this.addClass(n);
519
+ }
520
+ removeClass(e) {
521
+ if (this.isDestroyed) return;
522
+ let t = new Set(this.normalizeClasses(e)), n = Array.from(this.cache.values()).filter((e) => !t.has(e.cls));
523
+ n.length !== this.cache.size && (this.reset(), n.forEach((e) => this.incrementalParser.markProcessed(e.cls)), this.applyParseResults(n));
524
+ }
525
+ destroy() {
526
+ this.isDestroyed ||= (this.changeDetector.disconnect(), this.gc?.cancel(), this.stylePartitionManager.cleanup(), this.cache.clear(), this.rootCache.clear(), !0);
527
+ }
528
+ getStats() {
529
+ return {
530
+ cachedClasses: this.cache.size,
531
+ styleElementId: this.options.styleId,
532
+ isDestroyed: this.isDestroyed,
533
+ config: this.options.config,
534
+ cacheStats: this.getCacheStats()
535
+ };
536
+ }
537
+ }, x = null, S;
538
+ function C(e = {}) {
539
+ return !x || x.getStats().isDestroyed ? (x = new b(e), S = e.config) : e.config && e.config !== S && (x.updateConfig(e.config), S = e.config), x;
675
540
  }
676
- function R({ loadingClassName: a = "baro-boot", ...t } = {}) {
677
- if (!document.body) {
678
- document.addEventListener("DOMContentLoaded", () => R({ loadingClassName: a, ...t }), { once: !0 });
679
- return;
680
- }
681
- const e = `${a}-doing`, s = `${a}-done`;
682
- try {
683
- document.body.classList.add(e), I(t).observe(document.body, { scan: !0, onReady: () => {
684
- document.body.classList.remove(e), document.body.classList.add(s);
685
- } });
686
- } catch (i) {
687
- document.body?.classList.remove(e), console.error("BaroCSS boot failed:", i);
688
- }
541
+ function w({ loadingClassName: e = "baro-boot", ...t } = {}) {
542
+ if (!document.body) {
543
+ document.addEventListener("DOMContentLoaded", () => w({
544
+ loadingClassName: e,
545
+ ...t
546
+ }), { once: !0 });
547
+ return;
548
+ }
549
+ let n = `${e}-doing`, r = `${e}-done`;
550
+ try {
551
+ document.body.classList.add(n), C(t).observe(document.body, {
552
+ scan: !0,
553
+ onReady: () => {
554
+ document.body.classList.remove(n), document.body.classList.add(r);
555
+ }
556
+ });
557
+ } catch (e) {
558
+ document.body?.classList.remove(n), console.error("BaroCSS boot failed:", e);
559
+ }
689
560
  }
690
- const $ = R;
691
- function k(a) {
692
- if (!a || typeof a != "object" || Array.isArray(a)) return [];
693
- const t = a.elements;
694
- if (!t || typeof t != "object" || Array.isArray(t)) return [];
695
- const e = /* @__PURE__ */ new Set();
696
- for (const s of Object.keys(t)) {
697
- const i = t[s];
698
- if (!i || typeof i != "object" || Array.isArray(i)) continue;
699
- const r = i.props;
700
- if (!r || typeof r != "object" || Array.isArray(r)) continue;
701
- const n = r.className;
702
- if (typeof n == "string")
703
- for (const o of n.split(/\s+/))
704
- o && e.add(o);
705
- }
706
- return Array.from(e);
561
+ var T = w;
562
+ //#endregion
563
+ //#region src/json-render-preload.ts
564
+ function E(e) {
565
+ if (!e || typeof e != "object" || Array.isArray(e)) return [];
566
+ let t = e.elements;
567
+ if (!t || typeof t != "object" || Array.isArray(t)) return [];
568
+ let n = /* @__PURE__ */ new Set();
569
+ for (let e of Object.keys(t)) {
570
+ let r = t[e];
571
+ if (!r || typeof r != "object" || Array.isArray(r)) continue;
572
+ let i = r.props;
573
+ if (!i || typeof i != "object" || Array.isArray(i)) continue;
574
+ let a = i.className;
575
+ if (typeof a == "string") for (let e of a.split(/\s+/)) e && n.add(e);
576
+ }
577
+ return Array.from(n);
707
578
  }
708
- function j(a, t) {
709
- const e = k(a);
710
- e.length > 0 && t.addClass(e);
579
+ function D(e, t) {
580
+ let n = E(e);
581
+ n.length > 0 && t.addClass(n);
711
582
  }
712
- const z = [
713
- "background",
714
- "foreground",
715
- "card",
716
- "card-foreground",
717
- "popover",
718
- "popover-foreground",
719
- "primary",
720
- "primary-foreground",
721
- "secondary",
722
- "secondary-foreground",
723
- "muted",
724
- "muted-foreground",
725
- "accent",
726
- "accent-foreground",
727
- "destructive",
728
- "border",
729
- "input",
730
- "ring",
731
- "chart-1",
732
- "chart-2",
733
- "chart-3",
734
- "chart-4",
735
- "chart-5",
736
- "sidebar",
737
- "sidebar-foreground",
738
- "sidebar-primary",
739
- "sidebar-primary-foreground",
740
- "sidebar-accent",
741
- "sidebar-accent-foreground",
742
- "sidebar-border",
743
- "sidebar-ring"
744
- ], O = {
745
- colors: Object.fromEntries(z.map((a) => [a, `var(--${a})`])),
746
- borderRadius: {
747
- sm: "calc(var(--radius) - 4px)",
748
- md: "calc(var(--radius) - 2px)",
749
- lg: "var(--radius)",
750
- xl: "calc(var(--radius) + 4px)"
751
- }
752
- };
753
- export {
754
- N as BrowserRuntime,
755
- E as ChangeDetector,
756
- L as LAYER_ORDER,
757
- D as SSR_STYLE_SELECTOR,
758
- d as StylePartitionManager,
759
- R as baroBoot,
760
- $ as baroStart,
761
- k as collectJsonRenderClassNames,
762
- I as getRuntime,
763
- w as normalizeClassName,
764
- u as normalizeClassNameList,
765
- j as preloadJsonRenderClasses,
766
- O as shadcnTheme
583
+ var O = {
584
+ colors: Object.fromEntries((/* @__PURE__ */ "background.foreground.card.card-foreground.popover.popover-foreground.primary.primary-foreground.secondary.secondary-foreground.muted.muted-foreground.accent.accent-foreground.destructive.border.input.ring.chart-1.chart-2.chart-3.chart-4.chart-5.sidebar.sidebar-foreground.sidebar-primary.sidebar-primary-foreground.sidebar-accent.sidebar-accent-foreground.sidebar-border.sidebar-ring".split(".")).map((e) => [e, `var(--${e})`])),
585
+ borderRadius: {
586
+ sm: "calc(var(--radius) - 4px)",
587
+ md: "calc(var(--radius) - 2px)",
588
+ lg: "var(--radius)",
589
+ xl: "calc(var(--radius) + 4px)"
590
+ }
767
591
  };
592
+ //#endregion
593
+ export { b as BrowserRuntime, d as ChangeDetector, y as LAYER_ORDER, v as SSR_STYLE_SELECTOR, c as StylePartitionManager, w as baroBoot, T as baroStart, E as collectJsonRenderClassNames, C as getRuntime, l as normalizeClassName, u as normalizeClassNameList, D as preloadJsonRenderClasses, O as shadcnTheme };