lego-dom 1.3.3 → 1.3.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.3.4] - 2026-01-16
6
+
7
+ ### Improvements
8
+
9
+ - **Minified Build:** Added a build script (`npm run build`) that uses `esbuild` to generate a `main.min.js` file, reducing file size by ~55% for optimal CDN performance.
10
+
5
11
  ## [1.3.3] - 2026-01-16
6
12
 
7
13
  ### Fixes
@@ -16,7 +16,7 @@ export default defineConfig({
16
16
  { text: 'Examples', link: '/examples/' },
17
17
  { text: 'Router', link: '/router/' },
18
18
  {
19
- text: 'v1.3.3',
19
+ text: 'v1.3.4',
20
20
  items: [
21
21
  { text: 'Changelog', link: 'https://github.com/rayattack/LegoDOM/releases' }
22
22
 
@@ -69,7 +69,6 @@ export default defineConfig({
69
69
  { text: 'What is LegoDOM?', link: '/guide/' },
70
70
  { text: 'Getting Started', link: '/guide/getting-started' },
71
71
  { text: 'Quick Start', link: '/guide/quick-start' },
72
- { text: 'Contributing', link: '/guide/contributing' }
73
72
  ]
74
73
  },
75
74
  {
@@ -39,7 +39,7 @@ That's it! Open this file in any browser and it works.
39
39
  <script src="https://unpkg.com/lego-dom/main.js"></script>
40
40
 
41
41
  <!-- Specific version -->
42
- <script src="https://unpkg.com/lego-dom@0.0.7/main.js"></script>
42
+ <script src="https://unpkg.com/lego-dom@1.3.4/main.js"></script>
43
43
  ```
44
44
 
45
45
  ### jsdelivr
@@ -49,14 +49,10 @@ That's it! Open this file in any browser and it works.
49
49
  <script src="https://cdn.jsdelivr.net/npm/lego-dom/main.js"></script>
50
50
 
51
51
  <!-- Specific version -->
52
- <script src="https://cdn.jsdelivr.net/npm/lego-dom@0.0.7/main.js"></script>
52
+ <script src="https://cdn.jsdelivr.net/npm/lego-dom@1.3.4/main.js"></script>
53
53
  ```
54
54
 
55
- ### cdnjs
56
55
 
57
- ```html
58
- <script src="https://cdnjs.cloudflare.com/ajax/libs/lego-dom/0.0.7/main.js"></script>
59
- ```
60
56
 
61
57
  ## Complete Example
62
58
 
@@ -246,7 +242,7 @@ Lego components work alongside other frameworks:
246
242
  Always pin to a specific version:
247
243
 
248
244
  ```html
249
- <script src="https://unpkg.com/lego-dom@0.0.7/main.js"></script>
245
+ <script src="https://unpkg.com/lego-dom@1.3.4/main.js"></script>
250
246
  ```
251
247
 
252
248
  ### For Development/Prototyping
@@ -271,7 +267,7 @@ For maximum security:
271
267
 
272
268
  ```html
273
269
  <script
274
- src="https://unpkg.com/lego-dom@0.0.7/main.js"
270
+ src="https://unpkg.com/lego-dom@1.3.4/main.js"
275
271
  integrity="sha384-..."
276
272
  crossorigin="anonymous">
277
273
  </script>
@@ -288,9 +284,42 @@ Lego works in all modern browsers:
288
284
 
289
285
  No polyfills needed for these browsers!
290
286
 
287
+ ## Using .lego Files without Build Tools
288
+
289
+ You can use full Single File Components (`.lego` files) directly in the browser without any build step!
290
+ Lego provides a `loader` configuration that lets you fetch component files on demand.
291
+
292
+ ### How it Works
293
+
294
+ 1. **Serve your files**: Make sure your `.lego` files are accessible via HTTP (e.g., in a `/components` folder).
295
+ 2. **Configure the loader**: Tell Lego how to fetch a component when it encounters an unknown tag.
296
+
297
+ ### Example
298
+
299
+ ```html
300
+ <script>
301
+ Lego.init(document.body, {
302
+ // The loader function receives the tag name (e.g., 'user-card')
303
+ // and must return a Promise that resolves to the component's source code.
304
+ loader: (tagName) => {
305
+ // Fetch the raw text content of the .lego file
306
+ return fetch(`/components/${tagName}.lego`).then(res => res.text());
307
+ }
308
+ });
309
+ </script>
310
+
311
+ <!-- Now just use the tag! Lego will fetch, compile, and render it automatically. -->
312
+ <user-card></user-card>
313
+ ```
314
+
315
+ This is perfect for:
316
+ - **Micro-frontends**: Load components from different services.
317
+ - **CMS Integration**: Store component code in a database.
318
+ - **Dynamic Apps**: Load features only when they are needed.
319
+
291
320
  ## Pros and Cons
292
321
 
293
- ### Advantages
322
+ ### Advantages
294
323
 
295
324
  - **No build step** - Instant development
296
325
  - **No npm** - No dependency management
@@ -298,11 +327,8 @@ No polyfills needed for these browsers!
298
327
  - **Progressive enhancement** - Add to existing sites easily
299
328
  - **Low barrier** - Great for beginners
300
329
 
301
- ### ⚠️ Limitations
330
+ ### Limitations
302
331
 
303
- - No tree-shaking (you get the whole library)
304
- - No TypeScript compilation
305
- - No `.lego` SFC support
306
332
  - No hot module replacement
307
333
  - Slower for large apps compared to bundled versions
308
334
 
@@ -6,6 +6,12 @@ Learn how to create and use components in Lego.
6
6
 
7
7
  A component is a reusable, self-contained piece of UI with its own template, styles, and logic.
8
8
 
9
+
10
+ ::: warning Note That
11
+ `style` tags inside NON SFC components are inside the `<template>` tag. And outside the tag in SFCs.
12
+ :::
13
+
14
+
9
15
  ```html
10
16
  <template b-id="user-badge">
11
17
  <style>
package/docs/guide/sfc.md CHANGED
@@ -310,6 +310,50 @@ Scoped styles using Shadow DOM. Use `self` to target the component root:
310
310
 
311
311
  Styles are automatically scoped to your component—they won't affect other components or global styles.
312
312
 
313
+ ## Dynamic Styles
314
+
315
+ A powerful feature of LegoDOM SFCs is that **interpolation works inside `<style>` tags too!**
316
+
317
+ You can use `[[ ]]` to bind CSS values directly to your component's state, props, or logic. Because styles are scoped (Shadow DOM), this is safe and won't leak.
318
+
319
+ ```html
320
+ <template>
321
+ <button @click="toggleTheme()">Toggle Theme</button>
322
+ </template>
323
+
324
+ <style>
325
+ /* Use state variables directly in CSS */
326
+ self {
327
+ background-color: [[ theme === 'dark' ? '#333' : '#fff' ]];
328
+ color: [[ theme === 'dark' ? '#fff' : '#000' ]];
329
+
330
+ /* You can also bind strict values for calculation */
331
+ --padding: [[ basePadding + 'px' ]];
332
+ padding: var(--padding);
333
+ }
334
+ </style>
335
+
336
+ <script>
337
+ export default {
338
+ theme: 'light',
339
+ basePadding: 20,
340
+
341
+ toggleTheme() {
342
+ this.theme = this.theme === 'light' ? 'dark' : 'light';
343
+ }
344
+ }
345
+ </script>
346
+ ```
347
+
348
+ ::: tip Why this rocks 🤘
349
+ This eliminates the need for CSS-in-JS libraries. You get full reactivity in your CSS with standard syntax.
350
+ :::
351
+
352
+ ::: warning Performance Note
353
+ Binding to CSS properties works great for themes, settings, and layout changes.
354
+ For high-frequency updates (like drag-and-drop coordinates or 60fps animations), prefer binding to **CSS Variables** on the host element (`style="--x: [[ x ]]"`) to avoid re-parsing the stylesheet on every frame.
355
+ :::
356
+
313
357
  ## Hot Module Replacement
314
358
 
315
359
  During development, changes to `.lego` files trigger a full page reload. Your changes appear instantly!
package/main.min.js ADDED
@@ -0,0 +1,7 @@
1
+ const Lego=(()=>{const w={},M=new WeakMap,k=new WeakMap,O=new WeakMap,$=new Set,P=new Map,B=new Map,H=new Map,q=new Map;let G={};const p={onError:(e,s,c)=>{console.error(`[Lego Error] [${s}]`,e,c)},metrics:{},syntax:"brackets"},_=()=>p.syntax==="brackets"?["[[","]]"]:["{{","}}"],L=()=>{const[e,s]=_(),c=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),o=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`${c}(.*?)${o}`,"g")},R=[],ee=e=>typeof e!="string"?e:e.replace(/[&<>"']/g,s=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[s]),K=e=>{const c=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!c.includes("-"))throw new Error(`[Lego] Invalid component definition: "${e}". Component names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return c},V=(e,s)=>{if(typeof e=="function"){const o=Array.from(document.querySelectorAll("*")).filter(t=>t.tagName.includes("-"));return[].concat(e(o))}if(e.startsWith("#")){const o=document.getElementById(e.slice(1));return o?[o]:[]}const c=s?.querySelectorAll(e)||[];return c.length>0?[...c]:[...document.querySelectorAll(e)]},j=(e,...s)=>c=>{const o=async(t,a=null,r=!0,n={})=>{if(r){const d={legoTargets:s.filter(i=>typeof i=="string"),method:t,body:a};history.pushState(d,"",e)}await F(s.length?s:null,c)};return{get:(t=!0,a={})=>o("GET",null,t,a),post:(t,a=!0,r={})=>o("POST",t,a,r),put:(t,a=!0,r={})=>o("PUT",t,a,r),patch:(t,a=!0,r={})=>o("PATCH",t,a,r),delete:(t=!0,a={})=>o("DELETE",null,t,a)}},J=(()=>{let e=!1;const s=new Set;let c=!1;return{add:o=>{!o||c||(s.add(o),!e&&(e=!0,requestAnimationFrame(()=>{c=!0;const t=Array.from(s);s.clear(),e=!1,t.forEach(a=>C(a)),setTimeout(()=>{t.forEach(a=>{const r=a._studs;if(r&&typeof r.updated=="function")try{r.updated.call(r)}catch(n){console.error("[Lego] Error in updated hook:",n)}}),c=!1},0)})))}}})(),S=(e,s,c=J)=>{if(e===null||typeof e!="object"||e instanceof Node)return e;if(M.has(e))return M.get(e);const o={get:(a,r)=>{const n=Reflect.get(a,r);return n!==null&&typeof n=="object"&&!(n instanceof Node)?S(n,s,c):n},set:(a,r,n)=>{const l=a[r],d=Reflect.set(a,r,n);return l!==n&&c.add(s),d},deleteProperty:(a,r)=>{const n=Reflect.deleteProperty(a,r);return c.add(s),n}},t=new Proxy(e,o);return M.set(e,t),t},I=e=>{try{return new Function(`return (${e})`)()}catch(s){return console.error("[Lego] Failed to parse b-data:",e,s),{}}},N=e=>(k.has(e)||k.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null,hasGlobalDependency:!1}),k.get(e)),D=(e,s)=>{if(!e)return"";const c=e.trim().split(".");let o=s;for(const t of c){if(o==null)return"";o=o[t]}return o??""},Z=(e,s)=>{let c=e.parentElement||e.getRootNode().host;for(;c;){if(c.tagName&&c.tagName.toLowerCase()===s.toLowerCase())return c._studs;c=c.parentElement||c.getRootNode&&c.getRootNode().host}},h=(e,s,c=!1)=>{if(/\b(function|eval|import|class|module|deploy|constructor|__proto__)\b/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{const o=s.state||{};let t=H.get(e);t||(t=new Function("global","self","event","helpers",`
2
+ with(helpers) {
3
+ with(this) {
4
+ return ${e}
5
+ }
6
+ }
7
+ `),H.set(e,t));const a={$ancestors:n=>Z(s.self,n),$registry:n=>B.get(n.toLowerCase()),$element:s.self,$route:Lego.globals.$route,$go:(n,...l)=>j(n,...l)(s.self),$emit:(n,l)=>{s.self.dispatchEvent(new CustomEvent(n,{detail:l,bubbles:!0,composed:!0}))}},r=t.call(o,s.global,s.self,s.event,a);return typeof r=="function"?r.call(o,s.event):r}catch(o){if(c)throw o;p.onError(o,"render-error",s.self);return}},z=(e,s)=>{if(e.type==="checkbox")e.checked!==!!s&&(e.checked=!!s);else{const c=s==null?"":String(s);e.value!==c&&(e.value=c)}},x=(e,s,c=null)=>{const o=s._studs,t=n=>{const l=N(n);if(!l.bound){if(n.hasAttributes()){const d=n.attributes;for(let i=0;i<d.length;i++){const u=d[i];if(u.name.startsWith("@")){const f=u.name.slice(1);n.addEventListener(f,g=>{try{let m=o;if(c){const y=h(c.listName,{state:o,global:Lego.globals,self:s})[c.index];m=Object.assign(Object.create(o),{[c.name]:y})}h(u.value,{state:m,global:Lego.globals,self:n,event:g},!0)}catch(m){p.onError(m,"event-handler",n)}})}}if(n.hasAttribute("b-sync")){const i=n.getAttribute("b-sync"),u=()=>{try{let f,g;if(c&&i.startsWith(c.name+".")){const y=h(c.listName,{state:o,global:Lego.globals,self:s})[c.index];if(!y)return;const E=i.split(".").slice(1);g=E.pop(),f=E.reduce((T,A)=>T[A],y)}else{const b=i.split(".");g=b.pop(),f=b.reduce((y,E)=>y[E],o)}const m=n.type==="checkbox"?n.checked:n.value;f&&f[g]!==m&&(f[g]=m)}catch(f){p.onError(f,"sync-update",n)}};n.addEventListener("input",u),n.addEventListener("change",u)}if(n.hasAttribute("b-var")){const i=n.getAttribute("b-var");o.$vars&&(o.$vars[i]=n)}}l.bound=!0}};e instanceof Element&&t(e);const a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);let r;for(;r=a.nextNode();)t(r)},Y=e=>{const s=[],c=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);let o;for(;o=c.nextNode();){if((r=>{let n=r.parentNode;for(;n&&n!==e;){if(n.hasAttribute&&n.hasAttribute("b-for"))return!0;n=n.parentNode}return!1})(o))continue;const a=r=>{if(/\bglobal\b/.test(r)){const n=e.host||e;N(n).hasGlobalDependency=!0}};if(o.nodeType===Node.ELEMENT_NODE){if(o.hasAttribute("b-if")){const n=o.getAttribute("b-if");a(n);const l=document.createComment(`b-if: ${n}`),d=N(o);d.anchor=l,s.push({type:"b-if",node:o,anchor:l,expr:n})}if(o.hasAttribute("b-show")){const n=o.getAttribute("b-show");a(n),s.push({type:"b-show",node:o,expr:n})}if(o.hasAttribute("b-for")){const n=o.getAttribute("b-for").match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);n&&(a(n[2]),s.push({type:"b-for",node:o,itemName:n[1],listName:n[2].trim(),template:o.cloneNode(!0)}),o.innerHTML="")}if(o.hasAttribute("b-text")&&s.push({type:"b-text",node:o,path:o.getAttribute("b-text")}),o.hasAttribute("b-html")){const n=o.getAttribute("b-html");a(n),s.push({type:"b-html",node:o,expr:n})}o.hasAttribute("b-sync")&&s.push({type:"b-sync",node:o});const[r]=_();[...o.attributes].forEach(n=>{n.value.includes(r)&&(a(n.value),s.push({type:"attr",node:o,attrName:n.name,template:n.value}))})}else if(o.nodeType===Node.TEXT_NODE){const[r]=_();o.textContent.includes(r)&&(a(o.textContent),s.push({type:"text",node:o,template:o.textContent}))}}return s},Q=(e,s)=>{const c=a=>{if(a.nodeType===Node.TEXT_NODE){a._tpl===void 0&&(a._tpl=a.textContent);const r=a._tpl.replace(L(),(n,l)=>h(l.trim(),{state:s,global:Lego.globals,self:a})??"");a.textContent!==r&&(a.textContent=r)}else if(a.nodeType===Node.ELEMENT_NODE){const[r]=_();[...a.attributes].forEach(n=>{if(n._tpl===void 0&&(n._tpl=n.value),n._tpl.includes(r)){const l=n._tpl.replace(L(),(d,i)=>h(i.trim(),{state:s,global:Lego.globals,self:a})??"");n.value!==l&&(n.value=l,n.name==="class"&&(a.className=l))}})}};c(e);const o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);let t;for(;t=o.nextNode();)c(t)},C=e=>{const s=e._studs;if(!s)return;const c=N(e);if(!c.rendering){c.rendering=!0,p.metrics&&p.metrics.onRenderStart&&p.metrics.onRenderStart(e);try{const o=e.shadowRoot||e;c.bindings||(c.bindings=Y(o)),c.bindings.forEach(t=>{if(t.type==="b-if"){const a=!!h(t.expr,{state:s,global:Lego.globals,self:t.node}),r=!!t.node.parentNode;a&&!r?t.anchor.parentNode&&t.anchor.parentNode.replaceChild(t.node,t.anchor):!a&&r&&t.node.parentNode.replaceChild(t.anchor,t.node)}if(t.type==="b-show"&&(t.node.style.display=h(t.expr,{state:s,global:Lego.globals,self:t.node})?"":"none"),t.type==="b-text"&&(t.node.textContent=D(t.path,s)),t.type==="b-html"&&(t.node.innerHTML=h(t.expr,{state:s,global:Lego.globals,self:t.node})||""),t.type==="b-sync"&&z(t.node,D(t.node.getAttribute("b-sync"),s)),t.type==="text"){const a=t.template.replace(L(),(r,n)=>h(n.trim(),{state:s,global:Lego.globals,self:t.node})??"");t.node.textContent!==a&&(t.node.textContent=a)}if(t.type==="attr"){const a=t.template.replace(L(),(r,n)=>h(n.trim(),{state:s,global:Lego.globals,self:t.node})??"");t.node.getAttribute(t.attrName)!==a&&(t.node.setAttribute(t.attrName,a),t.attrName==="class"&&(t.node.className=a))}if(t.type==="b-for"){const a=h(t.listName,{state:s,global:Lego.globals,self:e})||[];O.has(t.node)||O.set(t.node,new Map);const r=O.get(t.node),n=new Set;a.forEach((l,d)=>{const i=l&&typeof l=="object"?l.__id||(l.__id=Math.random()):`${d}-${l}`;n.add(i);let u=r.get(i);u||(u=t.template.cloneNode(!0),u.removeAttribute("b-for"),r.set(i,u),x(u,e,{name:t.itemName,listName:t.listName,index:d}));const f=Object.assign(Object.create(s),{[t.itemName]:l});Q(u,f),u.querySelectorAll("[b-sync]").forEach(g=>{const m=g.getAttribute("b-sync");if(m.startsWith(t.itemName+".")){const b=h(t.listName,{state:s,global:Lego.globals,self:e});z(g,D(m.split(".").slice(1).join("."),b[d]))}}),t.node.children[d]!==u&&t.node.insertBefore(u,t.node.children[d]||null)});for(const[l,d]of r.entries())n.has(l)||(d.remove(),r.delete(l))}}),s===Lego.globals&&$.forEach(t=>{N(t).hasGlobalDependency&&C(t)})}catch(o){p.onError(o,"render",e)}finally{p.metrics&&p.metrics.onRenderEnd&&p.metrics.onRenderEnd(e),c.rendering=!1}}},v=e=>{if(!e||e.nodeType!==Node.ELEMENT_NODE)return;const s=N(e),c=e.tagName.toLowerCase(),o=w[c];if(o&&!s.snapped){s.snapped=!0;const a=o.content.cloneNode(!0),r=e.attachShadow({mode:"open"}),n=(o.getAttribute("b-styles")||"").split(/\s+/).filter(Boolean);if(n.length>0){const f=n.flatMap(g=>q.get(g)||[]);f.length>0&&(r.adoptedStyleSheets=[...f])}const l=P.get(c)||{},d=I(o.getAttribute("b-data")||"{}"),i=I(e.getAttribute("b-data")||"{}");e._studs=S({...l,...d,...i,$vars:{},$element:e,$emit:(f,g)=>{e.dispatchEvent(new CustomEvent(f,{detail:g,bubbles:!0,composed:!0}))},get $route(){return Lego.globals.$route},get $go(){return Lego.globals.$go}},e),r.appendChild(a);const u=r.querySelector("style");if(u&&(u.textContent=u.textContent.replace(/\bself\b/g,":host")),x(r,e),$.add(e),C(e),[...r.children].forEach(v),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(f){p.onError(f,"mounted",e)}}let t=e.parentElement;for(;t&&!t._studs;)t=t.parentElement;t&&t._studs&&x(e,t),[...e.children].forEach(v)},W=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(s){console.error("[Lego] Error in unmounted:",s)}e.shadowRoot&&[...e.shadowRoot.children].forEach(W),$.delete(e),[...e.children].forEach(W)},F=async(e=null,s=null)=>{const c=window.location.pathname,o=window.location.search,t=R.find(d=>d.regex.test(c));if(!t)return;let a=[];if(e)a=e.flatMap(d=>V(d,s));else{const d=document.querySelector("lego-router");d&&(a=[d])}if(a.length===0)return;const r=c.match(t.regex).slice(1),n=Object.fromEntries(t.paramNames.map((d,i)=>[d,r[i]])),l=Object.fromEntries(new URLSearchParams(o));t.middleware&&!await t.middleware(n,Lego.globals)||(Lego.globals.$route.url=c+o,Lego.globals.$route.route=t.path,Lego.globals.$route.params=n,Lego.globals.$route.query=l,Lego.globals.$route.method=history.state?.method||"GET",Lego.globals.$route.body=history.state?.body||null,a.forEach(d=>{if(d){const i=document.createElement(t.tagName);d.replaceChildren(i)}}))},U={init:async(e=document.body,s={})=>{(!e||typeof e.nodeType!="number")&&(e=document.body),G=s.styles||{},p.loader=s.loader;const c=Object.entries(G).map(async([t,a])=>{const r=await Promise.all(a.map(async n=>{try{const d=await(await fetch(n)).text(),i=new CSSStyleSheet;return await i.replace(d),i}catch(l){return console.error(`[Lego] Failed to load stylesheet: ${n}`,l),null}}));q.set(t,r.filter(n=>n!==null))});await Promise.all(c),document.querySelectorAll("template[b-id]").forEach(t=>{w[t.getAttribute("b-id")]=t}),new MutationObserver(t=>t.forEach(a=>{a.addedNodes.forEach(r=>{if(r.nodeType===Node.ELEMENT_NODE){v(r);const n=r.tagName.toLowerCase();if(n.includes("-")&&!w[n]&&p.loader&&!$.has(r)){const l=p.loader(n);if(l){const d=typeof l=="string"?fetch(l).then(i=>i.text()):l;Promise.resolve(d).then(i=>U.defineSFC(i,n+".lego")).catch(i=>console.error(`[Lego] Failed to load ${n}:`,i))}}}}),a.removedNodes.forEach(r=>r.nodeType===Node.ELEMENT_NODE&&W(r))})).observe(e,{childList:!0,subtree:!0}),e._studs=Lego.globals,v(e),x(e,e),C(e),R.length>0&&(window.addEventListener("popstate",t=>{const a=t.state?.legoTargets||null;F(a)}),document.addEventListener("submit",t=>{t.preventDefault()}),document.addEventListener("click",t=>{const r=t.composedPath().find(n=>n.tagName==="A"&&(n.hasAttribute("b-target")||n.hasAttribute("b-link")));if(r){t.preventDefault();const n=r.getAttribute("href"),l=r.getAttribute("b-target"),d=l?l.split(/\s+/).filter(Boolean):[],i=r.getAttribute("b-link")!=="false";Lego.globals.$go(n,...d).get(i)}}),F())},globals:S({$route:{url:window.location.pathname,route:"",params:{},query:{},method:"GET",body:null},$go:(e,...s)=>j(e,...s)(document.body)},document.body),defineSFC:(e,s="component.lego")=>{let c="",o="{}",t="",a="",r=e;const n=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;r;){const i=r.match(n);if(!i)break;const u=i[1].toLowerCase(),f=i[2],g=i[0],m=i.index,b=`</${u}>`,y=m+g.length,E=r.indexOf(b,y);if(E===-1){console.warn(`[Lego] Unclosed <${u}> tag in ${s}`);break}const T=r.slice(y,E);if(u==="template"){c=T.trim();const A=f.match(/b-styles=["']([^"']+)["']/);A&&(t=A[1])}else if(u==="script"){const A=T.trim(),X=A.match(/export\s+default\s+({[\s\S]*})/);o=X?X[1]:A}else u==="style"&&(a=T.trim());r=r.slice(E+b.length)}const l=K(s),d=new Function(`return ${o}`)();a&&(c=`<style>${a}</style>`+c),w[l]=document.createElement("template"),w[l].innerHTML=c,w[l].setAttribute("b-styles",t),P.set(l,d),document.querySelectorAll(l).forEach(i=>!N(i).snapped&&v(i))},define:(e,s,c={},o="")=>{const t=document.createElement("template");t.setAttribute("b-id",e),t.setAttribute("b-styles",o),t.innerHTML=s,w[e]=t,P.set(e,c);try{B.set(e.toLowerCase(),S({...c},document.body))}catch(a){p.onError(a,"define",e)}document.querySelectorAll(e).forEach(v)},getActiveComponentsCount:()=>$.size,config:p,route:(e,s,c=null)=>{const o=[],t=e.replace(/:([^\/]+)/g,(a,r)=>(o.push(r),"([^/]+)"));R.push({path:e,regex:new RegExp(`^${t}$`),tagName:s,paramNames:o,middleware:c})}};return U})();typeof window<"u"&&(window.Lego=Lego);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lego-dom",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "license": "MIT",
5
5
  "description": "A feature-rich web components + SFC frontend framework",
6
6
  "main": "main.js",
@@ -22,11 +22,13 @@
22
22
  "author": "Tersoo Ortserga",
23
23
  "scripts": {
24
24
  "test": "vitest run",
25
+ "build": "esbuild main.js --minify --outfile=main.min.js",
25
26
  "docs:dev": "vitepress dev docs",
26
27
  "docs:build": "vitepress build docs",
27
28
  "docs:preview": "vitepress preview docs"
28
29
  },
29
30
  "devDependencies": {
31
+ "esbuild": "^0.27.2",
30
32
  "jsdom": "^22.0.0",
31
33
  "vitepress": "^1.6.4",
32
34
  "vitest": "^1.0.0"