@barocss/browser 0.8.1 → 0.9.0
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/README.md +25 -0
- package/dist/cdn/barocss.js +2 -10069
- package/dist/cdn/barocss.js.map +1 -1
- package/dist/cdn/barocss.umd.cjs +2 -2
- package/dist/cdn/barocss.umd.cjs.map +1 -1
- package/dist/index.cjs +15 -0
- package/dist/index.d.cts +464 -0
- package/dist/index.d.ts +33 -4
- package/dist/index.es.js +819 -752
- package/dist/index.umd.js +12 -9
- package/package.json +12 -6
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@barocss/kit");var t=class{insertSorted(t,n,r){let i=t.keys??=[],a=(0,e.upperBound)(i,r),o=t.styleElement.sheet;o&&o.cssRules.length===i.length?(o.insertRule(this.escapeCssRule(n),a),t.styles.splice(a,0,n)):(t.styles.splice(a,0,n),t.styleElement.textContent=t.styles.join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`),i.splice(a,0,r)}constructor(t,n=50,r=`barocss-style-partition-`,i=t=>(0,e.parseClassName)(t).utility?.category){this.partitions=[],this.categoryPartitions=new Map,this.partitionCounter=0,this.maxRulesPerPartition=50,this.classToPartitionMap=new Map,this.classToCategoryPartitionMap=new Map,this.styleIdPrefix=`barocss-style-partition-`,this.insertionPoint=t,this.maxRulesPerPartition=n,this.styleIdPrefix=r,this.getCategory=i,this.initializeDefaultPartition()}initializeDefaultPartition(){this.createNewPartition()}createNewCategoryPartition(e,t=!1){let n={id:this.styleIdPrefix+`-${e}`,styles:[],styleElement:document.createElement(`style`)};n.styleElement.id=n.id,n.styleElement.setAttribute(`data-barocss`,`partition`),n.styleElement.setAttribute(`data-category`,e);let r=this.insertionPoint.ownerDocument?.head;return t&&r?r.insertBefore(n.styleElement,r.firstChild):this.insertionPoint.appendChild(n.styleElement),this.categoryPartitions.set(e,n),n}createNewPartition(){let e={id:this.styleIdPrefix+`-${this.partitionCounter++}`,styles:[],styleElement:document.createElement(`style`)};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}hasRule(e){return this.classToPartitionMap.has(e)}hasCategoryRule(e,t){return this.classToCategoryPartitionMap.get(e)===t}setRuleCache(e,t){this.classToPartitionMap.set(e,t)}setCategoryRuleCache(e,t){this.classToCategoryPartitionMap.set(e,t)}get currentPartition(){return this.partitions[this.partitions.length-1]}getCategoryPartition(e){return this.categoryPartitions.get(e)}hasDetachedPartitions(){return[...this.partitions,...this.categoryPartitions.values()].some(e=>!e.styleElement.isConnected)}escapeCssRule(e){return e.replace(/\\\//g,`\\/`)}addRule(t){if(this.hasRule(t))return!1;let n=(0,e.ruleSortKey)(t),r=this.partitions.findIndex(t=>{let r=t.keys;return!!r&&r.length>0&&(0,e.compareKeys)(r[r.length-1],n)>0});r===-1&&(this.currentPartition.styles.length>=this.maxRulesPerPartition&&this.createNewPartition(),r=this.partitions.length-1);let i=this.partitions[r];try{return this.insertSorted(i,t,n),this.setRuleCache(t,r),!0}catch(n){return(0,e.isDebug)()&&console.warn(`[StylePartitionManager] Failed to insert rule: ${t}`,n),!1}}addCategoryRule(t,n){if(this.hasCategoryRule(t,n))return!1;let r=this.getCategoryPartition(n);r||=this.createNewCategoryPartition(n);try{this.insertSorted(r,t,(0,e.ruleSortKey)(t))}catch(r){return(0,e.isDebug)()&&console.warn(`[StylePartitionManager] Failed to insert rule in category: ${n} ${t}`,r),!1}return this.setCategoryRuleCache(t,n),!0}addRootRules(t){let n=this.getCategoryPartition(`root`);n||=this.createNewCategoryPartition(`root`);try{let e=n.styleElement.sheet;for(let r of t)e?e.insertRule(this.escapeCssRule(r),e.cssRules.length):n.styleElement.textContent+=r+`
|
|
4
|
+
`}catch(n){return(0,e.isDebug)()&&console.warn(`[StylePartitionManager] Failed to insert rule in category: root ${t.join(`
|
|
5
|
+
`)}`,n),{success:0,failed:t.length}}return{success:t.length,failed:0}}addRules(e){let t=0,n=0;for(let r of e){let e=this.getCategory(r.cls);if(e)for(let t of r.cssList)this.addCategoryRule(t,e);else for(let e of r.cssList)this.addRule(e)?t++:n++}return{success:t,failed:n}}removeRule(e,t){let n;if(t){if(this.classToCategoryPartitionMap.get(e)!==t)return!1;n=this.categoryPartitions.get(t)}else{let t=this.classToPartitionMap.get(e);n=t===void 0?void 0:this.partitions[t]}if(!n)return!1;let r=n.styles.indexOf(e);if(r===-1)return!1;let i=n.styleElement.sheet,a=!!i&&i.cssRules.length===n.styles.length;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(`
|
|
6
|
+
`)+`
|
|
7
|
+
`:``,t?this.classToCategoryPartitionMap.delete(e):this.classToPartitionMap.delete(e),!0}get ruleCount(){return this.classToPartitionMap.size+this.classToCategoryPartitionMap.size}findRulePartition(e){let t=this.classToPartitionMap.get(e);if(t!==void 0&&this.partitions[t])return this.partitions[t];let n=this.classToCategoryPartitionMap.get(e);return n===void 0?null:this.categoryPartitions.get(n)||null}updateRuleContent(t,n,r=!1){let i=this.getCategoryPartition(t);if(i)i.styleElement.textContent=n;else{let i=this.createNewCategoryPartition(t,r);(0,e.isDebug)()&&console.log(`[StylePartitionManager] Created new partition for category: ${t}`),i.styleElement.textContent=n}}cleanup(){this.partitions.forEach(e=>{e.styleElement.parentNode&&e.styleElement.parentNode.removeChild(e.styleElement)}),this.categoryPartitions.forEach(e=>{e.styleElement.parentNode&&e.styleElement.parentNode.removeChild(e.styleElement)}),this.partitions=[],this.categoryPartitions.clear(),this.partitionCounter=0,this.classToPartitionMap.clear(),this.classToCategoryPartitionMap.clear()}};function n(e){return e?typeof e==`object`&&typeof e.baseVal==`string`?e.baseVal:e.toString():``}function r(e){return e?n(e).split(/\s+/).filter(Boolean):[]}var i=class{constructor(t,n,r=t=>(0,e.parseClassName)(t).utility?.category){this.observer=null,this.gc=null,this.incrementalParser=t,this.BrowserRuntime=n,this.getCategory=r}setGc(e){this.gc=e}setParser(e){this.incrementalParser=e}observe(e=document.body,t){return typeof window>`u`?new MutationObserver(()=>{}):(this.observer&&this.observer.disconnect(),this.gc?.setRoot(e),this.observer=new MutationObserver(t=>{let n=new Set,i=this.gc;if(t.forEach(t=>{if(i&&(t.type===`attributes`?i.reconcile(t.target):t.type===`childList`&&(t.removedNodes.forEach(e=>i.reconcileTree(e)),t.addedNodes.forEach(e=>i.reconcileTree(e)))),t.type===`attributes`&&t.attributeName===`class`&&e.contains(t.target)){let e=t.target;e.className&&r(e.className).forEach(e=>{this.incrementalParser.isProcessed(e)||n.add(e)})}t.type===`childList`&&t.addedNodes.forEach(t=>{if(t.nodeType===Node.ELEMENT_NODE&&e.contains(t)){let e=t;this.processElement(e,n),e.querySelectorAll(`[class]`).forEach(e=>{this.processElement(e,n)})}})}),n.size>0){let e=Array.from(n),t=this.incrementalParser.processClasses(e);this.BrowserRuntime?.applyParseResults(t)}else this.BrowserRuntime?.applyParseResults([]);i?.afterBatch()}),this.observer.observe(e,{attributes:!0,subtree:!0,attributeFilter:[`class`],childList:!0}),t?.scan&&this.scanExistingClasses(e,t),this.observer)}scanExistingClasses(e,t){let n=new Set,i=e.className;i&&r(i).forEach(e=>{this.incrementalParser.isProcessed(e)||n.add(e)});let a=e.querySelectorAll(`[class]`);for(let e of a)if(e.className){let t=r(e.className);for(let e of t)this.incrementalParser.isProcessed(e)||n.add(e)}if(n.size>0){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`);this.BrowserRuntime?.applyParseResults(i),t?.onReady?.(),this.BrowserRuntime?.applyParseResults(a)}else t?.onReady?.()}processElement(e,t){e.className&&r(e.className).forEach(e=>{this.incrementalParser.isProcessed(e)||t.add(e)})}disconnect(){this.observer&&=(this.observer.disconnect(),null)}};function a(e){return e.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g,(e,t,n)=>t?String.fromCodePoint(parseInt(t,16)):n)}var o=/^\s*(?::(?:where|is)\(\s*)?\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;function s(e){let t=[],n=0,r=0;for(let i=0;i<e.length;i++){let a=e[i];a===`\\`?i++:a===`(`||a===`[`?n++:a===`)`||a===`]`?n--:a===`,`&&n===0&&(t.push(e.slice(r,i)),r=i+1)}return t.push(e.slice(r)),t}function c(e,t=new Set){for(let n of Array.from(e)){if(n.type===7&&typeof n.name==`string`){t.add(n.name);continue}let e=n.cssRules;e&&e.length&&c(e,t)}return t}function l(e,t=new Set){for(let n of Array.from(e)){let e=n.selectorText;if(typeof e==`string`)for(let n of s(e)){let e=o.exec(n);e&&t.add(a(e[1]))}let r=n.cssRules;r&&r.length&&l(r,t)}return t}var u=class{constructor(e,t,n,r=()=>Date.now()){this.host=e,this.graceMs=t,this.maxRules=n,this.now=r,this.counts=new Map,this.counted=new WeakMap,this.candidates=new Map,this.timer=null,this.root=null}setRoot(e){this.counts.clear(),this.counted=new WeakMap,this.candidates.clear(),this.cancel(),this.root=e,e.nodeType===1?this.reconcileTree(e):e.querySelectorAll(`[class]`).forEach(e=>this.reconcile(e))}count(e){return this.counts.get(e)??0}reconcileTree(e){if(e.nodeType!==1)return;let t=e;this.reconcile(t),t.querySelectorAll(`[class]`).forEach(e=>this.reconcile(e))}reconcile(e){let t=this.root,n=t&&t.contains(e)?Array.from(new Set(r(e.getAttribute(`class`)))):[],i=this.counted.get(e);if(!i&&n.length===0)return;let a=new Set(i??[]),o=new Set(n);for(let e of o){if(a.has(e))continue;let t=(this.counts.get(e)??0)+1;this.counts.set(e,t),this.candidates.delete(e)}for(let e of a){if(o.has(e))continue;let t=(this.counts.get(e)??0)-1;t>0?this.counts.set(e,t):(this.counts.delete(e),this.candidates.delete(e),this.candidates.set(e,this.now()))}n.length?this.counted.set(e,n):this.counted.delete(e)}afterBatch(){this.candidates.size!==0&&(this.host.cachedCount()>this.maxRules?this.schedule(0):this.schedule(this.graceMs))}schedule(e){if(this.timer!==null){if(e>0)return;clearTimeout(this.timer)}this.timer=setTimeout(()=>{this.timer=null,this.sweep()},e)}sweep(){let e=this.now(),t=Math.max(0,this.host.cachedCount()-this.maxRules),n=[],r=0;for(let[i,a]of this.candidates){let o=e-a>=this.graceMs;!o&&r>=t||(this.candidates.delete(i),!(this.count(i)>0||this.inDom(i)||this.host.isPermanent(i))&&(n.push(i),o||r++))}n.length&&this.host.reclaim(n),this.candidates.size&&this.schedule(this.graceMs)}inDom(e){let t=this.root;if(!t)return!1;if(t.nodeType!==1)return Array.from(t.querySelectorAll(`[class]`)).some(t=>t.classList.contains(e));let n=t.ownerDocument??document;return t.classList.contains(e)||n.documentElement.classList.contains(e)||n.getElementsByClassName(e).length>0}cancel(){this.timer!==null&&clearTimeout(this.timer),this.timer=null}stats(){return{trackedClasses:this.counts.size,candidates:this.candidates.size}}};function d(e){let t=[],n=e.replace(/\/\*[\s\S]*?\*\//g,``);return n=n.replace(/(?<=^|[{};])(\s*)([^{};@\s][^{};]*?)\{([^{}]*)\}/g,(e,n,r,i)=>{let a=r.split(`,`).map(e=>e.trim()).filter(Boolean);if(a.includes(`body`))for(let e of i.split(`;`).map(e=>e.trim()).filter(Boolean))/^(min-height|scroll-behavior)\s*:/.test(e)||t.push(e);let o=Array.from(new Set(a.filter(e=>e!==`body`).map(e=>e===`html`||e===`:root`?`:host`:e)));return o.length===0?``:`${n}${o.join(`, `)} {${i}}`}),t.length&&(n+=`\n@layer base {\n:host {\n ${t.join(`;
|
|
8
|
+
`)};\n}\n}\n`),n}function f(e){return JSON.stringify(e,(e,t)=>typeof t==`function`?`fn:${String(t)}`:t instanceof RegExp?`re:${t}`:t)??``}function p(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function m(){try{return typeof ShadowRoot<`u`&&`adoptedStyleSheets`in ShadowRoot.prototype&&typeof CSSStyleSheet==`function`&&typeof new CSSStyleSheet().replaceSync==`function`}catch{return!1}}var h=e=>e.replace(/\\\//g,`\\/`),g=class{constructor(t,n,r=t){this.results=new Map,this.generations=0,this.prologueSheet=null,this.rulesSheet=null,this.prologue={preflight:``,vars:``},this.segments=new Map([[`root`,{rules:[],keys:[]}],[``,{rules:[],keys:[]}]]),this.refs=new Map,this.attached=[],this.key=t,this.fullKey=r,this.context=(0,e.createContext)(n),this.constructable=m(),this.constructable&&(this.prologueSheet=new CSSStyleSheet,this.rulesSheet=new CSSStyleSheet)}get rootCount(){return this.attached.length}get ruleCount(){return this.refs.size}attach(e){if(this.attached.some(t=>t.root===e))return;if(this.prologueSheet&&this.rulesSheet){let t=[this.prologueSheet,this.rulesSheet];e.adoptedStyleSheets=[...e.adoptedStyleSheets.filter(e=>!t.includes(e)),...t],this.attached.push({root:e});return}let t=e.ownerDocument??document,n=t.createElement(`style`),r=t.createElement(`style`);n.setAttribute(`data-barocss`,`root-prologue`),r.setAttribute(`data-barocss`,`root`),n.textContent=this.prologueText(),r.textContent=this.allRules().join(`
|
|
9
|
+
`),e.insertBefore(r,e.firstChild),e.insertBefore(n,r),this.attached.push({root:e,styles:[n,r]})}detach(e){let t=this.attached.findIndex(t=>t.root===e);if(t===-1)return;let[n]=this.attached.splice(t,1);n.styles?n.styles.forEach(e=>e.remove()):e.adoptedStyleSheets&&=e.adoptedStyleSheets.filter(e=>e!==this.prologueSheet&&e!==this.rulesSheet)}setPrologue(e,t){if(this.prologue[e]===t)return;this.prologue[e]=t;let n=this.prologueText();this.prologueSheet&&this.prologueSheet.replaceSync(n);for(let e of this.attached)e.styles&&(e.styles[0].textContent=n)}prologueText(){return[this.prologue.preflight,this.prologue.vars].filter(Boolean).join(`
|
|
10
|
+
`)}allRules(){return Array.from(this.segments.values()).flatMap(e=>e.rules)}offset(e){let t=0;for(let n of this.segments.values()){if(n===e)return t;t+=n.rules.length}return t}retain(t,n){let r=this.refs.get(t);if(r!==void 0)return this.refs.set(t,r+1),!0;let i=this.segments.get(n);i||(i={rules:[],keys:[]},this.segments.set(n,i));let a=n===`root`,o=(0,e.ruleSortKey)(t),s=a?i.rules.length:(0,e.upperBound)(i.keys,o),c=this.offset(i)+s;try{this.insertAt(t,c)}catch(n){return(0,e.isDebug)()&&console.warn(`[BrowserRuntime] Failed to insert rule into shadow root sheet: ${t}`,n),!1}return i.rules.splice(s,0,t),i.keys.splice(s,0,o),this.refs.set(t,1),!0}release(e){let t=this.refs.get(e);if(t!==void 0){if(t>1){this.refs.set(e,t-1);return}this.refs.delete(e);for(let t of this.segments.values()){let n=t.rules.indexOf(e);if(n===-1)continue;let r=this.offset(t)+n;t.rules.splice(n,1),t.keys.splice(n,1),this.deleteAt(r);return}}}insertAt(e,t){let n=h(e);if(this.rulesSheet){this.rulesSheet.insertRule(n,t);return}let r=this.allRules().length;for(let i of this.attached){let a=i.styles[1],o=a.sheet;if(o&&o.cssRules.length===r)o.insertRule(n,t);else{let n=this.allRules();n.splice(t,0,e),a.textContent=n.join(`
|
|
11
|
+
`)}}}deleteAt(e){if(this.rulesSheet){this.rulesSheet.deleteRule(e);return}let t=this.allRules().length;for(let n of this.attached){let r=n.styles[1],i=r.sheet;i&&i.cssRules.length===t+1?i.deleteRule(e):r.textContent=this.allRules().join(`
|
|
12
|
+
`)}}cssText(){return[this.prologueText(),...this.allRules()].join(`
|
|
13
|
+
`)}},_=new Map;function v(e,t=p){let n=f(e),r=_.get(n);return r||(r=new g(t(n),e,n),_.set(n,r)),r}function y(e){e.rootCount===0&&_.get(e.fullKey)===e&&_.delete(e.fullKey)}var b=class extends e.IncrementalParser{constructor(e){super(e.context),this.shared=e}processClass(e){if(this.isProcessed(e))return null;let t=this.shared.results.get(e);if(t)return this.markProcessed(e),t;let n=super.processClass(e);return n&&(this.shared.results.set(e,n),this.shared.generations++),n}},x=class{constructor(t,n,r=t=>(0,e.parseClassName)(t).utility?.category){this.shared=t,this.root=n,this.getCategory=r,this.owned=new Set,t.attach(n)}hasDetachedPartitions(){return!1}updateRuleContent(e,t){e===`preflight`?this.shared.setPrologue(`preflight`,d(t)):e===`css-vars`&&this.shared.setPrologue(`vars`,t)}take(e,t){return this.owned.has(e)||!this.shared.retain(e,t)?!1:(this.owned.add(e),!0)}addRule(e){return this.take(e,``)}addCategoryRule(e,t){return this.take(e,`c:${t}`)}addRootRules(e){let t=0;for(let n of e)this.take(n,`root`)&&t++;return{success:t,failed:e.length-t}}addRules(e){let t=0,n=0;for(let r of e){let e=this.getCategory(r.cls);for(let i of r.cssList)(e?this.addCategoryRule(i,e):this.addRule(i))?t++:n++}return{success:t,failed:n}}removeRule(e,t){return this.owned.delete(e)?(this.shared.release(e),!0):!1}get ruleCount(){return this.owned.size}cleanup(){this.owned.forEach(e=>this.shared.release(e)),this.owned.clear(),this.shared.detach(this.root),y(this.shared)}},S=`style[data-barocss-ssr]`,C=`@layer theme, base, components, utilities;`,w=class{constructor(t={}){this.cache=new Map,this.rootCache=new Set,this.shadowRoot=null,this.isDestroyed=!1,this.existing=null,this.existingKeyframes=new Set,this.existingSheetCount=-1,this.pinned=new Set,this.gc=null,this.reclaimedCount=0,this.ssrRules=[],this.ssrClasses=new Set,this.observedOnce=!1,this.getCategory=t=>(0,e.parseClassName)(t,this.context).utility?.category;let n={};this.options={config:t.config||n,styleId:t.styleId||`barocss-runtime`,insertionPoint:t.insertionPoint||`head`,maxRulesPerPartition:t.maxRulesPerPartition||50,skipExisting:t.skipExisting??!1,gc:t.gc??!0,gcGraceMs:t.gcGraceMs??3e3,maxRules:t.maxRules??1/0};let r=t.root;if(r&&r.nodeType===11&&(this.shadowRoot=r),this.shadowRoot){let e=v(this.options.config);this.context=e.context,this.incrementalParser=new b(e)}else this.context=(0,e.createContext)(this.options.config),this.incrementalParser=new e.IncrementalParser(this.context);this.changeDetector=new i(this.incrementalParser,this,this.getCategory),this.stylePartitionManager=this.createStyles(),this.options.gc&&(this.gc=new u({reclaim:e=>this.reclaim(e),isPermanent:e=>this.isPermanent(e),cachedCount:()=>this.cache.size},this.options.gcGraceMs,this.options.maxRules),this.changeDetector.setGc(this.gc)),this.init(),this.shadowRoot&&this.observe(this.shadowRoot,{scan:!0})}createStyles(){if(this.shadowRoot){let e=this.incrementalParser.shared,t=v(this.options.config);return t!==e&&(e=t,this.context=e.context,this.incrementalParser=new b(e),this.changeDetector?.setParser(this.incrementalParser)),new x(e,this.shadowRoot,this.getCategory)}return new t(this.getInsertionPoint(),this.options.maxRulesPerPartition,`${this.options.styleId}-partition`,this.getCategory)}debugLog(t,n,r){(0,e.isDebug)()&&(console[t]||console.log)(`[BrowserRuntime:${t.toUpperCase()}] ${n}`,r||``)}init(){this.debugLog(`debug`,`init`),this.injectPreflightCSS(),this.ensureCssVars(),this.adoptSsrSheets()}adoptSsrSheets(){if(typeof document>`u`||this.shadowRoot)return;let e=[];if(document.head){for(let t of Array.from(document.head.querySelectorAll(`${S}:not([data-barocss-adopted])`))){let n=t.sheet;if(!n)continue;t.setAttribute(`data-barocss-adopted`,``);let r=[];for(let e=n.cssRules.length-1;e>=0;e--){let t=n.cssRules[e],i=l([t]);i.size!==0&&(i.forEach(e=>this.ssrClasses.add(e)),r.unshift({css:t.cssText,cls:i.values().next().value}),n.deleteRule(e))}e.push(...r)}e.length!==0&&(this.ssrRules.push(...e),this.insertSsrRules(e))}}insertSsrRules(e){for(let{css:t,cls:n}of e){let e=this.getCategory(n);e?this.stylePartitionManager.addCategoryRule(t,e):this.stylePartitionManager.addRule(t)}}injectPreflightCSS(){let e=this.options.config.preflight??!0;if(e){let t=this.context.getPreflightCSS(e);this.stylePartitionManager.updateRuleContent(`preflight`,`${C}\n@layer base {\n${t}\n}`,!0)}}ensureCssVars(){if(this.isDestroyed)return;let e=this.context.themeToCssVars?this.context.themeToCssVars():`:root { /* CSS Variables will be generated here */ }`;this.stylePartitionManager.updateRuleContent(`css-vars`,e)}getInsertionPoint(){if(typeof this.options.insertionPoint!=`string`)return this.options.insertionPoint;switch(this.options.insertionPoint){case`body`:return document.body||document.head;default:return document.head}}addClass(e){if(this.isDestroyed)return;let t=this.normalizeClasses(e).filter(Boolean);t.forEach(e=>this.pinned.add(e)),this.processClasses(t)}processClasses(e){this.processClassesIncremental(e)}processClassesIncremental(e){let t=typeof window<`u`,n=this.incrementalParser.processClasses(e);this.debugLog(`debug`,`results`,{results:n,classList:e}),this.applyParseResults(n,{isBrowser:t})}applyParseResults(e,t){if(this.isDestroyed)return;if(!this.shadowRoot&&this.getInsertionPoint().isConnected&&this.stylePartitionManager.hasDetachedPartitions()){let t=Array.from(this.cache.values());this.reset(),e=[...t,...e],e.forEach(e=>this.incrementalParser.markProcessed(e.cls))}if(this.ssrClasses.size>0&&(e=e.filter(e=>!this.ssrClasses.has(e.cls))),this.options.skipExisting&&e.length>0&&typeof document<`u`){let t=this.getExistingClasses();e=e.filter(e=>!t.has(e.cls))}if(e.length===0)return;let n=[],r=[],i=this.options.skipExisting&&typeof document<`u`?(this.getExistingClasses(),this.existingKeyframes):null;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){if(i?.size){let t=/^\s*@keyframes\s+([^\s{]+)/.exec(e)?.[1];if(t&&i.has(t))continue}this.rootCache.has(e)||(this.rootCache.add(e),r.push(e))}r.length>0&&this.stylePartitionManager.addRootRules(r.filter(Boolean)),n.length>0&&this.stylePartitionManager.addRules(n),this.debugLog(`info`,`Applied ${e.length} parser results`,{cssRuleCount:n.length,rootCssCount:r.length})}isPermanent(e){return this.pinned.has(e)||this.ssrClasses.has(e)?!0:this.shadowRoot?!1:typeof document>`u`||this.getExistingClasses().has(e)}reclaim(e){if(this.isDestroyed)return;let t=e.filter(e=>this.cache.has(e));if(t.length===0)return;let n=t.map(e=>this.cache.get(e));t.forEach(e=>{this.cache.delete(e),this.incrementalParser.unmarkProcessed(e)});let r=new Set;for(let e of this.cache.values())e.cssList.forEach(e=>r.add(e));for(let e of n){let t=this.getCategory(e.cls);for(let n of e.cssList)r.has(n)||this.stylePartitionManager.removeRule(n,t)}this.reclaimedCount+=t.length}getExistingClasses(){let e=new Set(Array.from(document.querySelectorAll(`style[data-barocss]`),e=>e.sheet)),t=Array.from(document.styleSheets).filter(t=>{if(e.has(t))return!1;let n=t.ownerNode;return!(n&&typeof n.hasAttribute==`function`&&(n.hasAttribute(`data-barocss`)||(n.id||``).startsWith(this.options.styleId)))});if(this.existing&&t.length===this.existingSheetCount)return this.existing;let n=new Set,r=new Set;for(let e of t){let t;try{t=e.cssRules}catch{continue}l(t,n),c(t,r)}return this.existingKeyframes=r,this.existing=n,this.existingSheetCount=t.length,n}observe(e=this.shadowRoot??document.body,t){return this.observedOnce||(this.observedOnce=!0,this.adoptSsrSheets()),this.changeDetector.observe(e,t)}normalizeClasses(e){return Array.isArray(e)?e.flatMap(e=>e.split(/\s+/)):e.split(/\s+/)}has(e){return this.cache.has(e)}getCss(e){return this.cache.get(e)?.cssList.join(`
|
|
14
|
+
`)}getAllCss(){return[...this.rootCache,...Array.from(this.cache.values()).flatMap(e=>e.cssList)].join(`
|
|
15
|
+
`)}getClasses(){return Array.from(this.cache.keys())}getCacheStats(){let e=this.incrementalParser.getStats();return{runtime:{cachedClasses:this.cache.size,rootCacheSize:this.rootCache.size,ruleCount:this.stylePartitionManager.ruleCount,reclaimedClasses:this.reclaimedCount,gc:this.gc?.stats()??null},ast:e.cacheStats.ast,incremental:e}}clearCaches(){this.isDestroyed||(this.cache.clear(),this.rootCache.clear(),(0,e.clearAstCache)(this.context),this.incrementalParser.clearProcessed(),this.stylePartitionManager.cleanup(),this.stylePartitionManager=this.createStyles(),this.injectPreflightCSS(),this.ensureCssVars(),this.insertSsrRules(this.ssrRules))}reset(){this.isDestroyed||(this.cache.clear(),this.rootCache.clear(),this.incrementalParser.clearProcessed(),this.stylePartitionManager.cleanup(),this.stylePartitionManager=this.createStyles(),this.injectPreflightCSS(),this.ensureCssVars(),this.insertSsrRules(this.ssrRules))}updateConfig(t){if(this.isDestroyed)return;let n=Array.from(this.cache.keys());if(this.options.config=t,this.shadowRoot){this.stylePartitionManager.cleanup();let e=v(t);this.context=e.context,this.incrementalParser=new b(e)}else this.context=(0,e.createContext)(t),this.incrementalParser=new e.IncrementalParser(this.context);this.changeDetector.setParser(this.incrementalParser),this.reset(),n.length>0&&this.addClass(n)}removeClass(e){if(this.isDestroyed)return;let t=new Set(this.normalizeClasses(e)),n=Array.from(this.cache.values()).filter(e=>!t.has(e.cls));n.length!==this.cache.size&&(this.reset(),n.forEach(e=>this.incrementalParser.markProcessed(e.cls)),this.applyParseResults(n))}destroy(){this.isDestroyed||=(this.changeDetector.disconnect(),this.gc?.cancel(),this.stylePartitionManager.cleanup(),this.cache.clear(),this.rootCache.clear(),!0)}getStats(){return{cachedClasses:this.cache.size,styleElementId:this.options.styleId,isDestroyed:this.isDestroyed,config:this.options.config,cacheStats:this.getCacheStats(),sharedSheet:this.shadowRoot&&this.stylePartitionManager instanceof x?{roots:this.stylePartitionManager.shared.rootCount,rules:this.stylePartitionManager.shared.ruleCount,generations:this.stylePartitionManager.shared.generations,constructable:this.stylePartitionManager.shared.constructable}:null}}},T=null,E;function D(e={}){return!T||T.getStats().isDestroyed?(T=new w(e),E=e.config):e.config&&e.config!==E&&(T.updateConfig(e.config),E=e.config),T}function O({loadingClassName:e=`baro-boot`,...t}={}){if(t.root&&t.root.nodeType===11)return new w(t);if(!document.body){document.addEventListener(`DOMContentLoaded`,()=>O({loadingClassName:e,...t}),{once:!0});return}let n=`${e}-doing`,r=`${e}-done`;try{document.body.classList.add(n),D(t).observe(document.body,{scan:!0,onReady:()=>{document.body.classList.remove(n),document.body.classList.add(r)}})}catch(e){document.body?.classList.remove(n),console.error(`BaroCSS boot failed:`,e)}}var k=O;function A(e){if(!e||typeof e!=`object`||Array.isArray(e))return[];let t=e.elements;if(!t||typeof t!=`object`||Array.isArray(t))return[];let n=new Set;for(let e of Object.keys(t)){let r=t[e];if(!r||typeof r!=`object`||Array.isArray(r))continue;let i=r.props;if(!i||typeof i!=`object`||Array.isArray(i))continue;let a=i.className;if(typeof a==`string`)for(let e of a.split(/\s+/))e&&n.add(e)}return Array.from(n)}function j(e,t){let n=A(e);n.length>0&&t.addClass(n)}var M={colors:Object.fromEntries(`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})`])),borderRadius:{sm:`calc(var(--radius) - 4px)`,md:`calc(var(--radius) - 2px)`,lg:`var(--radius)`,xl:`calc(var(--radius) + 4px)`}};exports.BrowserRuntime=w,exports.ChangeDetector=i,exports.LAYER_ORDER=C,exports.SSR_STYLE_SELECTOR=S,exports.StylePartitionManager=t,exports.baroBoot=O,exports.baroStart=k,exports.collectJsonRenderClassNames=A,exports.getRuntime=D,exports.normalizeClassName=n,exports.normalizeClassNameList=r,exports.preloadJsonRenderClasses=j,exports.shadcnTheme=M;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import { Config } from '@barocss/kit';
|
|
2
|
+
import { GenerateCssRulesResult } from '@barocss/kit';
|
|
3
|
+
import { IncrementalParser } from '@barocss/kit';
|
|
4
|
+
import { RuleKey } from '@barocss/kit';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Starts BaroCSS on the document (the shared runtime). #327: with `root: shadowRoot` it instead returns a new
|
|
8
|
+
* runtime that observes and styles only that shadow root (runtimes with the same config share one sheet).
|
|
9
|
+
*/
|
|
10
|
+
export declare function baroBoot(options: BaroBootOptions & {
|
|
11
|
+
root: ShadowRoot;
|
|
12
|
+
}): BrowserRuntime;
|
|
13
|
+
|
|
14
|
+
export declare function baroBoot(options?: BaroBootOptions): void;
|
|
15
|
+
|
|
16
|
+
declare type BaroBootOptions = BrowserRuntimeOptions & {
|
|
17
|
+
loadingClassName?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export declare const baroStart: typeof baroBoot;
|
|
21
|
+
|
|
22
|
+
export declare class BrowserRuntime {
|
|
23
|
+
private cache;
|
|
24
|
+
private rootCache;
|
|
25
|
+
private context;
|
|
26
|
+
private options;
|
|
27
|
+
/** #327: the shadow root this runtime styles, or null in document mode. */
|
|
28
|
+
private shadowRoot;
|
|
29
|
+
private isDestroyed;
|
|
30
|
+
private existing;
|
|
31
|
+
/** #274: @keyframes names the page's own sheets define (filled with `existing`). */
|
|
32
|
+
private existingKeyframes;
|
|
33
|
+
private existingSheetCount;
|
|
34
|
+
/** #269: classes requested explicitly through addClass(); never reclaimed. */
|
|
35
|
+
private pinned;
|
|
36
|
+
private gc;
|
|
37
|
+
private reclaimedCount;
|
|
38
|
+
/** #268: class rules adopted from `<style data-barocss-ssr>`, in sheet order, and the classes they lead. */
|
|
39
|
+
private ssrRules;
|
|
40
|
+
private ssrClasses;
|
|
41
|
+
private observedOnce;
|
|
42
|
+
private incrementalParser;
|
|
43
|
+
private changeDetector;
|
|
44
|
+
private stylePartitionManager;
|
|
45
|
+
private getCategory;
|
|
46
|
+
constructor(options?: BrowserRuntimeOptions);
|
|
47
|
+
/** Document partitions, or (#327) this root's view of the shared shadow-root sheet. */
|
|
48
|
+
private createStyles;
|
|
49
|
+
/**
|
|
50
|
+
* Add debug logs (by level)
|
|
51
|
+
*/
|
|
52
|
+
private debugLog;
|
|
53
|
+
private init;
|
|
54
|
+
/**
|
|
55
|
+
* #268: adopt the class rules of server-rendered `<style data-barocss-ssr>` sheets in <head>, at startup
|
|
56
|
+
* (constructor and the first observe()). Each rule moves
|
|
57
|
+
* (same task, so no paint in between) into the partition its class would get if generated here, at
|
|
58
|
+
* its #254 sorted position, so a later client `sm:` rule lands before a server `lg:` rule. Its classes
|
|
59
|
+
* are never regenerated and never reclaimed. `:root`, `@property` and `@keyframes` stay in the sheet.
|
|
60
|
+
*/
|
|
61
|
+
private adoptSsrSheets;
|
|
62
|
+
private insertSsrRules;
|
|
63
|
+
private injectPreflightCSS;
|
|
64
|
+
private ensureCssVars;
|
|
65
|
+
private getInsertionPoint;
|
|
66
|
+
/**
|
|
67
|
+
* Dynamically add one or more class names and generate/insert CSS
|
|
68
|
+
*/
|
|
69
|
+
addClass(classes: string | string[]): void;
|
|
70
|
+
/**
|
|
71
|
+
* Process classes
|
|
72
|
+
*/
|
|
73
|
+
private processClasses;
|
|
74
|
+
/**
|
|
75
|
+
* Process classes using incremental parsing
|
|
76
|
+
*/
|
|
77
|
+
private processClassesIncremental;
|
|
78
|
+
/**
|
|
79
|
+
* Public method to apply parser results, update internal caches, and inject CSS
|
|
80
|
+
*/
|
|
81
|
+
applyParseResults(results: Array<GenerateCssRulesResult>, _opts?: {
|
|
82
|
+
isBrowser?: boolean;
|
|
83
|
+
}): void;
|
|
84
|
+
/** #269: a class that must never be reclaimed. */
|
|
85
|
+
private isPermanent;
|
|
86
|
+
/**
|
|
87
|
+
* #269: delete the generated rules of classes no live element uses. Root/@property/@keyframes rules stay
|
|
88
|
+
* (they are shared and harmless); a rule text another cached class still emits is kept.
|
|
89
|
+
*/
|
|
90
|
+
private reclaim;
|
|
91
|
+
/** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
|
|
92
|
+
getExistingClasses(): Set<string>;
|
|
93
|
+
/**
|
|
94
|
+
* MutationObserver instance method to automatically call addClass when class attributes change in DOM
|
|
95
|
+
*/
|
|
96
|
+
observe(root?: HTMLElement | ShadowRoot, options?: {
|
|
97
|
+
scan?: boolean;
|
|
98
|
+
onReady?: () => void;
|
|
99
|
+
}): MutationObserver;
|
|
100
|
+
private normalizeClasses;
|
|
101
|
+
has(cls: string): boolean;
|
|
102
|
+
getCss(cls: string): string | undefined;
|
|
103
|
+
getAllCss(): string;
|
|
104
|
+
getClasses(): string[];
|
|
105
|
+
/**
|
|
106
|
+
* Get comprehensive cache statistics
|
|
107
|
+
*/
|
|
108
|
+
getCacheStats(): {
|
|
109
|
+
runtime: {
|
|
110
|
+
cachedClasses: number;
|
|
111
|
+
rootCacheSize: number;
|
|
112
|
+
ruleCount: number;
|
|
113
|
+
reclaimedClasses: number;
|
|
114
|
+
gc: {
|
|
115
|
+
trackedClasses: number;
|
|
116
|
+
candidates: number;
|
|
117
|
+
} | null;
|
|
118
|
+
};
|
|
119
|
+
ast: {
|
|
120
|
+
size: number;
|
|
121
|
+
maxSize: number;
|
|
122
|
+
hitRate: number;
|
|
123
|
+
};
|
|
124
|
+
incremental: {
|
|
125
|
+
processedClasses: number;
|
|
126
|
+
pendingClasses: number;
|
|
127
|
+
cacheStats: {
|
|
128
|
+
ast: {
|
|
129
|
+
size: number;
|
|
130
|
+
maxSize: number;
|
|
131
|
+
hitRate: number;
|
|
132
|
+
};
|
|
133
|
+
css: {};
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Clear all caches (useful for debugging or memory management)
|
|
139
|
+
*/
|
|
140
|
+
clearCaches(): void;
|
|
141
|
+
reset(): void;
|
|
142
|
+
updateConfig(newConfig: Config): void;
|
|
143
|
+
removeClass(classes: string | string[]): void;
|
|
144
|
+
destroy(): void;
|
|
145
|
+
getStats(): {
|
|
146
|
+
cachedClasses: number;
|
|
147
|
+
styleElementId: string;
|
|
148
|
+
isDestroyed: boolean;
|
|
149
|
+
config: Config;
|
|
150
|
+
cacheStats: {
|
|
151
|
+
runtime: {
|
|
152
|
+
cachedClasses: number;
|
|
153
|
+
rootCacheSize: number;
|
|
154
|
+
ruleCount: number;
|
|
155
|
+
reclaimedClasses: number;
|
|
156
|
+
gc: {
|
|
157
|
+
trackedClasses: number;
|
|
158
|
+
candidates: number;
|
|
159
|
+
} | null;
|
|
160
|
+
};
|
|
161
|
+
ast: {
|
|
162
|
+
size: number;
|
|
163
|
+
maxSize: number;
|
|
164
|
+
hitRate: number;
|
|
165
|
+
};
|
|
166
|
+
incremental: {
|
|
167
|
+
processedClasses: number;
|
|
168
|
+
pendingClasses: number;
|
|
169
|
+
cacheStats: {
|
|
170
|
+
ast: {
|
|
171
|
+
size: number;
|
|
172
|
+
maxSize: number;
|
|
173
|
+
hitRate: number;
|
|
174
|
+
};
|
|
175
|
+
css: {};
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
/** #327: the shared shadow-root sheet this runtime uses (null in document mode). */
|
|
180
|
+
sharedSheet: {
|
|
181
|
+
roots: number;
|
|
182
|
+
rules: number;
|
|
183
|
+
generations: number;
|
|
184
|
+
constructable: boolean;
|
|
185
|
+
} | null;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export declare interface BrowserRuntimeOptions {
|
|
190
|
+
config?: Config;
|
|
191
|
+
styleId?: string;
|
|
192
|
+
insertionPoint?: 'head' | 'body' | HTMLElement;
|
|
193
|
+
maxRulesPerPartition?: number;
|
|
194
|
+
/**
|
|
195
|
+
* #210: skip classes the page's existing (non-BaroCSS, same-origin) stylesheets already define,
|
|
196
|
+
* so a built app plus the runtime injects only what the build is missing. Opt-in. A class counts
|
|
197
|
+
* as covered only when a rule's selector starts with it (e.g. `.p-4`, `.md\:p-4` inside @media,
|
|
198
|
+
* `.hover\:x:hover`), so a class seen only as a descendant (`.group:hover .x`) is not skipped.
|
|
199
|
+
* The index is rebuilt when `document.styleSheets.length` changes. A page class that leads a selector
|
|
200
|
+
* with the same name is treated as covered, and rules added later to an already-indexed sheet aren't seen.
|
|
201
|
+
*/
|
|
202
|
+
skipExisting?: boolean;
|
|
203
|
+
/**
|
|
204
|
+
* #269: reclaim the rules of classes that no element inside the observed root carries any more.
|
|
205
|
+
* On by default; it only acts on classes seen through `observe()`. A class is deleted only after
|
|
206
|
+
* its refcount has stayed 0 for `gcGraceMs` and a live-DOM re-check finds no element with it.
|
|
207
|
+
* Never reclaimed: classes passed to `addClass()`, classes any pre-existing (non-BaroCSS) sheet
|
|
208
|
+
* defines (build output, server sheet), root/@property/preflight rules. `false` disables it.
|
|
209
|
+
*/
|
|
210
|
+
gc?: boolean;
|
|
211
|
+
/** #269: how long a class must stay unused before its rules are deleted (default 3000 ms). */
|
|
212
|
+
gcGraceMs?: number;
|
|
213
|
+
/**
|
|
214
|
+
* #269: soft cap on cached classes. When exceeded, unused (refcount 0) classes are evicted
|
|
215
|
+
* oldest-first without waiting for the grace period; classes in use are never evicted. Default: no cap.
|
|
216
|
+
*/
|
|
217
|
+
maxRules?: number;
|
|
218
|
+
/**
|
|
219
|
+
* #327: a ShadowRoot to style instead of the document. The runtime observes that root (with an initial scan)
|
|
220
|
+
* and places all of its CSS in it: utilities, theme variables, @property, @keyframes and a preflight rewritten
|
|
221
|
+
* for the root (`html`/`:root` -> `:host`, `body` declarations re-emitted on `:host`). Nothing goes to
|
|
222
|
+
* `document.head`. Runtimes with the same config share one constructable sheet adopted by every root
|
|
223
|
+
* (`adoptedStyleSheets`); without constructable sheets each root gets `<style>` elements instead.
|
|
224
|
+
* `insertionPoint`, `styleId` and `maxRulesPerPartition` are ignored in this mode, and server sheets (#268)
|
|
225
|
+
* are not adopted. `document` (or omitting it) keeps the document mode.
|
|
226
|
+
*/
|
|
227
|
+
root?: ShadowRoot | Document;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Change detection system for DOM mutations
|
|
232
|
+
*
|
|
233
|
+
* ⚠️ BROWSER-ONLY: This class is designed for browser environments only.
|
|
234
|
+
* It uses MutationObserver and DOM APIs that are not available in Node.js.
|
|
235
|
+
*
|
|
236
|
+
* This class monitors DOM changes and automatically processes new CSS classes
|
|
237
|
+
* that are added to elements. It uses MutationObserver to detect:
|
|
238
|
+
* - Class attribute changes on existing elements
|
|
239
|
+
* - New elements being added to the DOM
|
|
240
|
+
* - Changes in child elements
|
|
241
|
+
*
|
|
242
|
+
* For server-side usage, use IncrementalParser directly with processClassesSync()
|
|
243
|
+
* or processClasses() methods.
|
|
244
|
+
*/
|
|
245
|
+
export declare class ChangeDetector {
|
|
246
|
+
/** MutationObserver instance for DOM change detection */
|
|
247
|
+
private observer;
|
|
248
|
+
/** Reference to IncrementalParser for class processing */
|
|
249
|
+
private incrementalParser;
|
|
250
|
+
/** Reference to BrowserRuntime for CSS injection (optional) */
|
|
251
|
+
private BrowserRuntime?;
|
|
252
|
+
private getCategory;
|
|
253
|
+
/**
|
|
254
|
+
* Create a new ChangeDetector instance
|
|
255
|
+
*
|
|
256
|
+
* @param incrementalParser - IncrementalParser instance for class processing
|
|
257
|
+
* @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
|
|
258
|
+
*/
|
|
259
|
+
constructor(incrementalParser: IncrementalParser, BrowserRuntime?: BrowserRuntime, getCategory?: (cls: string) => string | undefined);
|
|
260
|
+
/** #269: refcount/GC tracker, when the runtime has GC enabled. */
|
|
261
|
+
private gc;
|
|
262
|
+
setGc(gc: ClassGc | null): void;
|
|
263
|
+
setParser(parser: IncrementalParser): void;
|
|
264
|
+
/**
|
|
265
|
+
* Starts observing DOM changes for new CSS classes
|
|
266
|
+
*
|
|
267
|
+
* This method sets up a MutationObserver that monitors:
|
|
268
|
+
* - Attribute changes (specifically class attribute modifications)
|
|
269
|
+
* - Child list changes (new elements being added)
|
|
270
|
+
* - Subtree changes (changes in descendant elements)
|
|
271
|
+
*
|
|
272
|
+
* The observer automatically processes any new classes it discovers
|
|
273
|
+
* by adding them to the IncrementalParser's pending queue.
|
|
274
|
+
*
|
|
275
|
+
* @param root - The root element to observe (defaults to document.body)
|
|
276
|
+
* @param options - Configuration options including initial scan and onReady callback
|
|
277
|
+
* @returns The MutationObserver instance for external control
|
|
278
|
+
*/
|
|
279
|
+
observe(root?: HTMLElement | ShadowRoot, options?: {
|
|
280
|
+
scan?: boolean;
|
|
281
|
+
onReady?: () => void;
|
|
282
|
+
}): MutationObserver;
|
|
283
|
+
/**
|
|
284
|
+
* Scan existing classes in the DOM and process them
|
|
285
|
+
*/
|
|
286
|
+
private scanExistingClasses;
|
|
287
|
+
/**
|
|
288
|
+
* Processes an individual element and extracts new classes
|
|
289
|
+
*
|
|
290
|
+
* This method is called for each element discovered during DOM mutations.
|
|
291
|
+
* It:
|
|
292
|
+
* - Extracts all class names from the element's className
|
|
293
|
+
* - Filters out already processed classes
|
|
294
|
+
* - Adds new classes to the collection for batch processing
|
|
295
|
+
*
|
|
296
|
+
* @param element - The HTML element to process
|
|
297
|
+
* @param newClasses - Set to collect newly discovered class names
|
|
298
|
+
*/
|
|
299
|
+
private processElement;
|
|
300
|
+
/**
|
|
301
|
+
* Stops observing DOM changes and cleans up resources
|
|
302
|
+
*
|
|
303
|
+
* This method disconnects the MutationObserver and clears the
|
|
304
|
+
* observer reference to prevent memory leaks and allow the
|
|
305
|
+
* ChangeDetector to be properly garbage collected.
|
|
306
|
+
*/
|
|
307
|
+
disconnect(): void;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
declare class ClassGc {
|
|
311
|
+
private host;
|
|
312
|
+
private graceMs;
|
|
313
|
+
private maxRules;
|
|
314
|
+
private now;
|
|
315
|
+
private counts;
|
|
316
|
+
private counted;
|
|
317
|
+
/** class -> time its count reached 0 (insertion order = oldest first). */
|
|
318
|
+
private candidates;
|
|
319
|
+
private timer;
|
|
320
|
+
private root;
|
|
321
|
+
constructor(host: ClassGcHost, graceMs: number, maxRules: number, now?: () => number);
|
|
322
|
+
/** Start counting for a new root: count every element currently inside it. */
|
|
323
|
+
setRoot(root: Element | ShadowRoot): void;
|
|
324
|
+
count(cls: string): number;
|
|
325
|
+
/** Re-count `el` and (optionally) all its descendants from their current state. */
|
|
326
|
+
reconcileTree(node: Node): void;
|
|
327
|
+
reconcile(el: Element): void;
|
|
328
|
+
/** Call after a mutation batch has been counted and its classes inserted. */
|
|
329
|
+
afterBatch(): void;
|
|
330
|
+
private schedule;
|
|
331
|
+
/** Reclaim candidates whose grace period elapsed (plus LRU overflow). Public for tests. */
|
|
332
|
+
sweep(): void;
|
|
333
|
+
private inDom;
|
|
334
|
+
cancel(): void;
|
|
335
|
+
stats(): {
|
|
336
|
+
trackedClasses: number;
|
|
337
|
+
candidates: number;
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* #269: per-class refcount over the observed root, plus a delayed sweep that
|
|
343
|
+
* reclaims classes no live element carries any more.
|
|
344
|
+
*
|
|
345
|
+
* Counting is reconciliation, not delta arithmetic: for every element a
|
|
346
|
+
* mutation batch touches (attribute target, added subtree, removed subtree) we
|
|
347
|
+
* compare the classes we last counted for it with what it carries *now*
|
|
348
|
+
* (nothing if it is no longer inside the root). That makes the count
|
|
349
|
+
* independent of record order, so remove-then-re-add in one batch, moves
|
|
350
|
+
* between parents and edits made while detached all settle to the true state.
|
|
351
|
+
* An element we miss can only leak a count (rule kept), never drop one.
|
|
352
|
+
*
|
|
353
|
+
* Before a class is reclaimed the sweep re-checks the live DOM
|
|
354
|
+
* (`getElementsByClassName`), so even a miscount cannot unstyle a live element.
|
|
355
|
+
*/
|
|
356
|
+
declare interface ClassGcHost {
|
|
357
|
+
/** Delete the rules of these classes. */
|
|
358
|
+
reclaim(classes: string[]): void;
|
|
359
|
+
/** Whether a class must never be reclaimed (pinned, found in a pre-existing sheet, ...). */
|
|
360
|
+
isPermanent(cls: string): boolean;
|
|
361
|
+
/** Number of generated rules/classes currently cached (for the LRU cap). */
|
|
362
|
+
cachedCount(): number;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** Collect literal className tokens from a json-render Spec's flat elements map. */
|
|
366
|
+
export declare function collectJsonRenderClassNames(spec: unknown): string[];
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Returns the shared runtime, creating it on first use. If a live runtime
|
|
370
|
+
* already exists and `options.config` is a different config object, it is
|
|
371
|
+
* applied via `updateConfig` (which replaces the whole config), so an early
|
|
372
|
+
* `getRuntime()` never makes a later `baroStart({ config })` lose its config.
|
|
373
|
+
*/
|
|
374
|
+
export declare function getRuntime(options?: BrowserRuntimeOptions): BrowserRuntime;
|
|
375
|
+
|
|
376
|
+
/** Tailwind 4 layer order, declared by BaroCSS's first <style> in <head>. */
|
|
377
|
+
export declare const LAYER_ORDER = "@layer theme, base, components, utilities;";
|
|
378
|
+
|
|
379
|
+
export declare function normalizeClassName(className: any): string;
|
|
380
|
+
|
|
381
|
+
export declare function normalizeClassNameList(className: any): string[];
|
|
382
|
+
|
|
383
|
+
/** Submit literal classes synchronously before UI mount; the caller validates class support. */
|
|
384
|
+
export declare function preloadJsonRenderClasses(spec: unknown, runtime: Pick<BrowserRuntime, 'addClass'>): void;
|
|
385
|
+
|
|
386
|
+
export declare const shadcnTheme: {
|
|
387
|
+
colors: Record<string, string>;
|
|
388
|
+
borderRadius: Record<string, string>;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/** #268: marks a server-rendered sheet (`@barocss/server` `ssrStyleTag()`); the runtime adopts its class rules. */
|
|
392
|
+
export declare const SSR_STYLE_SELECTOR = "style[data-barocss-ssr]";
|
|
393
|
+
|
|
394
|
+
export declare interface StylePartition {
|
|
395
|
+
id: string;
|
|
396
|
+
styles: string[];
|
|
397
|
+
styleElement: HTMLStyleElement;
|
|
398
|
+
/** Sort keys parallel to `styles` / the sheet's cssRules (#254). */
|
|
399
|
+
keys?: RuleKey[];
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export declare class StylePartitionManager {
|
|
403
|
+
/**
|
|
404
|
+
* Insert `rule` at its Tailwind variant position within `partition` (#254):
|
|
405
|
+
* one insertRule at a binary-searched index, no sheet rewrite.
|
|
406
|
+
*/
|
|
407
|
+
private insertSorted;
|
|
408
|
+
private partitions;
|
|
409
|
+
private categoryPartitions;
|
|
410
|
+
private partitionCounter;
|
|
411
|
+
private maxRulesPerPartition;
|
|
412
|
+
private insertionPoint;
|
|
413
|
+
private classToPartitionMap;
|
|
414
|
+
private classToCategoryPartitionMap;
|
|
415
|
+
private styleIdPrefix;
|
|
416
|
+
private getCategory;
|
|
417
|
+
constructor(insertionPoint: HTMLElement, maxRulesPerPartition?: number, styleIdPrefix?: string, getCategory?: (cls: string) => string | undefined);
|
|
418
|
+
private initializeDefaultPartition;
|
|
419
|
+
private createNewCategoryPartition;
|
|
420
|
+
private createNewPartition;
|
|
421
|
+
hasRule(rule: string): boolean;
|
|
422
|
+
hasCategoryRule(rule: string, category: string): boolean;
|
|
423
|
+
setRuleCache(rule: string, partitionIndex: number): void;
|
|
424
|
+
setCategoryRuleCache(rule: string, category: string): void;
|
|
425
|
+
get currentPartition(): StylePartition;
|
|
426
|
+
getCategoryPartition(category: string): StylePartition | undefined;
|
|
427
|
+
hasDetachedPartitions(): boolean;
|
|
428
|
+
/**
|
|
429
|
+
* Escape CSS rule text
|
|
430
|
+
* - Properly escape special characters
|
|
431
|
+
* - Prevent CSS syntax errors
|
|
432
|
+
*/
|
|
433
|
+
private escapeCssRule;
|
|
434
|
+
addRule(rule: string): boolean;
|
|
435
|
+
addCategoryRule(rule: string, category: string): boolean;
|
|
436
|
+
addRootRules(rules: string[]): {
|
|
437
|
+
success: number;
|
|
438
|
+
failed: number;
|
|
439
|
+
};
|
|
440
|
+
addRules(rules: GenerateCssRulesResult[]): {
|
|
441
|
+
success: number;
|
|
442
|
+
failed: number;
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Remove one generated rule (#269 GC). Keeps `styles`, the #254 `keys` and the
|
|
446
|
+
* sheet's cssRules parallel: one deleteRule at the rule's index, or a text
|
|
447
|
+
* rebuild when the sheet isn't solely ours / has no CSSOM. Returns whether
|
|
448
|
+
* the rule was found.
|
|
449
|
+
*/
|
|
450
|
+
removeRule(rule: string, category?: string): boolean;
|
|
451
|
+
/** Number of generated (non-root, non-preflight) rules currently held. */
|
|
452
|
+
get ruleCount(): number;
|
|
453
|
+
/**
|
|
454
|
+
* 특정 규칙이 어느 파티션에 있는지 찾기
|
|
455
|
+
*/
|
|
456
|
+
findRulePartition(rule: string): StylePartition | null;
|
|
457
|
+
updateRuleContent(category: string, ruleContent: string, atDocumentStart?: boolean): void;
|
|
458
|
+
/**
|
|
459
|
+
* 모든 파티션 정리
|
|
460
|
+
*/
|
|
461
|
+
cleanup(): void;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export { }
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,15 @@ import { GenerateCssRulesResult } from '@barocss/kit';
|
|
|
3
3
|
import { IncrementalParser } from '@barocss/kit';
|
|
4
4
|
import { RuleKey } from '@barocss/kit';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Starts BaroCSS on the document (the shared runtime). #327: with `root: shadowRoot` it instead returns a new
|
|
8
|
+
* runtime that observes and styles only that shadow root (runtimes with the same config share one sheet).
|
|
9
|
+
*/
|
|
10
|
+
export declare function baroBoot(options: BaroBootOptions & {
|
|
11
|
+
root: ShadowRoot;
|
|
12
|
+
}): BrowserRuntime;
|
|
13
|
+
|
|
14
|
+
export declare function baroBoot(options?: BaroBootOptions): void;
|
|
7
15
|
|
|
8
16
|
declare type BaroBootOptions = BrowserRuntimeOptions & {
|
|
9
17
|
loadingClassName?: string;
|
|
@@ -16,6 +24,8 @@ export declare class BrowserRuntime {
|
|
|
16
24
|
private rootCache;
|
|
17
25
|
private context;
|
|
18
26
|
private options;
|
|
27
|
+
/** #327: the shadow root this runtime styles, or null in document mode. */
|
|
28
|
+
private shadowRoot;
|
|
19
29
|
private isDestroyed;
|
|
20
30
|
private existing;
|
|
21
31
|
/** #274: @keyframes names the page's own sheets define (filled with `existing`). */
|
|
@@ -34,6 +44,8 @@ export declare class BrowserRuntime {
|
|
|
34
44
|
private stylePartitionManager;
|
|
35
45
|
private getCategory;
|
|
36
46
|
constructor(options?: BrowserRuntimeOptions);
|
|
47
|
+
/** Document partitions, or (#327) this root's view of the shared shadow-root sheet. */
|
|
48
|
+
private createStyles;
|
|
37
49
|
/**
|
|
38
50
|
* Add debug logs (by level)
|
|
39
51
|
*/
|
|
@@ -81,7 +93,7 @@ export declare class BrowserRuntime {
|
|
|
81
93
|
/**
|
|
82
94
|
* MutationObserver instance method to automatically call addClass when class attributes change in DOM
|
|
83
95
|
*/
|
|
84
|
-
observe(root?: HTMLElement, options?: {
|
|
96
|
+
observe(root?: HTMLElement | ShadowRoot, options?: {
|
|
85
97
|
scan?: boolean;
|
|
86
98
|
onReady?: () => void;
|
|
87
99
|
}): MutationObserver;
|
|
@@ -164,6 +176,13 @@ export declare class BrowserRuntime {
|
|
|
164
176
|
};
|
|
165
177
|
};
|
|
166
178
|
};
|
|
179
|
+
/** #327: the shared shadow-root sheet this runtime uses (null in document mode). */
|
|
180
|
+
sharedSheet: {
|
|
181
|
+
roots: number;
|
|
182
|
+
rules: number;
|
|
183
|
+
generations: number;
|
|
184
|
+
constructable: boolean;
|
|
185
|
+
} | null;
|
|
167
186
|
};
|
|
168
187
|
}
|
|
169
188
|
|
|
@@ -196,6 +215,16 @@ export declare interface BrowserRuntimeOptions {
|
|
|
196
215
|
* oldest-first without waiting for the grace period; classes in use are never evicted. Default: no cap.
|
|
197
216
|
*/
|
|
198
217
|
maxRules?: number;
|
|
218
|
+
/**
|
|
219
|
+
* #327: a ShadowRoot to style instead of the document. The runtime observes that root (with an initial scan)
|
|
220
|
+
* and places all of its CSS in it: utilities, theme variables, @property, @keyframes and a preflight rewritten
|
|
221
|
+
* for the root (`html`/`:root` -> `:host`, `body` declarations re-emitted on `:host`). Nothing goes to
|
|
222
|
+
* `document.head`. Runtimes with the same config share one constructable sheet adopted by every root
|
|
223
|
+
* (`adoptedStyleSheets`); without constructable sheets each root gets `<style>` elements instead.
|
|
224
|
+
* `insertionPoint`, `styleId` and `maxRulesPerPartition` are ignored in this mode, and server sheets (#268)
|
|
225
|
+
* are not adopted. `document` (or omitting it) keeps the document mode.
|
|
226
|
+
*/
|
|
227
|
+
root?: ShadowRoot | Document;
|
|
199
228
|
}
|
|
200
229
|
|
|
201
230
|
/**
|
|
@@ -247,7 +276,7 @@ export declare class ChangeDetector {
|
|
|
247
276
|
* @param options - Configuration options including initial scan and onReady callback
|
|
248
277
|
* @returns The MutationObserver instance for external control
|
|
249
278
|
*/
|
|
250
|
-
observe(root?: HTMLElement, options?: {
|
|
279
|
+
observe(root?: HTMLElement | ShadowRoot, options?: {
|
|
251
280
|
scan?: boolean;
|
|
252
281
|
onReady?: () => void;
|
|
253
282
|
}): MutationObserver;
|
|
@@ -291,7 +320,7 @@ declare class ClassGc {
|
|
|
291
320
|
private root;
|
|
292
321
|
constructor(host: ClassGcHost, graceMs: number, maxRules: number, now?: () => number);
|
|
293
322
|
/** Start counting for a new root: count every element currently inside it. */
|
|
294
|
-
setRoot(root: Element): void;
|
|
323
|
+
setRoot(root: Element | ShadowRoot): void;
|
|
295
324
|
count(cls: string): number;
|
|
296
325
|
/** Re-count `el` and (optionally) all its descendants from their current state. */
|
|
297
326
|
reconcileTree(node: Node): void;
|