lume-js 2.0.1 → 2.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.mjs","sources":["../src/handlers/index.js"],"sourcesContent":["/**\n * Lume-JS DOM Binding Handlers\n *\n * Extend bindDom() with additional reactive data-* attribute capabilities.\n * Each handler is a plain object — no framework API, no registration.\n *\n * Usage:\n * import { state, bindDom } from 'lume-js';\n * import { show, classToggle } from 'lume-js/handlers';\n *\n * const store = state({ isVisible: true, isActive: false });\n * bindDom(document.body, store, { handlers: [show, classToggle('active')] });\n *\n * Custom handlers:\n * const tooltip = { attr: 'data-tooltip', apply(el, val) { el.title = val ?? ''; } };\n * bindDom(root, store, { handlers: [tooltip] });\n *\n * Handler contract:\n * { attr: string, apply(el: HTMLElement, val: any): void }\n */\n\n// --- Ready-to-use Handlers ---\n\n/**\n * data-show=\"key\" → el.hidden = !Boolean(val)\n * Shows element when state value is truthy (inverse of built-in data-hidden).\n */\nexport const show = {\n attr: 'data-show',\n apply(el, val) { el.hidden = !Boolean(val); }\n};\n\n// --- Factory Functions ---\n\n/**\n * Create a handler for any HTML boolean attribute.\n * Uses toggleAttribute() — works correctly with any attribute name\n * (readonly, contenteditable, etc.) without worrying about camelCase property names.\n *\n * Note: built-in boolean handlers (hidden, disabled, checked, required) use\n * property assignment directly. This factory uses toggleAttribute for broader\n * attribute name compatibility.\n *\n * @param {string} name - Attribute name (e.g., 'readonly', 'open', 'contenteditable')\n * @returns {{ attr: string, apply: function }}\n *\n * @example\n * bindDom(root, store, { handlers: [boolAttr('readonly')] });\n * // <input data-readonly=\"isReadonly\" />\n */\nexport function boolAttr(name) {\n return {\n attr: `data-${name}`,\n apply(el, val) { el.toggleAttribute(name, Boolean(val)); }\n };\n}\n\n/**\n * Create a handler for an ARIA attribute.\n * Use for ARIA attrs beyond the built-in aria-expanded/aria-hidden.\n *\n * @param {string} name - ARIA name, with or without \"aria-\" prefix\n * @returns {{ attr: string, apply: function }}\n *\n * @example\n * bindDom(root, store, { handlers: [ariaAttr('pressed'), ariaAttr('selected')] });\n * // <button data-aria-pressed=\"isPressed\">Toggle</button>\n */\nexport function ariaAttr(name) {\n const fullName = name.startsWith('aria-') ? name : `aria-${name}`;\n return {\n attr: `data-${fullName}`,\n apply(el, val) { el.setAttribute(fullName, val ? 'true' : 'false'); }\n };\n}\n\n/**\n * Create handlers for CSS class toggling.\n * Each name creates a handler: data-class-{name}=\"key\" → el.classList.toggle(name, Boolean(val))\n *\n * Returns an array — pass directly to handlers (auto-flattened by bindDom).\n *\n * @param {...string} names - CSS class names to create handlers for\n * @returns {Array<{ attr: string, apply: function }>}\n *\n * @example\n * bindDom(root, store, { handlers: [classToggle('active', 'loading', 'error')] });\n * // <div data-class-active=\"isActive\" data-class-loading=\"isLoading\">\n */\nexport function classToggle(...names) {\n return names.map(name => ({\n attr: `data-class-${name}`,\n apply(el, val) { el.classList.toggle(name, Boolean(val)); }\n }));\n}\n\n/**\n * Create a handler for any string attribute (href, src, title, alt, action, etc.)\n * Sets the attribute value as a string. Removes attribute when value is null/undefined.\n *\n * @param {string} name - HTML attribute name (e.g., 'href', 'src', 'title')\n * @returns {{ attr: string, apply: function }}\n *\n * @example\n * bindDom(root, store, { handlers: [stringAttr('href'), stringAttr('src')] });\n * // <a data-href=\"profileUrl\">Profile</a>\n * // <img data-src=\"imageUrl\" />\n */\nexport function stringAttr(name) {\n return {\n attr: `data-${name}`,\n apply(el, val) {\n if (val == null) el.removeAttribute(name);\n else el.setAttribute(name, String(val));\n }\n };\n}\n\n// --- Presets ---\n\n/** Form-related handlers (beyond built-in disabled/checked/required) */\nexport const formHandlers = [\n boolAttr('readonly'),\n];\n\n/** Additional ARIA handlers (beyond built-in aria-expanded/aria-hidden) */\nexport const a11yHandlers = [\n ariaAttr('pressed'),\n ariaAttr('selected'),\n ariaAttr('disabled'),\n];\n\n// --- htmlAttrs() — All Standard HTML Attributes ---\n\n/**\n * Standard HTML boolean attributes (beyond built-in hidden/disabled/checked/required).\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#boolean_attributes\n */\nconst BOOL_ATTRS = [\n 'readonly', 'open', 'novalidate', 'formnovalidate', 'multiple',\n 'autofocus', 'autoplay', 'controls', 'loop', 'muted', 'defer',\n 'async', 'reversed', 'selected', 'inert', 'allowfullscreen',\n];\n\n/**\n * Standard HTML string attributes.\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes\n */\nconst STRING_ATTRS = [\n 'href', 'src', 'alt', 'title', 'placeholder', 'action', 'method',\n 'target', 'rel', 'type', 'name', 'role', 'lang', 'tabindex',\n 'pattern', 'min', 'max', 'step', 'minlength', 'maxlength',\n 'width', 'height', 'for', 'form', 'accept', 'autocomplete',\n 'loading', 'decoding', 'inputmode', 'enterkeyhint', 'draggable',\n 'contenteditable', 'spellcheck', 'translate', 'dir', 'id',\n 'poster', 'preload', 'download', 'media', 'sizes', 'srcset',\n 'colspan', 'rowspan', 'scope', 'headers', 'wrap', 'sandbox',\n];\n\n/**\n * ARIA boolean state attributes — toggled between \"true\" and \"false\".\n * Use ariaAttr() for these (coerces to \"true\"/\"false\" string).\n * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes\n */\nconst ARIA_BOOL_ATTRS = [\n 'pressed', 'selected', 'disabled', 'checked', 'invalid', 'required',\n 'busy', 'modal', 'multiselectable', 'multiline', 'readonly', 'atomic',\n];\n\n/**\n * ARIA string/token/numeric attributes — value passed through as-is.\n * Use stringAttr() with \"aria-\" prefix for these.\n * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes\n */\nconst ARIA_STRING_ATTRS = [\n 'current', 'live', 'relevant', 'haspopup',\n 'sort', 'autocomplete', 'orientation',\n 'label', 'describedby', 'labelledby', 'controls', 'owns',\n 'activedescendant', 'errormessage', 'details', 'flowto',\n 'valuenow', 'valuemin', 'valuemax', 'valuetext',\n 'colcount', 'colindex', 'colspan', 'rowcount', 'rowindex', 'rowspan',\n 'level', 'setsize', 'posinset', 'placeholder', 'roledescription',\n 'keyshortcuts', 'braillelabel', 'brailleroledescription',\n];\n\n/**\n * One-import preset that enables all standard HTML attributes as reactive handlers.\n *\n * Includes:\n * - Boolean attributes: readonly, open, autofocus, controls, muted, inert, etc.\n * - String attributes: href, src, alt, title, placeholder, role, tabindex, etc.\n * - ARIA attributes: aria-pressed, aria-label, aria-describedby, aria-valuenow, etc.\n * - Show handler: data-show (inverse of data-hidden)\n *\n * Returns a flat array — pass directly to handlers option.\n *\n * @returns {Array<{ attr: string, apply: function }>}\n *\n * @example\n * import { htmlAttrs } from 'lume-js/handlers';\n *\n * bindDom(document.body, store, { handlers: [htmlAttrs()] });\n * // Now use any data-* attribute:\n * // <a data-href=\"url\">Link</a>\n * // <input data-readonly=\"isLocked\" />\n * // <div data-aria-label=\"labelText\">...</div>\n * // <div data-show=\"isVisible\">...</div>\n */\nexport function htmlAttrs() {\n return [\n show,\n ...BOOL_ATTRS.map(name => boolAttr(name)),\n ...STRING_ATTRS.map(name => stringAttr(name)),\n ...ARIA_BOOL_ATTRS.map(name => ariaAttr(name)),\n ...ARIA_STRING_ATTRS.map(name => stringAttr(`aria-${name}`)),\n ];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handlers.mjs","sources":["../src/handlers/show.js","../src/handlers/className.js","../src/handlers/boolAttr.js","../src/handlers/ariaAttr.js","../src/handlers/classToggle.js","../src/handlers/stringAttr.js","../src/handlers/htmlAttrs.js","../src/handlers/presets.js"],"sourcesContent":["/** data-show=\"key\" → el.hidden = !Boolean(val) */\nexport const show = {\n attr: 'data-show',\n apply(el, val) { el.hidden = !Boolean(val); }\n};\n","/** data-classname=\"key\" → el.className = val || '' */\nexport const className = {\n attr: 'data-classname',\n apply(el, val) { el.className = val || ''; }\n};\n","/**\n * Create a handler for any HTML boolean attribute.\n * Uses toggleAttribute() — works correctly with any attribute name\n * (readonly, contenteditable, etc.) without worrying about camelCase property names.\n *\n * @param {string} name - Attribute name (e.g., 'readonly', 'open', 'contenteditable')\n * @returns {{ attr: string, apply: function }}\n */\nexport function boolAttr(name) {\n return {\n attr: `data-${name}`,\n apply(el, val) { el.toggleAttribute(name, Boolean(val)); }\n };\n}\n","/**\n * Create a handler for an ARIA attribute.\n * Coerces value to \"true\"/\"false\" string — use stringAttr(\"aria-X\") for token/string ARIA attrs.\n *\n * @param {string} name - ARIA name, with or without \"aria-\" prefix\n * @returns {{ attr: string, apply: function }}\n */\nexport function ariaAttr(name) {\n const fullName = name.startsWith('aria-') ? name : `aria-${name}`;\n return {\n attr: `data-${fullName}`,\n apply(el, val) { el.setAttribute(fullName, val ? 'true' : 'false'); }\n };\n}\n","/**\n * Create handlers for CSS class toggling.\n * Each name creates a handler: data-class-{name}=\"key\" → el.classList.toggle(name, Boolean(val))\n * Returns an array — pass directly to handlers (auto-flattened by bindDom).\n *\n * @param {...string} names - CSS class names to create handlers for\n * @returns {Array<{ attr: string, apply: function }>}\n */\nexport function classToggle(...names) {\n return names.map(name => ({\n attr: `data-class-${name}`,\n apply(el, val) { el.classList.toggle(name, Boolean(val)); }\n }));\n}\n","/**\n * Create a handler for any string attribute (href, src, title, alt, action, etc.)\n * Sets the attribute value as a string. Removes the attribute when value is null/undefined.\n *\n * @param {string} name - HTML attribute name (e.g., 'href', 'src', 'title')\n * @returns {{ attr: string, apply: function }}\n */\nexport function stringAttr(name) {\n return {\n attr: `data-${name}`,\n apply(el, val) {\n if (val == null) el.removeAttribute(name);\n else el.setAttribute(name, String(val));\n }\n };\n}\n","import { show } from './show.js';\nimport { boolAttr } from './boolAttr.js';\nimport { ariaAttr } from './ariaAttr.js';\nimport { stringAttr } from './stringAttr.js';\n\n/** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#boolean_attributes */\nconst BOOL_ATTRS = [\n 'readonly', 'open', 'novalidate', 'formnovalidate', 'multiple',\n 'autofocus', 'autoplay', 'controls', 'loop', 'muted', 'defer',\n 'async', 'reversed', 'selected', 'inert', 'allowfullscreen',\n];\n\n/** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes */\nconst STRING_ATTRS = [\n 'href', 'src', 'alt', 'title', 'placeholder', 'action', 'method',\n 'target', 'rel', 'type', 'name', 'role', 'lang', 'tabindex',\n 'pattern', 'min', 'max', 'step', 'minlength', 'maxlength',\n 'width', 'height', 'for', 'form', 'accept', 'autocomplete',\n 'loading', 'decoding', 'inputmode', 'enterkeyhint', 'draggable',\n 'contenteditable', 'spellcheck', 'translate', 'dir', 'id',\n 'poster', 'preload', 'download', 'media', 'sizes', 'srcset',\n 'colspan', 'rowspan', 'scope', 'headers', 'wrap', 'sandbox',\n];\n\n/** ARIA boolean state attributes — coerced to \"true\"/\"false\" string. */\nconst ARIA_BOOL_ATTRS = [\n 'pressed', 'selected', 'disabled', 'checked', 'invalid', 'required',\n 'busy', 'modal', 'multiselectable', 'multiline', 'readonly', 'atomic',\n];\n\n/** ARIA string/token/numeric attributes — value passed through as-is. */\nconst ARIA_STRING_ATTRS = [\n 'current', 'live', 'relevant', 'haspopup',\n 'sort', 'autocomplete', 'orientation',\n 'label', 'describedby', 'labelledby', 'controls', 'owns',\n 'activedescendant', 'errormessage', 'details', 'flowto',\n 'valuenow', 'valuemin', 'valuemax', 'valuetext',\n 'colcount', 'colindex', 'colspan', 'rowcount', 'rowindex', 'rowspan',\n 'level', 'setsize', 'posinset', 'placeholder', 'roledescription',\n 'keyshortcuts', 'braillelabel', 'brailleroledescription',\n];\n\n/**\n * One-import preset that enables all standard HTML attributes as reactive handlers.\n * Returns a flat array — pass directly to handlers option.\n *\n * @returns {Array<{ attr: string, apply: function }>}\n */\nexport function htmlAttrs() {\n return [\n show,\n ...BOOL_ATTRS.map(name => boolAttr(name)),\n ...STRING_ATTRS.map(name => stringAttr(name)),\n ...ARIA_BOOL_ATTRS.map(name => ariaAttr(name)),\n ...ARIA_STRING_ATTRS.map(name => stringAttr(`aria-${name}`)),\n ];\n}\n","import { boolAttr } from './boolAttr.js';\nimport { ariaAttr } from './ariaAttr.js';\n\n/** Form-related handlers (beyond built-in disabled/checked/required) */\nexport const formHandlers = [\n boolAttr('readonly'),\n];\n\n/** Additional ARIA handlers (beyond built-in aria-expanded/aria-hidden) */\nexport const a11yHandlers = [\n ariaAttr('pressed'),\n ariaAttr('selected'),\n ariaAttr('disabled'),\n];\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var Lume=function(e){"use strict";function t(e,...t){void 0!==console&&"function"==typeof console.warn&&console.warn(e,...t)}function o(e,...t){void 0!==console&&"function"==typeof console.error&&console.error(e,...t)}const n=new Set;function r(e,t){n.add(e);try{return t()}finally{n.delete(e)}}const c=e=>({attr:"data-"+e,apply(t,o){t[e]=!!o}}),s=e=>({attr:"data-"+e,apply(t,o){t.setAttribute(e,o?"true":"false")}}),i=[c("hidden"),c("disabled"),c("checked"),c("required"),s("aria-expanded"),s("aria-hidden")];function l(e,t,o,n){const r=u(t,o);if(!r)return null;const{target:c,key:s}=r;return c.$subscribe(s,t=>n.apply(e,t))}function a(e,t,o,n){const r=u(t,o);if(!r)return null;const{target:c,key:s}=r,i=c.$subscribe(s,t=>function(e,t){"INPUT"===e.tagName?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t+"":e.value=t??"":"TEXTAREA"===e.tagName||"SELECT"===e.tagName?e.value=t??"":e.textContent=t??""}(e,t));return function(e){return"INPUT"===e.tagName||"TEXTAREA"===e.tagName||"SELECT"===e.tagName}(e)&&n.set(e,{target:c,key:s}),i}function u(e,o){if(!o)return null;const n=o.split("."),r=n.pop(),c=function(e,t){if(!t||0===t.length)return e;let o=e;for(let n=0;n<t.length;n++){const e=t[n];if(null==o)return null;if(!(e in o))return null;o=o[e]}return o}(e,n);return null==c?(t(`[Lume.js] Invalid path "${o}"`),null):c?.$subscribe?{target:c,key:r}:(t(`[Lume.js] Target for "${o}" is not reactive`),null)}let f=null;function d(e,t){if("function"!=typeof e)throw Error("effect() requires a function");const n=[];let c=!1;const s=()=>{if(!c){c=!0;try{e()}catch(t){throw o("[Lume.js effect] Error in effect:",t),t}finally{c=!1}}};if(Array.isArray(t)){for(const e of t)if(Array.isArray(e)&&e.length>=2){const[t,...o]=e;if(t&&"function"==typeof t.$subscribe)for(const e of o){let o=!0;const r=t.$subscribe(e,()=>{o?o=!1:s()});n.push(r)}}s()}else{const t=()=>{if(c)return;const s=n.splice(0),i={fn:e,cleanups:n,execute:t,tracking:{}},l=f;f=i,c=!0;try{r((e,t,o)=>{f===i&&(i.tracking[t]||(i.tracking[t]=!0,i.cleanups.push(o(t,i.execute))))},e)}catch(a){throw n.length=0,n.push(...s),o("[Lume.js effect] Error in effect:",a),a}finally{f=l,c=!1}if(n.length>0)for(const e of s)e();else n.push(...s)};t()}return()=>{for(;n.length;)n.pop()()}}function p(e){const t=document.activeElement;if(!e.contains(t))return null;let o=null,n=null;return"INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName||(o=t.selectionStart,n=t.selectionEnd),()=>{document.body.contains(t)&&(t.focus(),null!==o&&null!==n&&t.setSelectionRange(o,n))}}function b(e,t={}){const{isReorder:o=!1}=t,n=e.scrollTop;if(0===n)return()=>{e.scrollTop=0};let r=null,c=0;if(!o){const t=e.getBoundingClientRect();for(let o=e.firstElementChild;o;o=o.nextElementSibling){const e=o.getBoundingClientRect();if(e.bottom>t.top){r=o,c=e.top-t.top;break}}}return()=>{if(r&&document.body.contains(r)){const t=r.getBoundingClientRect(),o=e.getBoundingClientRect(),n=t.top-o.top-c;e.scrollTop=e.scrollTop+n}else e.scrollTop=n}}let g=!0,h=null;const y=new Map;function m(e){return null===h||("string"==typeof h?e.includes(h):!(h instanceof RegExp)||h.test(e))}function w(e,t,o){const n=function(e){return y.has(e)||y.set(e,{gets:new Map,sets:new Map,notifies:new Map}),y.get(e)}(e),r=n[t];r.set(o,(r.get(o)||0)+1)}function E(e){try{const t=JSON.stringify(e);return t.length>100?t.slice(0,97)+"...":t}catch{return e+""}}const v={enable(){g=!0,console.log("%c[lume-debug]%c Logging enabled","color: #888; font-weight: bold","color: #4CAF50")},disable(){g=!1,console.log("%c[lume-debug]%c Logging disabled","color: #888; font-weight: bold","color: #F44336")},isEnabled:()=>g,filter(e){h=e,console.log(null===e?"%c[lume-debug]%c Filter cleared":"%c[lume-debug]%c Filter set: "+e,"color: #888; font-weight: bold","color: inherit")},getFilter:()=>h,stats(){const e={};for(const[t,o]of y)e[t]={gets:Object.fromEntries(o.gets),sets:Object.fromEntries(o.sets),notifies:Object.fromEntries(o.notifies)};return e},logStats(){const e=this.stats();if(0===Object.keys(e).length)return console.log("%c[lume-debug]%c No stats collected yet","color: #888; font-weight: bold","color: inherit"),e;console.group("%c[lume-debug] Statistics","color: #888; font-weight: bold");for(const[t,o]of Object.entries(e)){console.group("%c"+t,"color: #2196F3; font-weight: bold");const e=[],n=new Set([...Object.keys(o.gets),...Object.keys(o.sets),...Object.keys(o.notifies)]);for(const t of n)e.push({key:t,gets:o.gets[t]||0,sets:o.sets[t]||0,notifies:o.notifies[t]||0});e.length>0&&console.table(e),console.groupEnd()}return console.groupEnd(),e},resetStats(){y.clear(),console.log("%c[lume-debug]%c Stats reset","color: #888; font-weight: bold","color: inherit")}},$={attr:"data-show",apply(e,t){e.hidden=!t}};function j(e){return{attr:"data-"+e,apply(t,o){t.toggleAttribute(e,!!o)}}}function S(e){const t=e.startsWith("aria-")?e:"aria-"+e;return{attr:"data-"+t,apply(e,o){e.setAttribute(t,o?"true":"false")}}}function k(e){return{attr:"data-"+e,apply(t,o){null==o?t.removeAttribute(e):t.setAttribute(e,o+"")}}}const L=[j("readonly")],A=[S("pressed"),S("selected"),S("disabled")],x=["readonly","open","novalidate","formnovalidate","multiple","autofocus","autoplay","controls","loop","muted","defer","async","reversed","selected","inert","allowfullscreen"],O=["href","src","alt","title","placeholder","action","method","target","rel","type","name","role","lang","tabindex","pattern","min","max","step","minlength","maxlength","width","height","for","form","accept","autocomplete","loading","decoding","inputmode","enterkeyhint","draggable","contenteditable","spellcheck","translate","dir","id","poster","preload","download","media","sizes","srcset","colspan","rowspan","scope","headers","wrap","sandbox"],T=["pressed","selected","disabled","checked","invalid","required","busy","modal","multiselectable","multiline","readonly","atomic"],F=["current","live","relevant","haspopup","sort","autocomplete","orientation","label","describedby","labelledby","controls","owns","activedescendant","errormessage","details","flowto","valuenow","valuemin","valuemax","valuetext","colcount","colindex","colspan","rowcount","rowindex","rowspan","level","setsize","posinset","placeholder","roledescription","keyshortcuts","braillelabel","brailleroledescription"];return e.a11yHandlers=A,e.ariaAttr=S,e.bindDom=function(e,t,o={}){if(!(e instanceof HTMLElement))throw Error("bindDom() requires a valid HTMLElement as root");if(!t||"object"!=typeof t)throw Error("bindDom() requires a reactive state object");const{immediate:n=!1,handlers:r=[]}=o,c=function(e,t){if(!t.length)return e;const o=new Map;for(const n of e)o.set(n.attr,n);for(const n of t.flat())o.set(n.attr,n);return[...o.values()]}(i,r),s=()=>{const o=[],n=new WeakMap,r=["[data-bind]",...c.map(e=>`[${e.attr}]`)].join(","),s=e.querySelectorAll(r);for(const e of s){if(e.hasAttribute("data-bind")){const r=a(e,t,e.getAttribute("data-bind"),n);r&&o.push(r)}for(const n of c)if(e.hasAttribute(n.attr)){const r=l(e,t,e.getAttribute(n.attr),n);r&&o.push(r)}}const i=e=>{const t=n.get(e.target);var o;t&&(t.target[t.key]="checkbox"===(o=e.target).type?o.checked:"number"===o.type||"range"===o.type?o.valueAsNumber:o.value)};return e.addEventListener("input",i),o.push(()=>e.removeEventListener("input",i)),()=>o.forEach(e=>e())};if(!n&&"loading"===document.readyState){let e=null;const t=()=>{e=s()};return document.addEventListener("DOMContentLoaded",t,{once:!0}),()=>e?e():document.removeEventListener("DOMContentLoaded",t)}return s()},e.boolAttr=j,e.classToggle=function(...e){return e.map(e=>({attr:"data-class-"+e,apply(t,o){t.classList.toggle(e,!!o)}}))},e.computed=function(e){if("function"!=typeof e)throw Error("computed() requires a function");let t,n=!1,r=!1,c=!1;const s=[],i=d(()=>{if(!r&&!c){r=!0;try{const o=e();n&&Object.is(o,t)||(t=o,n=!0,s.forEach(e=>e(t)))}catch(i){o("[Lume.js computed] Error in computation:",i),n&&void 0===t||(t=void 0,n=!0,s.forEach(e=>e(t)))}finally{queueMicrotask(()=>{c||(r=!1)})}}});return{get value(){if(!n)throw Error("Computed value accessed before initialization");return t},subscribe(e){if("function"!=typeof e)throw Error("subscribe() requires a function");return s.push(e),n&&e(t),()=>{const t=s.indexOf(e);t>-1&&s.splice(t,1)}},dispose(){c=!0,i(),s.length=0,n=!1,r=!1}}},e.createCleanupGroup=function(){const e=[];return{add(t){"function"==typeof t&&e.push(t)},dispose(){for(;e.length;){const o=e.pop();try{o()}catch(t){}}}}},e.createDebugPlugin=function(e={}){const t=e.label??"store",o=(t,o)=>{const n=e[t];return void 0!==n?n:o};return{name:"debug:"+t,onInit:()=>{g&&console.log(`%c[${t}]%c initialized`,"color: #888; font-weight: bold","color: inherit")},onGet:(e,n)=>("string"==typeof e&&e.startsWith("$")||(w(t,"gets",e),g&&o("logGet",!1)&&m(e)&&console.log(`%c[${t}]%c GET %c${e}%c = ${E(n)}`,"color: #888; font-weight: bold","color: #4CAF50","color: #2196F3; font-weight: bold","color: inherit")),n),onSet:(e,n,r)=>("string"==typeof e&&e.startsWith("$")||(w(t,"sets",e),g&&o("logSet",!0)&&m(e)&&(console.log(`%c[${t}]%c SET %c${e}%c: ${E(r)} → ${E(n)}`,"color: #888; font-weight: bold","color: #FF9800","color: #2196F3; font-weight: bold","color: inherit"),o("trace",!1)&&console.trace(`%c[${t}] Stack trace for ${e}`,"color: #888"))),n),onSubscribe:e=>{g&&m(e)&&console.log(`%c[${t}]%c SUBSCRIBE %c${e}`,"color: #888; font-weight: bold","color: #9C27B0","color: #2196F3; font-weight: bold")},onNotify:(e,n)=>{"string"==typeof e&&e.startsWith("$")||(w(t,"notifies",e),g&&o("logNotify",!0)&&m(e)&&console.log(`%c[${t}]%c NOTIFY %c${e}%c = ${E(n)}`,"color: #888; font-weight: bold","color: #E91E63","color: #2196F3; font-weight: bold","color: inherit"))}}},e.debug=v,e.defaultFocusPreservation=p,e.defaultScrollPreservation=b,e.effect=d,e.formHandlers=L,e.htmlAttrs=function(){return[$,...x.map(e=>j(e)),...O.map(e=>k(e)),...T.map(e=>S(e)),...F.map(e=>k("aria-"+e))]},e.hydrateState=function(e="#__LUME_DATA__"){const t="undefined"!=typeof document?document.querySelector(e):null;if(!t)return{};try{return JSON.parse(t.textContent)}catch{return{}}},e.isReactive=function(e){return!(!e||"object"!=typeof e||"function"!=typeof e.$subscribe)},e.repeat=function(e,n,r,c){const{key:s,render:i,create:l,update:a,element:u="div",preserveFocus:f=p,preserveScroll:d=b}=c,g="string"==typeof e?document.querySelector(e):e;if(!g)return t(`[Lume.js] repeat(): container "${e}" not found`),()=>{};if("function"!=typeof s)throw Error("[Lume.js] repeat(): options.key must be a function");if("function"!=typeof i&&"function"!=typeof l)throw Error("[Lume.js] repeat(): options.render or options.create must be a function");const h=new Map,y=new Map,m=new Map,w=new Set;function E(){return"function"==typeof u?u():document.createElement(u)}function v(){const e=n[r];if(!Array.isArray(e))return void t(`[Lume.js] repeat(): store.${r} is not an array`);let c=!1;if(d&&h.size===e.length){c=!0;for(let t=0;t<e.length;t++)if(!h.has(s(e[t]))){c=!1;break}}w.clear();const u=[];for(let n=0;n<e.length;n++){const r=e[n],c=s(r);if(w.has(c)){t(`[Lume.js] repeat(): duplicate key "${c}"`);continue}w.add(c);let f=h.get(c);const d=!f;d&&(f=E(),h.set(c,f));try{d&&l&&l(r,f,n);const e=y.get(c),t=m.get(c);a?e===r&&t===n||a(r,f,n,{isFirstRender:d}):i&&i(r,f,n),y.set(c,r),m.set(c,n)}catch(p){o(`[Lume.js] repeat(): error rendering key "${c}":`,p)}u.push(f)}!function(e,t,o){const n=document.body.contains(e),r=n&&f?f(e):null,c=n&&d?d(e,{isReorder:o}):null;(()=>{if(function(e,t){let o=e.firstChild;for(let n=0;n<t.length;n++){const r=t[n];o!==r?e.insertBefore(r,o):o=o.nextSibling}for(;o;){const t=o.nextSibling;e.removeChild(o),o=t}}(g,u),h.size!==w.size)for(const e of h.keys())w.has(e)||(h.delete(e),y.delete(e),m.delete(e))})(),r&&r(),c&&c()}(g,0,c)}let $;if("function"==typeof n.$subscribe)$=n.$subscribe(r,v);else{if("function"!=typeof n.subscribe)return v(),t("[Lume.js] repeat(): store is not reactive (no $subscribe or subscribe method)"),()=>{g.replaceChildren(),h.clear(),y.clear(),m.clear(),w.clear()};{const e=n.subscribe(()=>v());v(),$="function"==typeof e?e:()=>{e?.unsubscribe?.()}}}return()=>{"function"==typeof $&&$(),g.replaceChildren(),h.clear(),y.clear(),m.clear(),w.clear()}},e.show=$,e.state=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw Error("state() requires a plain object");if(Object.isFrozen(e)||Object.isSealed(e))throw Error("state() requires a mutable plain object");const t=Object.create(null),r=new Map,c=new Set,s=[];let i=!1;e[Symbol("lume.reactive")]=!0;const l=(e,o)=>{t[e]||(t[e]=[]);const n=()=>{c.add(o)};return t[e].push(n),()=>{if(t[e]){const o=t[e].indexOf(n);-1!==o&&(t[e].splice(o,1),0===t[e].length&&delete t[e])}}},a=new Proxy(e,{get(e,t){if("string"==typeof t&&t.startsWith("$"))return e[t];const o=e[t];if(n.size>0)for(const r of n)r(a,t,l);return o},set(e,n,l){const a=e[n];return Object.is(a,l)||(e[n]=l,r.set(n,l),i||(i=!0,queueMicrotask(()=>{let e=0;try{for(;(r.size>0||c.size>0)&&100>e;){e++;for(let e=0;e<s.length;e++)try{s[e]()}catch(n){o("[Lume.js state] Error in beforeFlush hook:",n)}for(const[e,c]of r)if(t[e]){const r=t[e];let s=0;for(;s<r.length;){const t=r[s];try{t(c)}catch(n){o(`[Lume.js state] Error notifying subscriber for key "${e+""}":`,n)}r[s]===t&&s++}}r.clear();const i=Array(c.size);let l=0;for(const e of c)i[l++]=e;c.clear();for(let e=0;e<i.length;e++)try{i[e]()}catch(n){o("[Lume.js state] Error in effect:",n)}}}finally{i=!1}100>e||o("[Lume.js state] Maximum flush iterations reached (100). This usually indicates an infinite loop caused by an effect or computed mutating state it depends on.")}))),!0}});return e.$beforeFlush=e=>{if("function"!=typeof e)throw Error("$beforeFlush requires a function");return-1===s.indexOf(e)&&s.push(e),()=>{const t=s.indexOf(e);-1!==t&&s.splice(t,1)}},e.$subscribe=(e,o)=>{if("function"!=typeof o)throw Error("Subscriber must be a function");return t[e]||(t[e]=[]),t[e].push(o),o(a[e]),()=>{if(t[e]){const n=t[e].indexOf(o);-1!==n&&(t[e].splice(n,1),0===t[e].length&&delete t[e])}}},a},e.stringAttr=k,e.watch=function(e,t,o){if(!e.$subscribe)throw Error("store must be created with state()");return e.$subscribe(t,o)},e.withPlugins=function(e,t=[]){if(!t.length)return e;for(const s of t)try{s.onInit?.()}catch(c){o(`[Lume.js] Plugin "${s.name}" error in onInit:`,c)}const n=new Map;let r;return"function"==typeof e.$beforeFlush&&(r=e.$beforeFlush(function(){for(const[e,r]of n)for(const n of t)try{n.onNotify?.(e,r)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onNotify:`,c)}n.clear()})),new Proxy(e,{get(e,s){if("$dispose"===s)return()=>{r&&r(),n.clear()};if("string"==typeof s&&s.startsWith("$")){const n=e[s];return"$subscribe"===s&&"function"==typeof n?(e,r)=>{for(const n of t)try{n.onSubscribe?.(e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onSubscribe:`,c)}return n(e,r)}:n}let i=e[s];for(const n of t)try{const e=n.onGet?.(s,i);void 0!==e&&(i=e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onGet:`,c)}return i},set(e,r,s){const i=e[r];let l=s;for(const n of t)try{const e=n.onSet?.(r,l,i);void 0!==e&&(l=e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onSet:`,c)}return Object.is(l,i)||n.set(r,l),e[r]=l,!0}})},e.withReadObserver=r,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),e}({});
1
+ var Lume=function(e){"use strict";function t(e,...t){void 0!==console&&"function"==typeof console.warn&&console.warn(e,...t)}function o(e,...t){void 0!==console&&"function"==typeof console.error&&console.error(e,...t)}const n=new Set;function r(e,t){n.add(e);try{return t()}finally{n.delete(e)}}const c=e=>({attr:"data-"+e,apply(t,o){t[e]=!!o}}),s=e=>({attr:"data-"+e,apply(t,o){t.setAttribute(e,o?"true":"false")}}),i=[c("hidden"),c("disabled"),c("checked"),c("required"),s("aria-expanded"),s("aria-hidden")];function l(e,t,o,n){const r=u(t,o);if(!r)return null;const{target:c,key:s}=r;return c.$subscribe(s,t=>n.apply(e,t))}function a(e,t,o,n){const r=u(t,o);if(!r)return null;const{target:c,key:s}=r,i=c.$subscribe(s,t=>function(e,t){"INPUT"===e.tagName?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t+"":e.value=t??"":"TEXTAREA"===e.tagName||"SELECT"===e.tagName?e.value=t??"":e.textContent=t??""}(e,t));return function(e){return"INPUT"===e.tagName||"TEXTAREA"===e.tagName||"SELECT"===e.tagName}(e)&&n.set(e,{target:c,key:s}),i}function u(e,o){if(!o)return null;const n=o.split("."),r=n.pop(),c=function(e,t){if(!t||0===t.length)return e;let o=e;for(let n=0;n<t.length;n++){const e=t[n];if(null==o)return null;if(!(e in o))return null;o=o[e]}return o}(e,n);return null==c?(t(`[Lume.js] Invalid path "${o}"`),null):c?.$subscribe?{target:c,key:r}:(t(`[Lume.js] Target for "${o}" is not reactive`),null)}let f=null;function d(e,t){if("function"!=typeof e)throw Error("effect() requires a function");const n=[];let c=!1;const s=()=>{if(!c){c=!0;try{e()}catch(t){throw o("[Lume.js effect] Error in effect:",t),t}finally{c=!1}}};if(Array.isArray(t)){for(const e of t)if(Array.isArray(e)&&e.length>=2){const[t,...o]=e;if(t&&"function"==typeof t.$subscribe)for(const e of o){let o=!0;const r=t.$subscribe(e,()=>{o?o=!1:s()});n.push(r)}}s()}else{const t=()=>{if(c)return;const s=n.splice(0),i={fn:e,cleanups:n,execute:t,tracking:{}},l=f;f=i,c=!0;try{r((e,t,o)=>{f===i&&(i.tracking[t]||(i.tracking[t]=!0,i.cleanups.push(o(t,i.execute))))},e)}catch(a){throw n.length=0,n.push(...s),o("[Lume.js effect] Error in effect:",a),a}finally{f=l,c=!1}if(n.length>0)for(const e of s)e();else n.push(...s)};t()}return()=>{for(;n.length;)n.pop()()}}function p(e){const t=document.activeElement;if(!e.contains(t))return null;let o=null,n=null;return"INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName||(o=t.selectionStart,n=t.selectionEnd),()=>{document.body.contains(t)&&(t.focus(),null!==o&&null!==n&&t.setSelectionRange(o,n))}}function g(e,t={}){const{isReorder:o=!1}=t,n=e.scrollTop;if(0===n)return()=>{e.scrollTop=0};let r=null,c=0;if(!o){const t=e.getBoundingClientRect();for(let o=e.firstElementChild;o;o=o.nextElementSibling){const e=o.getBoundingClientRect();if(e.bottom>t.top){r=o,c=e.top-t.top;break}}}return()=>{if(r&&document.body.contains(r)){const t=r.getBoundingClientRect(),o=e.getBoundingClientRect(),n=t.top-o.top-c;e.scrollTop=e.scrollTop+n}else e.scrollTop=n}}let b=!0,h=null;const y=new Map;function m(e){return null===h||("string"==typeof h?e.includes(h):!(h instanceof RegExp)||h.test(e))}function w(e,t,o){const n=function(e){return y.has(e)||y.set(e,{gets:new Map,sets:new Map,notifies:new Map}),y.get(e)}(e),r=n[t];r.set(o,(r.get(o)||0)+1)}function E(e){try{const t=JSON.stringify(e);return t.length>100?t.slice(0,97)+"...":t}catch{return e+""}}const $={enable(){b=!0,console.log("%c[lume-debug]%c Logging enabled","color: #888; font-weight: bold","color: #4CAF50")},disable(){b=!1,console.log("%c[lume-debug]%c Logging disabled","color: #888; font-weight: bold","color: #F44336")},isEnabled:()=>b,filter(e){h=e,console.log(null===e?"%c[lume-debug]%c Filter cleared":"%c[lume-debug]%c Filter set: "+e,"color: #888; font-weight: bold","color: inherit")},getFilter:()=>h,stats(){const e={};for(const[t,o]of y)e[t]={gets:Object.fromEntries(o.gets),sets:Object.fromEntries(o.sets),notifies:Object.fromEntries(o.notifies)};return e},logStats(){const e=this.stats();if(0===Object.keys(e).length)return console.log("%c[lume-debug]%c No stats collected yet","color: #888; font-weight: bold","color: inherit"),e;console.group("%c[lume-debug] Statistics","color: #888; font-weight: bold");for(const[t,o]of Object.entries(e)){console.group("%c"+t,"color: #2196F3; font-weight: bold");const e=[],n=new Set([...Object.keys(o.gets),...Object.keys(o.sets),...Object.keys(o.notifies)]);for(const t of n)e.push({key:t,gets:o.gets[t]||0,sets:o.sets[t]||0,notifies:o.notifies[t]||0});e.length>0&&console.table(e),console.groupEnd()}return console.groupEnd(),e},resetStats(){y.clear(),console.log("%c[lume-debug]%c Stats reset","color: #888; font-weight: bold","color: inherit")}},v={attr:"data-show",apply(e,t){e.hidden=!t}},j={attr:"data-classname",apply(e,t){e.className=t||""}};function S(e){return{attr:"data-"+e,apply(t,o){t.toggleAttribute(e,!!o)}}}function k(e){const t=e.startsWith("aria-")?e:"aria-"+e;return{attr:"data-"+t,apply(e,o){e.setAttribute(t,o?"true":"false")}}}function L(e){return{attr:"data-"+e,apply(t,o){null==o?t.removeAttribute(e):t.setAttribute(e,o+"")}}}const A=["readonly","open","novalidate","formnovalidate","multiple","autofocus","autoplay","controls","loop","muted","defer","async","reversed","selected","inert","allowfullscreen"],x=["href","src","alt","title","placeholder","action","method","target","rel","type","name","role","lang","tabindex","pattern","min","max","step","minlength","maxlength","width","height","for","form","accept","autocomplete","loading","decoding","inputmode","enterkeyhint","draggable","contenteditable","spellcheck","translate","dir","id","poster","preload","download","media","sizes","srcset","colspan","rowspan","scope","headers","wrap","sandbox"],O=["pressed","selected","disabled","checked","invalid","required","busy","modal","multiselectable","multiline","readonly","atomic"],T=["current","live","relevant","haspopup","sort","autocomplete","orientation","label","describedby","labelledby","controls","owns","activedescendant","errormessage","details","flowto","valuenow","valuemin","valuemax","valuetext","colcount","colindex","colspan","rowcount","rowindex","rowspan","level","setsize","posinset","placeholder","roledescription","keyshortcuts","braillelabel","brailleroledescription"],F=[S("readonly")],N=[k("pressed"),k("selected"),k("disabled")];return e.a11yHandlers=N,e.ariaAttr=k,e.bindDom=function(e,t,o={}){if(!(e instanceof HTMLElement))throw Error("bindDom() requires a valid HTMLElement as root");if(!t||"object"!=typeof t)throw Error("bindDom() requires a reactive state object");const{immediate:n=!1,handlers:r=[]}=o,c=function(e,t){if(!t.length)return e;const o=new Map;for(const n of e)o.set(n.attr,n);for(const n of t.flat())o.set(n.attr,n);return[...o.values()]}(i,r),s=()=>{const o=[],n=new WeakMap,r=["[data-bind]",...c.map(e=>`[${e.attr}]`)].join(","),s=e.querySelectorAll(r);for(const e of s){if(e.hasAttribute("data-bind")){const r=a(e,t,e.getAttribute("data-bind"),n);r&&o.push(r)}for(const n of c)if(e.hasAttribute(n.attr)){const r=l(e,t,e.getAttribute(n.attr),n);r&&o.push(r)}}const i=e=>{const t=n.get(e.target);var o;t&&(t.target[t.key]="checkbox"===(o=e.target).type?o.checked:"number"===o.type||"range"===o.type?o.valueAsNumber:o.value)};return e.addEventListener("input",i),o.push(()=>e.removeEventListener("input",i)),()=>o.forEach(e=>e())};if(!n&&"loading"===document.readyState){let e=null;const t=()=>{e=s()};return document.addEventListener("DOMContentLoaded",t,{once:!0}),()=>e?e():document.removeEventListener("DOMContentLoaded",t)}return s()},e.boolAttr=S,e.className=j,e.classToggle=function(...e){return e.map(e=>({attr:"data-class-"+e,apply(t,o){t.classList.toggle(e,!!o)}}))},e.computed=function(e){if("function"!=typeof e)throw Error("computed() requires a function");let t,n=!1,r=!1,c=!1;const s=[],i=d(()=>{if(!r&&!c){r=!0;try{const o=e();n&&Object.is(o,t)||(t=o,n=!0,s.forEach(e=>e(t)))}catch(i){o("[Lume.js computed] Error in computation:",i),n&&void 0===t||(t=void 0,n=!0,s.forEach(e=>e(t)))}finally{queueMicrotask(()=>{c||(r=!1)})}}});return{get value(){if(!n)throw Error("Computed value accessed before initialization");return t},subscribe(e){if("function"!=typeof e)throw Error("subscribe() requires a function");return s.push(e),n&&e(t),()=>{const t=s.indexOf(e);t>-1&&s.splice(t,1)}},dispose(){c=!0,i(),s.length=0,n=!1,r=!1}}},e.createCleanupGroup=function(){const e=[];return{add(t){"function"==typeof t&&e.push(t)},dispose(){for(;e.length;){const o=e.pop();try{o()}catch(t){}}}}},e.createDebugPlugin=function(e={}){const t=e.label??"store",o=(t,o)=>{const n=e[t];return void 0!==n?n:o};return{name:"debug:"+t,onInit:()=>{b&&console.log(`%c[${t}]%c initialized`,"color: #888; font-weight: bold","color: inherit")},onGet:(e,n)=>("string"==typeof e&&e.startsWith("$")||(w(t,"gets",e),b&&o("logGet",!1)&&m(e)&&console.log(`%c[${t}]%c GET %c${e}%c = ${E(n)}`,"color: #888; font-weight: bold","color: #4CAF50","color: #2196F3; font-weight: bold","color: inherit")),n),onSet:(e,n,r)=>("string"==typeof e&&e.startsWith("$")||(w(t,"sets",e),b&&o("logSet",!0)&&m(e)&&(console.log(`%c[${t}]%c SET %c${e}%c: ${E(r)} → ${E(n)}`,"color: #888; font-weight: bold","color: #FF9800","color: #2196F3; font-weight: bold","color: inherit"),o("trace",!1)&&console.trace(`%c[${t}] Stack trace for ${e}`,"color: #888"))),n),onSubscribe:e=>{b&&m(e)&&console.log(`%c[${t}]%c SUBSCRIBE %c${e}`,"color: #888; font-weight: bold","color: #9C27B0","color: #2196F3; font-weight: bold")},onNotify:(e,n)=>{"string"==typeof e&&e.startsWith("$")||(w(t,"notifies",e),b&&o("logNotify",!0)&&m(e)&&console.log(`%c[${t}]%c NOTIFY %c${e}%c = ${E(n)}`,"color: #888; font-weight: bold","color: #E91E63","color: #2196F3; font-weight: bold","color: inherit"))}}},e.debug=$,e.defaultFocusPreservation=p,e.defaultScrollPreservation=g,e.effect=d,e.formHandlers=F,e.htmlAttrs=function(){return[v,...A.map(e=>S(e)),...x.map(e=>L(e)),...O.map(e=>k(e)),...T.map(e=>L("aria-"+e))]},e.hydrateState=function(e="#__LUME_DATA__"){const t="undefined"!=typeof document?document.querySelector(e):null;if(!t)return{};try{return JSON.parse(t.textContent)}catch{return{}}},e.isReactive=function(e){return!(!e||"object"!=typeof e||"function"!=typeof e.$subscribe)},e.repeat=function(e,n,r,c){const{key:s,render:i,create:l,update:a,remove:u,element:f="div",preserveFocus:d=p,preserveScroll:b=g}=c,h="string"==typeof e?document.querySelector(e):e;if(!h)return t(`[Lume.js] repeat(): container "${e}" not found`),()=>{};if("function"!=typeof s)throw Error("[Lume.js] repeat(): options.key must be a function");if("function"!=typeof i&&"function"!=typeof l)throw Error("[Lume.js] repeat(): options.render or options.create must be a function");const y=new Map,m=new Map,w=new Map,E=new Map,$=new Set;function v(){return"function"==typeof f?f():document.createElement(f)}function j(){const e=n[r];if(!Array.isArray(e))return void t(`[Lume.js] repeat(): store.${r} is not an array`);let c=!1;if(b&&y.size===e.length){c=!0;for(let t=0;t<e.length;t++)if(!y.has(s(e[t]))){c=!1;break}}$.clear();const f=[];for(let n=0;n<e.length;n++){const r=e[n],c=s(r);if($.has(c)){t(`[Lume.js] repeat(): duplicate key "${c}"`);continue}$.add(c);let u=y.get(c);const d=!u;d&&(u=v(),y.set(c,u));try{if(d&&l){const e=l(r,u,n);"function"==typeof e&&E.set(c,e)}const e=m.get(c),t=w.get(c);a?e===r&&t===n||a(r,u,n,{isFirstRender:d}):i&&i(r,u,n),m.set(c,r),w.set(c,n)}catch(p){o(`[Lume.js] repeat(): error rendering key "${c}":`,p)}f.push(u)}!function(e,t,n){const r=document.body.contains(e),c=r&&d?d(e):null,s=r&&b?b(e,{isReorder:n}):null;(()=>{if(function(e,t){let o=e.firstChild;for(let n=0;n<t.length;n++){const r=t[n];o!==r?e.insertBefore(r,o):o=o.nextSibling}for(;o;){const t=o.nextSibling;e.removeChild(o),o=t}}(h,f),y.size!==$.size)for(const e of y.keys())if(!$.has(e)){const t=y.get(e),n=m.get(e),r=E.get(e);if("function"==typeof r)try{r()}catch(p){o(`[Lume.js] repeat(): cleanup error for key "${e}":`,p)}"function"==typeof u&&t&&u(n,t),y.delete(e),m.delete(e),w.delete(e),E.delete(e)}})(),c&&c(),s&&s()}(h,0,c)}let S;if("function"==typeof n.$subscribe)S=n.$subscribe(r,j);else{if("function"!=typeof n.subscribe)return j(),t("[Lume.js] repeat(): store is not reactive (no $subscribe or subscribe method)"),()=>{for(const[t,n]of y){const r=m.get(t),c=E.get(t);if("function"==typeof c)try{c()}catch(e){o(`[Lume.js] repeat(): cleanup error for key "${t}":`,e)}"function"==typeof u&&u(r,n)}h.replaceChildren(),y.clear(),m.clear(),w.clear(),E.clear(),$.clear()};{const e=n.subscribe(()=>j());j(),S="function"==typeof e?e:()=>{e?.unsubscribe?.()}}}return()=>{"function"==typeof S&&S();for(const[t,n]of y){const r=m.get(t),c=E.get(t);if("function"==typeof c)try{c()}catch(e){o(`[Lume.js] repeat(): cleanup error for key "${t}":`,e)}"function"==typeof u&&u(r,n)}h.replaceChildren(),y.clear(),m.clear(),w.clear(),E.clear(),$.clear()}},e.show=v,e.state=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw Error("state() requires a plain object");if(Object.isFrozen(e)||Object.isSealed(e))throw Error("state() requires a mutable plain object");const t=Object.create(null),r=new Map,c=new Set,s=[];let i=!1;e[Symbol("lume.reactive")]=!0;const l=(e,o)=>{t[e]||(t[e]=[]);const n=()=>{c.add(o)};return t[e].push(n),()=>{if(t[e]){const o=t[e].indexOf(n);-1!==o&&(t[e].splice(o,1),0===t[e].length&&delete t[e])}}},a=new Proxy(e,{get(e,t){if("string"==typeof t&&t.startsWith("$"))return e[t];const o=e[t];if(n.size>0)for(const r of n)r(a,t,l);return o},set(e,n,l){const a=e[n];return Object.is(a,l)||(e[n]=l,r.set(n,l),i||(i=!0,queueMicrotask(()=>{let e=0;try{for(;(r.size>0||c.size>0)&&100>e;){e++;for(let e=0;e<s.length;e++)try{s[e]()}catch(n){o("[Lume.js state] Error in beforeFlush hook:",n)}for(const[e,c]of r)if(t[e]){const r=t[e];let s=0;for(;s<r.length;){const t=r[s];try{t(c)}catch(n){o(`[Lume.js state] Error notifying subscriber for key "${e+""}":`,n)}r[s]===t&&s++}}r.clear();const i=Array(c.size);let l=0;for(const e of c)i[l++]=e;c.clear();for(let e=0;e<i.length;e++)try{i[e]()}catch(n){o("[Lume.js state] Error in effect:",n)}}}finally{i=!1}100>e||o("[Lume.js state] Maximum flush iterations reached (100). This usually indicates an infinite loop caused by an effect or computed mutating state it depends on.")}))),!0}});return e.$beforeFlush=e=>{if("function"!=typeof e)throw Error("$beforeFlush requires a function");return-1===s.indexOf(e)&&s.push(e),()=>{const t=s.indexOf(e);-1!==t&&s.splice(t,1)}},e.$subscribe=(e,o)=>{if("function"!=typeof o)throw Error("Subscriber must be a function");return t[e]||(t[e]=[]),t[e].push(o),o(a[e]),()=>{if(t[e]){const n=t[e].indexOf(o);-1!==n&&(t[e].splice(n,1),0===t[e].length&&delete t[e])}}},a},e.stringAttr=L,e.watch=function(e,t,o,{immediate:n=!0}={}){if(!e.$subscribe)throw Error("store must be created with state()");if(!n){let n=!1;return e.$subscribe(t,e=>{n?o(e):n=!0})}return e.$subscribe(t,o)},e.withPlugins=function(e,t=[]){if(!t.length)return e;for(const s of t)try{s.onInit?.()}catch(c){o(`[Lume.js] Plugin "${s.name}" error in onInit:`,c)}const n=new Map;let r;return"function"==typeof e.$beforeFlush&&(r=e.$beforeFlush(function(){for(const[e,r]of n)for(const n of t)try{n.onNotify?.(e,r)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onNotify:`,c)}n.clear()})),new Proxy(e,{get(e,s){if("$dispose"===s)return()=>{r&&r(),n.clear()};if("string"==typeof s&&s.startsWith("$")){const n=e[s];return"$subscribe"===s&&"function"==typeof n?(e,r)=>{for(const n of t)try{n.onSubscribe?.(e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onSubscribe:`,c)}return n(e,r)}:n}let i=e[s];for(const n of t)try{const e=n.onGet?.(s,i);void 0!==e&&(i=e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onGet:`,c)}return i},set(e,r,s){const i=e[r];let l=s;for(const n of t)try{const e=n.onSet?.(r,l,i);void 0!==e&&(l=e)}catch(c){o(`[Lume.js] Plugin "${n.name}" error in onSet:`,c)}return Object.is(l,i)||n.set(r,l),e[r]=l,!0}})},e.withReadObserver=r,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),e}({});
2
2
  //# sourceMappingURL=lume.global.js.map