ladrillosjs 2.0.0-beta.1 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +680 -473
- package/dist/core/html/htmlRenderer.d.ts +6 -1
- package/dist/core/html/htmlparser.d.ts +7 -1
- package/dist/{index-CXHidyhO.js → index-63mcJ9Hl.js} +4 -4
- package/dist/index-63mcJ9Hl.js.map +1 -0
- package/dist/{index-VkDZJVOR.mjs → index-CUJmLlUh.mjs} +4 -4
- package/dist/index-CUJmLlUh.mjs.map +1 -0
- package/dist/ladrillosjs.cjs.js +1 -1
- package/dist/ladrillosjs.es.js +1 -1
- package/dist/ladrillosjs.umd.js +26 -17
- package/dist/ladrillosjs.umd.js.map +1 -1
- package/dist/types/LadrilloTypes.d.ts +14 -0
- package/dist/webcomponent-DNeyn3kB.js +79 -0
- package/dist/webcomponent-DNeyn3kB.js.map +1 -0
- package/dist/webcomponent-DzBRHkic.mjs +970 -0
- package/dist/webcomponent-DzBRHkic.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/index-CXHidyhO.js.map +0 -1
- package/dist/index-VkDZJVOR.mjs.map +0 -1
- package/dist/webcomponent-CJ3lZBZb.mjs +0 -703
- package/dist/webcomponent-CJ3lZBZb.mjs.map +0 -1
- package/dist/webcomponent-i9W7LUiv.js +0 -70
- package/dist/webcomponent-i9W7LUiv.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BindingDescriptor, ConditionalDescriptor } from "../../types/LadrilloTypes";
|
|
1
|
+
import { BindingDescriptor, ConditionalDescriptor, LoopDescriptor } from "../../types/LadrilloTypes";
|
|
2
2
|
/**
|
|
3
3
|
* Safely sets a nested value in an object using a path array.
|
|
4
4
|
* Example: setValue({ user: {} }, ['user', 'name'], 'John') sets user.name to 'John'
|
|
@@ -16,3 +16,8 @@ export declare const renderBindings: (bindings: BindingDescriptor[], context: un
|
|
|
16
16
|
* Shows/hides elements based on their $if, $else-if, $else conditions.
|
|
17
17
|
*/
|
|
18
18
|
export declare const renderConditionals: (conditionalGroups: ConditionalDescriptor[][], context: unknown, component?: any) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Renders loop elements based on array data.
|
|
21
|
+
* Creates clones of the template for each item in the array.
|
|
22
|
+
*/
|
|
23
|
+
export declare const renderLoops: (loops: LoopDescriptor[], context: unknown, component?: any) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BindingDescriptor, TwoWayBindingDescriptor, ConditionalDescriptor } from "../../types/LadrilloTypes";
|
|
1
|
+
import { BindingDescriptor, TwoWayBindingDescriptor, ConditionalDescriptor, LoopDescriptor } from "../../types/LadrilloTypes";
|
|
2
2
|
/**
|
|
3
3
|
* Injects the template HTML into the host element and scans for data bindings.
|
|
4
4
|
* Returns a list of all bindings found in text nodes and attributes.
|
|
@@ -7,6 +7,7 @@ export declare const loadTemplate: (host: HTMLElement | ShadowRoot, template: st
|
|
|
7
7
|
bindings: BindingDescriptor[];
|
|
8
8
|
twoWayBindings: TwoWayBindingDescriptor[];
|
|
9
9
|
conditionals: ConditionalDescriptor[][];
|
|
10
|
+
loops: LoopDescriptor[];
|
|
10
11
|
};
|
|
11
12
|
/**
|
|
12
13
|
* Extracts variable names from conditional expressions.
|
|
@@ -14,3 +15,8 @@ export declare const loadTemplate: (host: HTMLElement | ShadowRoot, template: st
|
|
|
14
15
|
* e.g., "{sending}" → ["sending"], "{count > 5}" → ["count"]
|
|
15
16
|
*/
|
|
16
17
|
export declare const extractConditionalVariables: (conditionalGroups: ConditionalDescriptor[][]) => Set<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Extracts variable names from loop expressions.
|
|
20
|
+
* e.g., "item in items" → ["items"], "(user, index) in users" → ["users"]
|
|
21
|
+
*/
|
|
22
|
+
export declare const extractLoopVariables: (loops: LoopDescriptor[]) => Set<string>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var y=t=>{throw TypeError(t)};var R=(t,e,r)=>e.has(t)||y("Cannot "+r);var S=(t,e,r)=>e.has(t)?y("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r);var C=(t,e,r)=>(R(t,e,"access private method"),r);var a=(t,e,r)=>new Promise((s,o)=>{var n=u=>{try{i(r.next(u))}catch(h){o(h)}},c=u=>{try{i(r.throw(u))}catch(h){o(h)}},i=u=>u.done?s(u.value):Promise.resolve(u.value).then(n,c);i((r=r.apply(t,e)).next())});const $=()=>{try{return!1}catch(t){return process.env.NODE_ENV==="development"}},m={log(t,...e){$()&&console.log(t,...e)},error(t,...e){console.error(t,...e)},warn(t,...e){$()&&console.warn(t,...e)}},l=new Map,M=25,z=t=>{const e=l.get(t);return e&&(l.delete(t),l.set(t,e)),e},F=(t,e)=>{if(l.has(t))l.delete(t);else if(l.size>=M){const r=l.keys().next().value;r&&l.delete(r)}l.set(t,e)},L=t=>a(null,null,function*(){if(!t)throw new Error("Path cannot be null or empty");const e=z(t);if(e)return e;try{const r=yield fetch(t);if(!r.ok)throw new Error(`Failed to fetch component from ${t}: ${r.statusText}`);const s=yield r.text();return F(t,s),s}catch(r){m.error(`Error fetching component from ${t}: ${r.message}`)}}),j=t=>a(null,null,function*(){try{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);return yield e.text()}catch(e){return m.error(`Failed to fetch resource at ${t}:`,e),""}}),d={bindings:/{([^}]+)}/g,comments:{js:/\/\*[\s\S]*?\*\/|\/\/.*$/gm,css:/\/\*[\s\S]*?\*\//g,html:/<!--[\s\S]*?-->/g}},D=new DOMParser,N=(t,e)=>a(null,null,function*(){const r=B(t),{scripts:s,externalScripts:o}=G(r),n=yield O(r),c=r.body.innerHTML.trim();return{tagName:e,template:c,scripts:s,externalScripts:o,styles:n}}),B=t=>D.parseFromString(t.replace(d.comments.html,""),"text/html"),H=t=>["/@vite/","/__vite","/webpack-dev-server","/hot-update","/__webpack_hmr","/browser-sync/","/livereload.js"].some(r=>t.includes(r)),G=t=>{var s,o;const e=[],r=[];for(const n of t.querySelectorAll("script")){if(n.src){if(H(n.src)){n.remove();continue}const c=n.hasAttribute("external");r.push({src:n.getAttribute("src")||n.src,type:(s=n.type)!=null?s:null,external:c})}else if(n.textContent){let c=n.textContent.trim();c=c.replace(d.comments.js,"").trim(),e.push({content:c,type:(o=n.type)!=null?o:null})}n.remove()}return{scripts:e,externalScripts:r}},K=t=>{const e=t.match(/const __vite__css = "([
|
|
1
|
+
"use strict";var y=t=>{throw TypeError(t)};var R=(t,e,r)=>e.has(t)||y("Cannot "+r);var S=(t,e,r)=>e.has(t)?y("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r);var C=(t,e,r)=>(R(t,e,"access private method"),r);var a=(t,e,r)=>new Promise((s,o)=>{var n=u=>{try{i(r.next(u))}catch(h){o(h)}},c=u=>{try{i(r.throw(u))}catch(h){o(h)}},i=u=>u.done?s(u.value):Promise.resolve(u.value).then(n,c);i((r=r.apply(t,e)).next())});const $=()=>{try{return!1}catch(t){return process.env.NODE_ENV==="development"}},m={log(t,...e){$()&&console.log(t,...e)},error(t,...e){console.error(t,...e)},warn(t,...e){$()&&console.warn(t,...e)}},l=new Map,M=25,z=t=>{const e=l.get(t);return e&&(l.delete(t),l.set(t,e)),e},F=(t,e)=>{if(l.has(t))l.delete(t);else if(l.size>=M){const r=l.keys().next().value;r&&l.delete(r)}l.set(t,e)},L=t=>a(null,null,function*(){if(!t)throw new Error("Path cannot be null or empty");const e=z(t);if(e)return e;try{const r=yield fetch(t);if(!r.ok)throw new Error(`Failed to fetch component from ${t}: ${r.statusText}`);const s=yield r.text();return F(t,s),s}catch(r){m.error(`Error fetching component from ${t}: ${r.message}`)}}),j=t=>a(null,null,function*(){try{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);return yield e.text()}catch(e){return m.error(`Failed to fetch resource at ${t}:`,e),""}}),d={bindings:/{([^}]+)}/g,comments:{js:/\/\*[\s\S]*?\*\/|\/\/.*$/gm,css:/\/\*[\s\S]*?\*\//g,html:/<!--[\s\S]*?-->/g}},D=new DOMParser,N=(t,e)=>a(null,null,function*(){const r=B(t),{scripts:s,externalScripts:o}=G(r),n=yield O(r),c=r.body.innerHTML.trim();return{tagName:e,template:c,scripts:s,externalScripts:o,styles:n}}),B=t=>D.parseFromString(t.replace(d.comments.html,""),"text/html"),H=t=>["/@vite/","/__vite","/webpack-dev-server","/hot-update","/__webpack_hmr","/browser-sync/","/livereload.js"].some(r=>t.includes(r)),G=t=>{var s,o;const e=[],r=[];for(const n of t.querySelectorAll("script")){if(n.src){if(H(n.src)){n.remove();continue}const c=n.hasAttribute("external");r.push({src:n.getAttribute("src")||n.src,type:(s=n.type)!=null?s:null,external:c})}else if(n.textContent){let c=n.textContent.trim();c=c.replace(d.comments.js,"").trim(),e.push({content:c,type:(o=n.type)!=null?o:null})}n.remove()}return{scripts:e,externalScripts:r}},K=t=>{const e=t.match(/const __vite__css = "((?:[^"\\]|\\.)*)"/);if(e&&e[1])return e[1].replace(/\\r\\n/g,`
|
|
2
2
|
`).replace(/\\n/g,`
|
|
3
|
-
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const r=t.match(/export\s+default\s+"([
|
|
3
|
+
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const r=t.match(/export\s+default\s+"((?:[^"\\]|\\.)*)"/);return r&&r[1]?r[1].replace(/\\r\\n/g,`
|
|
4
4
|
`).replace(/\\n/g,`
|
|
5
5
|
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):t.includes("import")||t.includes("export")?(m.warn("CSS file returned JavaScript module format. CSS may not load correctly."),""):t},O=t=>a(null,null,function*(){let e="";const r=t.querySelectorAll("style, link[rel='stylesheet']");for(const s of r){if(s.tagName==="LINK"){const n=yield j(s.href),c=K(n);c&&(e+=`
|
|
6
6
|
`+c)}else if(s.tagName==="STYLE"){const o=s;if(o.textContent){let n=o.textContent.trim();n=n.replace(d.comments.css,"").trim(),e+=`
|
|
7
|
-
`+n}}s.remove()}return e.trim()});var p,x;class W{constructor(){S(this,p);this.components={}}registerComponent(e,r,s=!0){return a(this,null,function*(){if(this.components[e]){m.warn(`Component with name "${e}" is already registered.`);return}try{const o=yield L(r),n=yield N(o,e);this.components[e]={tagName:e,template:n.template,scripts:n.scripts,externalScripts:n.externalScripts,styles:n.styles,sourcePath:r},m.log(`Component ${e} registered successfully`),yield C(this,p,x).call(this,e,s)}catch(o){m.error(`Failed to register component "${e}": ${o.message}`);return}})}}p=new WeakSet,x=function(e,r){return a(this,null,function*(){const{defineWebComponent:s}=yield Promise.resolve().then(()=>require("./webcomponent-
|
|
8
|
-
//# sourceMappingURL=index-
|
|
7
|
+
`+n}}s.remove()}return e.trim()});var p,x;class W{constructor(){S(this,p);this.components={}}registerComponent(e,r,s=!0){return a(this,null,function*(){if(this.components[e]){m.warn(`Component with name "${e}" is already registered.`);return}try{const o=yield L(r),n=yield N(o,e);this.components[e]={tagName:e,template:n.template,scripts:n.scripts,externalScripts:n.externalScripts,styles:n.styles,sourcePath:r},m.log(`Component ${e} registered successfully`),yield C(this,p,x).call(this,e,s)}catch(o){m.error(`Failed to register component "${e}": ${o.message}`);return}})}}p=new WeakSet,x=function(e,r){return a(this,null,function*(){const{defineWebComponent:s}=yield Promise.resolve().then(()=>require("./webcomponent-DNeyn3kB.js"));this.components[e]&&s(this.components[e],r)})};const v=new W;class X{constructor(){this.listeners=new Map}emit(e,r){const s=new CustomEvent(e,{detail:r,bubbles:!0,composed:!0});document.dispatchEvent(s);const o=this.listeners.get(e);if(!o||o.size===0)return Promise.resolve();const n=[];return o.forEach(c=>{try{const i=c(r);i instanceof Promise&&n.push(i)}catch(i){console.error(`Error in event listener for "${e}":`,i),n.push(Promise.reject(i))}}),n.length>0?Promise.all(n).then(()=>{}):Promise.resolve()}listen(e,r){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(r),()=>{this.off(e,r)}}off(e,r){const s=this.listeners.get(e);s&&(s.delete(r),s.size===0&&this.listeners.delete(e))}clear(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var r,s;return(s=(r=this.listeners.get(e))==null?void 0:r.size)!=null?s:0}}const g=new X,E=(t,e,r)=>v.registerComponent(t,e,r),_=t=>a(null,null,function*(){yield Promise.all(t.map(({name:e,path:r,useShadowDOM:s})=>v.registerComponent(e,r,s)))}),q=(t,e)=>g.listen(t,e),P=(t,e)=>{g.emit(t,e)},I=(t,e)=>{if(e){const r=e.tagName.toLowerCase();window.__ladrilloContexts||(window.__ladrilloContexts=new Map),window.__ladrilloContexts.set(r,{shadowRoot:t,element:e})}},w=()=>{const t=window.__ladrilloContexts;if(t&&t.size>0){const e=Array.from(t.values());return e[e.length-1]}return null},b=()=>{const t=w();return t&&t.element?t.element.state||{}:{}},f=t=>{const e=w();e&&e.setState&&e.setState(t)},A=(t,e)=>(f({[t]:e}),r=>{f({[t]:r})}),T=(t,e)=>{if(e)return e.querySelector(t);const r=w();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelector(t);if(o)return o}}return document.querySelector(t)},k=(t,e)=>{if(e)return e.querySelectorAll(t);const r=w();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelectorAll(t);if(o.length>0)return o}}return document.querySelectorAll(t)};typeof window!="undefined"&&(window.ladrillosjs={registerComponent:E,registerComponents:_},window.$listen=q,window.$emit=P,window.$querySelector=T,window.$querySelectorAll=k,window.$reactive=A,window.$setState=f,window.$getState=b);exports.$emit=P;exports.$getState=b;exports.$listen=q;exports.$querySelector=T;exports.$querySelectorAll=k;exports.$reactive=A;exports.$setState=f;exports.REGEX_PATTERNS=d;exports.__setComponentContext=I;exports.eventBus=g;exports.logger=m;exports.registerComponent=E;exports.registerComponents=_;
|
|
8
|
+
//# sourceMappingURL=index-63mcJ9Hl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-63mcJ9Hl.js","sources":["../src/utils/logger.ts","../src/cache/index.ts","../src/core/componentSource.ts","../src/utils/regex.ts","../src/core/componentParser.ts","../src/core/main.ts","../src/core/eventBus.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Utility for conditional logging based on environment\r\n */\r\n\r\n// Type guard for Vite environment\r\nconst isDevelopment = (): boolean => {\r\n try {\r\n return (import.meta as any).env?.DEV === true;\r\n } catch {\r\n return process.env.NODE_ENV === 'development';\r\n }\r\n};\r\n\r\nexport const logger = {\r\n /**\r\n * Log a message only in development mode\r\n * @param message - The message to log\r\n * @param args - Additional arguments to log\r\n */\r\n log(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.log(message, ...args);\r\n }\r\n },\r\n\r\n /**\r\n * Log an error (always logs in both dev and production)\r\n * @param message - The error message\r\n * @param args - Additional arguments to log\r\n */\r\n error(message: string, ...args: any[]): void {\r\n console.error(message, ...args);\r\n },\r\n\r\n /**\r\n * Log a warning only in development mode\r\n * @param message - The warning message\r\n * @param args - Additional arguments to log\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.warn(message, ...args);\r\n }\r\n },\r\n};\r\n","const cache = new Map<string, string>();\r\nconst maxCacheSize = 25; // TODO: make configurable for developer to set\r\n\r\n/**\r\n * LRU Cache: Gets cached content and marks it as recently used\r\n * Moves the accessed item to the end of the Map (most recently used position)\r\n * This ensures frequently accessed components stay in cache longer\r\n * @param path - The file path to retrieve from cache\r\n * @returns The cached content or undefined if not found\r\n */\r\nexport const getCached = (path: string): string | undefined => {\r\n const cached = cache.get(path);\r\n if (cached) {\r\n // LRU: Move to end (most recently used position)\r\n cache.delete(path);\r\n cache.set(path, cached);\r\n }\r\n return cached;\r\n};\r\n\r\n/**\r\n * LRU Cache: Stores content with automatic eviction of least recently used items\r\n * Maintains cache size limit by removing oldest items when full\r\n * Updates existing items without affecting cache size\r\n * @param path - The file path to cache\r\n * @param content - The content to store\r\n */\r\nexport const setCache = (path: string, content: string): void => {\r\n if (cache.has(path)) {\r\n // Update existing: remove and re-add to mark as most recent\r\n cache.delete(path);\r\n } else if (cache.size >= maxCacheSize) {\r\n // Cache full: remove least recently used (first item in Map)\r\n const firstKey = cache.keys().next().value;\r\n if (firstKey) {\r\n cache.delete(firstKey);\r\n }\r\n }\r\n // Add/update as most recently used (end of Map)\r\n cache.set(path, content);\r\n};\r\n","import { getCached, setCache } from \"../cache\";\r\nimport { logger } from \"../utils/logger\";\r\n\r\n/**\r\n * Fetches component source with caching support\r\n * @param path - The file path to fetch\r\n * @returns The component source content\r\n */\r\nexport const fetchComponentSource = async (\r\n path: string\r\n): Promise<string | undefined> => {\r\n if (!path) {\r\n throw new Error(\"Path cannot be null or empty\");\r\n }\r\n\r\n const cached = getCached(path);\r\n if (cached) return cached;\r\n\r\n // fetch and cache\r\n try {\r\n const response = await fetch(path);\r\n\r\n if (!response.ok) {\r\n throw new Error(\r\n `Failed to fetch component from ${path}: ${response.statusText}`\r\n );\r\n }\r\n\r\n const text = await response.text();\r\n setCache(path, text);\r\n\r\n return text;\r\n } catch (error) {\r\n logger.error(\r\n `Error fetching component from ${path}: ${(error as Error).message}`\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * Safe fetch helper that returns empty string on error\r\n * @param url - The URL to fetch\r\n * @returns The fetched content or empty string\r\n */\r\nexport const safeFetch = async (url: string): Promise<string> => {\r\n try {\r\n const res = await fetch(url);\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n return await res.text();\r\n } catch (err) {\r\n logger.error(`Failed to fetch resource at ${url}:`, err);\r\n return \"\";\r\n }\r\n};\r\n","import { RegexPatterns } from \"../types/LadrilloTypes\";\r\n\r\nexport const REGEX_PATTERNS: RegexPatterns = {\r\n bindings: /{([^}]+)}/g,\r\n comments: {\r\n js: /\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*$/gm,\r\n css: /\\/\\*[\\s\\S]*?\\*\\//g,\r\n html: /<!--[\\s\\S]*?-->/g,\r\n },\r\n};\r\n","import {\r\n ExternalScriptElement,\r\n LadrillosComponent,\r\n ScriptElement,\r\n} from \"../types/LadrilloTypes\";\r\nimport { REGEX_PATTERNS } from \"../utils/regex\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { safeFetch } from \"./componentSource\";\r\n\r\nconst parser = new DOMParser();\r\n\r\n/**\r\n * Parses component HTML and extracts scripts and styles\r\n * @param source - The HTML source of the component\r\n * @param name - The name of the component\r\n * @returns Parsed component object\r\n */\r\nexport const parseComponent = async (\r\n source: string,\r\n name: string\r\n): Promise<LadrillosComponent> => {\r\n const doc = parseComponentHTML(source);\r\n const { scripts, externalScripts } = extractScripts(doc);\r\n const styles = await extractStyles(doc);\r\n const template = doc.body.innerHTML.trim();\r\n\r\n return {\r\n tagName: name,\r\n template,\r\n scripts,\r\n externalScripts,\r\n styles,\r\n };\r\n};\r\n\r\n/**\r\n * Parses HTML content and removes comments\r\n * @param source - The HTML source to parse\r\n * @returns Parsed DOM document\r\n */\r\nexport const parseComponentHTML = (source: string): Document => {\r\n return parser.parseFromString(\r\n source.replace(REGEX_PATTERNS.comments.html, \"\"),\r\n \"text/html\"\r\n );\r\n};\r\n\r\n/**\r\n * Checks if a script URL is a development server script that should be ignored.\r\n * Dev server scripts (Vite, Webpack HMR, etc.) are injected by the dev environment\r\n * and should not be processed as part of the component.\r\n */\r\nconst isDevServerScript = (src: string): boolean => {\r\n const devPatterns = [\r\n \"/@vite/\", // Vite dev client\r\n \"/__vite\", // Vite internal\r\n \"/webpack-dev-server\", // Webpack dev server\r\n \"/hot-update\", // Webpack HMR\r\n \"/__webpack_hmr\", // Webpack HMR\r\n \"/browser-sync/\", // Browser Sync\r\n \"/livereload.js\", // LiveReload\r\n ];\r\n\r\n return devPatterns.some((pattern) => src.includes(pattern));\r\n};\r\n\r\n/**\r\n * Extracts and processes script elements from the document\r\n * @param doc - The parsed document\r\n * @returns Object containing scripts and external scripts\r\n */\r\nexport const extractScripts = (\r\n doc: Document\r\n): {\r\n scripts: ScriptElement[];\r\n externalScripts: ExternalScriptElement[];\r\n} => {\r\n const scripts: ScriptElement[] = [];\r\n const externalScripts: ExternalScriptElement[] = [];\r\n\r\n for (const el of doc.querySelectorAll(\"script\")) {\r\n if (el.src) {\r\n // Skip dev server scripts (Vite, Webpack, etc.)\r\n if (isDevServerScript(el.src)) {\r\n el.remove();\r\n continue;\r\n }\r\n\r\n // Only mark as external if the 'external' attribute is explicitly present\r\n const isExternal = el.hasAttribute(\"external\");\r\n\r\n externalScripts.push({\r\n src: el.getAttribute(\"src\") || el.src, // Use getAttribute to preserve relative paths\r\n type: el.type ?? null,\r\n external: isExternal,\r\n });\r\n } else if (el.textContent) {\r\n let content = el.textContent.trim();\r\n // strip JavaScript comments (single‑line and block)\r\n content = content.replace(REGEX_PATTERNS.comments.js, \"\").trim();\r\n scripts.push({\r\n content,\r\n type: el.type ?? null,\r\n });\r\n }\r\n el.remove();\r\n }\r\n\r\n return { scripts, externalScripts };\r\n};\r\n\r\n/**\r\n * Extracts CSS content from various response formats\r\n * Handles:\r\n * - Vite dev server (wrapped in __vite__css variable)\r\n * - Plain CSS files (production/CDN)\r\n * - Other build tool formats\r\n */\r\nconst extractCSSFromResponse = (response: string): string => {\r\n // Check if this is a Vite HMR response (contains __vite__css)\r\n // Use a regex that properly handles escaped quotes within the string\r\n const viteMatch = response.match(/const __vite__css = \"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (viteMatch && viteMatch[1]) {\r\n // Unescape the CSS string\r\n return viteMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // Check for other module formats (e.g., \"export default ...\")\r\n const exportMatch = response.match(/export\\s+default\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (exportMatch && exportMatch[1]) {\r\n return exportMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // If it looks like JavaScript (not CSS), warn and return empty\r\n if (response.includes(\"import\") || response.includes(\"export\")) {\r\n logger.warn(\r\n \"CSS file returned JavaScript module format. CSS may not load correctly.\"\r\n );\r\n return \"\";\r\n }\r\n\r\n // If not a module format, assume it's plain CSS (production or direct file)\r\n return response;\r\n};\r\n\r\n/**\r\n * Extracts and processes style elements from the document\r\n * @param doc - The parsed document\r\n * @returns Concatenated CSS content\r\n */\r\nexport const extractStyles = async (doc: Document): Promise<string> => {\r\n let style = \"\";\r\n\r\n // Process styles in document order (inline styles and external stylesheets)\r\n const styleElements = doc.querySelectorAll(\"style, link[rel='stylesheet']\");\r\n\r\n for (const element of styleElements) {\r\n if (element.tagName === \"LINK\") {\r\n const linkElement = element as HTMLLinkElement;\r\n const response = await safeFetch(linkElement.href);\r\n const cssContent = extractCSSFromResponse(response);\r\n if (cssContent) {\r\n style += \"\\n\" + cssContent;\r\n }\r\n } else if (element.tagName === \"STYLE\") {\r\n const styleEl = element as HTMLStyleElement;\r\n if (styleEl.textContent) {\r\n let css = styleEl.textContent.trim();\r\n // strip CSS comments\r\n css = css.replace(REGEX_PATTERNS.comments.css, \"\").trim();\r\n style += \"\\n\" + css;\r\n }\r\n }\r\n element.remove();\r\n }\r\n\r\n return style.trim();\r\n};\r\n","import { LadrillosComponent } from \"../types/LadrilloTypes\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { fetchComponentSource } from \"./componentSource\";\r\nimport { parseComponent } from \"./componentParser\";\r\n\r\nclass Ladrillos {\r\n // properties\r\n components: Record<string, LadrillosComponent>;\r\n\r\n constructor() {\r\n // Initialize the Ladrillos instance\r\n this.components = {};\r\n }\r\n\r\n async registerComponent(\r\n name: string,\r\n path: string,\r\n useShadowDOM: boolean = true\r\n ): Promise<void> {\r\n if (this.components[name]) {\r\n logger.warn(`Component with name \"${name}\" is already registered.`);\r\n return;\r\n }\r\n\r\n try {\r\n const source = await fetchComponentSource(path);\r\n const component = await parseComponent(source!, name);\r\n\r\n this.components[name] = {\r\n tagName: name,\r\n template: component.template,\r\n scripts: component.scripts,\r\n externalScripts: component.externalScripts,\r\n styles: component.styles,\r\n sourcePath: path,\r\n };\r\n\r\n // Define the web component\r\n logger.log(`Component ${name} registered successfully`);\r\n await this.#defineWebComponent(name, useShadowDOM);\r\n } catch (error) {\r\n logger.error(\r\n `Failed to register component \"${name}\": ${(error as Error).message}`\r\n );\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Defines the web component using the webcomponent module\r\n * @param name - Component name\r\n * @param useShadowDOM - Whether to use Shadow DOM\r\n */\r\n async #defineWebComponent(\r\n name: string,\r\n useShadowDOM: boolean\r\n ): Promise<void> {\r\n const { defineWebComponent } = await import(\"./webcomponent\");\r\n\r\n // safety check\r\n if (this.components[name]) {\r\n defineWebComponent(this.components[name], useShadowDOM);\r\n }\r\n }\r\n}\r\n\r\nexport const ladrillos = new Ladrillos();\r\n","/**\r\n * Global Event Bus for component-to-component communication\r\n * Allows components to emit events and listen to events from other components\r\n */\r\n\r\ntype EventCallback = (data?: any) => void | Promise<void>;\r\ntype EventListeners = Map<string, Set<EventCallback>>;\r\n\r\nclass EventBus {\r\n private listeners: EventListeners = new Map();\r\n\r\n /**\r\n * Emit an event with optional data\r\n * @param eventName - The name of the event to emit\r\n * @param data - Optional data to pass to listeners\r\n * @returns Promise that resolves when all listeners have been called\r\n */\r\n emit(eventName: string, data?: any): Promise<void> {\r\n // Also dispatch as a native DOM CustomEvent so document.addEventListener works\r\n const customEvent = new CustomEvent(eventName, {\r\n detail: data,\r\n bubbles: true,\r\n composed: true,\r\n });\r\n document.dispatchEvent(customEvent);\r\n\r\n const callbacks = this.listeners.get(eventName);\r\n\r\n if (!callbacks || callbacks.size === 0) {\r\n // No listeners, resolve immediately\r\n return Promise.resolve();\r\n }\r\n\r\n // Execute all callbacks and collect promises\r\n const promises: Promise<void>[] = [];\r\n\r\n callbacks.forEach((callback) => {\r\n try {\r\n const result = callback(data);\r\n // If callback returns a promise, add it to promises array\r\n if (result instanceof Promise) {\r\n promises.push(result);\r\n }\r\n } catch (error) {\r\n console.error(`Error in event listener for \"${eventName}\":`, error);\r\n promises.push(Promise.reject(error));\r\n }\r\n });\r\n\r\n // If any callbacks returned promises, wait for all of them\r\n if (promises.length > 0) {\r\n return Promise.all(promises).then(() => undefined);\r\n }\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * Listen to an event\r\n * @param eventName - The name of the event to listen for\r\n * @param callback - Function to call when event is emitted\r\n * @returns Function to remove the listener\r\n */\r\n listen(eventName: string, callback: EventCallback): () => void {\r\n if (!this.listeners.has(eventName)) {\r\n this.listeners.set(eventName, new Set());\r\n }\r\n\r\n this.listeners.get(eventName)!.add(callback);\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n this.off(eventName, callback);\r\n };\r\n }\r\n\r\n /**\r\n * Remove a specific event listener\r\n * @param eventName - The name of the event\r\n * @param callback - The callback to remove\r\n */\r\n off(eventName: string, callback: EventCallback): void {\r\n const callbacks = this.listeners.get(eventName);\r\n if (callbacks) {\r\n callbacks.delete(callback);\r\n // Clean up empty sets\r\n if (callbacks.size === 0) {\r\n this.listeners.delete(eventName);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event, or all listeners if no event specified\r\n * @param eventName - Optional event name to clear listeners for\r\n */\r\n clear(eventName?: string): void {\r\n if (eventName) {\r\n this.listeners.delete(eventName);\r\n } else {\r\n this.listeners.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Get count of listeners for an event\r\n * @param eventName - The event name\r\n * @returns Number of listeners\r\n */\r\n listenerCount(eventName: string): number {\r\n return this.listeners.get(eventName)?.size ?? 0;\r\n }\r\n}\r\n\r\n// Export singleton instance\r\nexport const eventBus = new EventBus();\r\n","import { ladrillos } from \"./core/main.js\";\r\nimport { eventBus } from \"./core/eventBus.js\";\r\n\r\ndeclare global {\r\n interface Window {\r\n ladrillosjs: {\r\n registerComponent: typeof registerComponent;\r\n registerComponents: typeof registerComponents;\r\n };\r\n $listen: typeof $listen;\r\n $emit: typeof $emit;\r\n $querySelector: typeof $querySelector;\r\n $querySelectorAll: typeof $querySelectorAll;\r\n $reactive: typeof $reactive;\r\n $setState: typeof $setState;\r\n $getState: typeof $getState;\r\n }\r\n}\r\n\r\nexport const registerComponent = (\r\n name: string,\r\n path: string,\r\n useShadowDOM?: boolean\r\n) => ladrillos.registerComponent(name, path, useShadowDOM);\r\n\r\nexport const registerComponents = async (\r\n components: Array<{ name: string; path: string; useShadowDOM?: boolean }>\r\n): Promise<void> => {\r\n await Promise.all(\r\n components.map(({ name, path, useShadowDOM }) =>\r\n ladrillos.registerComponent(name, path, useShadowDOM)\r\n )\r\n );\r\n};\r\n\r\n// Event bus helper functions\r\nexport const $listen = (event: string, callback: (data?: any) => void) => {\r\n return eventBus.listen(event, callback);\r\n};\r\n\r\nexport const $emit = (event: string, data?: any) => {\r\n eventBus.emit(event, data);\r\n};\r\n\r\n// Component context management\r\n// Maps script URLs to their component contexts for persistent association\r\nconst scriptContextMap = new Map<\r\n string,\r\n { shadowRoot?: ShadowRoot; element?: HTMLElement }\r\n>();\r\nconst activeContext: { shadowRoot?: ShadowRoot; element?: HTMLElement } | null =\r\n null;\r\n\r\n/**\r\n * Internal: Set component context for a script\r\n * Called by the framework when loading scripts from components\r\n */\r\nexport const __setComponentContext = (\r\n shadowRoot?: ShadowRoot,\r\n element?: HTMLElement\r\n) => {\r\n // Store in the global registry by component tag name\r\n if (element) {\r\n const tagName = element.tagName.toLowerCase();\r\n if (!(window as any).__ladrilloContexts) {\r\n (window as any).__ladrilloContexts = new Map();\r\n }\r\n (window as any).__ladrilloContexts.set(tagName, { shadowRoot, element });\r\n }\r\n};\r\n\r\n/**\r\n * Internal: Get component context for the current script\r\n */\r\nconst getComponentContext = () => {\r\n const registry = (window as any).__ladrilloContexts as Map<string, any>;\r\n if (registry && registry.size > 0) {\r\n // For now, return the last registered context\r\n // In the future, we could track which script belongs to which component\r\n const contexts = Array.from(registry.values());\r\n return contexts[contexts.length - 1];\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Get the component's reactive state (for use in module scripts with bind attribute)\r\n * Returns a Proxy that allows direct property access to component.state\r\n * @returns Proxy to component state or empty object if no component context\r\n */\r\nexport const $getState = (): any => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.element) {\r\n return (ctx.element as any).state || {};\r\n }\r\n return {};\r\n};\r\n\r\n/**\r\n * Set component state (for use in module scripts with bind attribute)\r\n * @param updates - Object with state updates\r\n */\r\nexport const $setState = (updates: any) => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.setState) {\r\n ctx.setState(updates);\r\n }\r\n};\r\n\r\n/**\r\n * Creates a reactive variable that automatically updates the component when changed.\r\n * For use in ES module scripts with the bind attribute.\r\n * @param name - The variable name (must match the binding in the template)\r\n * @param initialValue - The initial value\r\n * @returns A setter function to update the value\r\n *\r\n * @example\r\n * ```javascript\r\n * import { $reactive } from 'ladrillosjs';\r\n *\r\n * // In your module script:\r\n * const setBeers = $reactive('beers', 'loading...');\r\n *\r\n * // Later, update it:\r\n * setBeers('<card>...</card>');\r\n * ```\r\n */\r\nexport const $reactive = <T = any>(\r\n name: string,\r\n initialValue: T\r\n): ((value: T) => void) => {\r\n // Initialize the state\r\n $setState({ [name]: initialValue });\r\n\r\n // Return a setter function\r\n return (value: T) => {\r\n $setState({ [name]: value });\r\n };\r\n};\r\n\r\n// DOM query helpers with smart component context detection\r\n// Automatically searches within component context when appropriate\r\nexport const $querySelector = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): Element | null => {\r\n if (root) {\r\n return root.querySelector(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelector(selector);\r\n if (result) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelector(selector);\r\n};\r\n\r\nexport const $querySelectorAll = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): NodeListOf<Element> => {\r\n if (root) {\r\n return root.querySelectorAll(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelectorAll(selector);\r\n if (result.length > 0) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelectorAll(selector);\r\n};\r\n\r\n// for a browser‑global via <script src=\"…ladrillosjs.js\"></script>\r\nif (typeof window !== \"undefined\") {\r\n window.ladrillosjs = {\r\n registerComponent,\r\n registerComponents,\r\n };\r\n\r\n // Expose helper functions globally for non-module scripts\r\n window.$listen = $listen;\r\n window.$emit = $emit;\r\n window.$querySelector = $querySelector;\r\n window.$querySelectorAll = $querySelectorAll;\r\n window.$reactive = $reactive;\r\n window.$setState = $setState;\r\n window.$getState = $getState;\r\n}\r\n"],"names":["isDevelopment","e","logger","message","args","cache","maxCacheSize","getCached","path","cached","setCache","content","firstKey","fetchComponentSource","__async","response","text","error","safeFetch","url","res","err","REGEX_PATTERNS","parser","parseComponent","source","name","doc","parseComponentHTML","scripts","externalScripts","extractScripts","styles","extractStyles","template","isDevServerScript","src","pattern","el","isExternal","_a","_b","extractCSSFromResponse","viteMatch","exportMatch","style","styleElements","element","cssContent","styleEl","css","Ladrillos","__privateAdd","_Ladrillos_instances","useShadowDOM","component","__privateMethod","defineWebComponent_fn","defineWebComponent","ladrillos","EventBus","eventName","data","customEvent","callbacks","promises","callback","result","eventBus","registerComponent","registerComponents","components","$listen","event","$emit","__setComponentContext","shadowRoot","tagName","getComponentContext","registry","contexts","$getState","ctx","$setState","updates","$reactive","initialValue","value","$querySelector","selector","root","searchRoot","$querySelectorAll"],"mappings":"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"}
|
|
@@ -149,12 +149,12 @@ const x = () => {
|
|
|
149
149
|
}
|
|
150
150
|
return { scripts: e, externalScripts: s };
|
|
151
151
|
}, F = (t) => {
|
|
152
|
-
const e = t.match(/const __vite__css = "([
|
|
152
|
+
const e = t.match(/const __vite__css = "((?:[^"\\]|\\.)*)"/);
|
|
153
153
|
if (e && e[1])
|
|
154
154
|
return e[1].replace(/\\r\\n/g, `
|
|
155
155
|
`).replace(/\\n/g, `
|
|
156
156
|
`).replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
157
|
-
const s = t.match(/export\s+default\s+"([
|
|
157
|
+
const s = t.match(/export\s+default\s+"((?:[^"\\]|\\.)*)"/);
|
|
158
158
|
return s && s[1] ? s[1].replace(/\\r\\n/g, `
|
|
159
159
|
`).replace(/\\n/g, `
|
|
160
160
|
`).replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\") : t.includes("import") || t.includes("export") ? (m.warn(
|
|
@@ -213,7 +213,7 @@ class j {
|
|
|
213
213
|
}
|
|
214
214
|
f = new WeakSet(), C = function(e, s) {
|
|
215
215
|
return a(this, null, function* () {
|
|
216
|
-
const { defineWebComponent: r } = yield import("./webcomponent-
|
|
216
|
+
const { defineWebComponent: r } = yield import("./webcomponent-DzBRHkic.mjs");
|
|
217
217
|
this.components[e] && r(this.components[e], s);
|
|
218
218
|
});
|
|
219
219
|
};
|
|
@@ -358,4 +358,4 @@ export {
|
|
|
358
358
|
m as l,
|
|
359
359
|
H as r
|
|
360
360
|
};
|
|
361
|
-
//# sourceMappingURL=index-
|
|
361
|
+
//# sourceMappingURL=index-CUJmLlUh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CUJmLlUh.mjs","sources":["../src/utils/logger.ts","../src/cache/index.ts","../src/core/componentSource.ts","../src/utils/regex.ts","../src/core/componentParser.ts","../src/core/main.ts","../src/core/eventBus.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Utility for conditional logging based on environment\r\n */\r\n\r\n// Type guard for Vite environment\r\nconst isDevelopment = (): boolean => {\r\n try {\r\n return (import.meta as any).env?.DEV === true;\r\n } catch {\r\n return process.env.NODE_ENV === 'development';\r\n }\r\n};\r\n\r\nexport const logger = {\r\n /**\r\n * Log a message only in development mode\r\n * @param message - The message to log\r\n * @param args - Additional arguments to log\r\n */\r\n log(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.log(message, ...args);\r\n }\r\n },\r\n\r\n /**\r\n * Log an error (always logs in both dev and production)\r\n * @param message - The error message\r\n * @param args - Additional arguments to log\r\n */\r\n error(message: string, ...args: any[]): void {\r\n console.error(message, ...args);\r\n },\r\n\r\n /**\r\n * Log a warning only in development mode\r\n * @param message - The warning message\r\n * @param args - Additional arguments to log\r\n */\r\n warn(message: string, ...args: any[]): void {\r\n if (isDevelopment()) {\r\n console.warn(message, ...args);\r\n }\r\n },\r\n};\r\n","const cache = new Map<string, string>();\r\nconst maxCacheSize = 25; // TODO: make configurable for developer to set\r\n\r\n/**\r\n * LRU Cache: Gets cached content and marks it as recently used\r\n * Moves the accessed item to the end of the Map (most recently used position)\r\n * This ensures frequently accessed components stay in cache longer\r\n * @param path - The file path to retrieve from cache\r\n * @returns The cached content or undefined if not found\r\n */\r\nexport const getCached = (path: string): string | undefined => {\r\n const cached = cache.get(path);\r\n if (cached) {\r\n // LRU: Move to end (most recently used position)\r\n cache.delete(path);\r\n cache.set(path, cached);\r\n }\r\n return cached;\r\n};\r\n\r\n/**\r\n * LRU Cache: Stores content with automatic eviction of least recently used items\r\n * Maintains cache size limit by removing oldest items when full\r\n * Updates existing items without affecting cache size\r\n * @param path - The file path to cache\r\n * @param content - The content to store\r\n */\r\nexport const setCache = (path: string, content: string): void => {\r\n if (cache.has(path)) {\r\n // Update existing: remove and re-add to mark as most recent\r\n cache.delete(path);\r\n } else if (cache.size >= maxCacheSize) {\r\n // Cache full: remove least recently used (first item in Map)\r\n const firstKey = cache.keys().next().value;\r\n if (firstKey) {\r\n cache.delete(firstKey);\r\n }\r\n }\r\n // Add/update as most recently used (end of Map)\r\n cache.set(path, content);\r\n};\r\n","import { getCached, setCache } from \"../cache\";\r\nimport { logger } from \"../utils/logger\";\r\n\r\n/**\r\n * Fetches component source with caching support\r\n * @param path - The file path to fetch\r\n * @returns The component source content\r\n */\r\nexport const fetchComponentSource = async (\r\n path: string\r\n): Promise<string | undefined> => {\r\n if (!path) {\r\n throw new Error(\"Path cannot be null or empty\");\r\n }\r\n\r\n const cached = getCached(path);\r\n if (cached) return cached;\r\n\r\n // fetch and cache\r\n try {\r\n const response = await fetch(path);\r\n\r\n if (!response.ok) {\r\n throw new Error(\r\n `Failed to fetch component from ${path}: ${response.statusText}`\r\n );\r\n }\r\n\r\n const text = await response.text();\r\n setCache(path, text);\r\n\r\n return text;\r\n } catch (error) {\r\n logger.error(\r\n `Error fetching component from ${path}: ${(error as Error).message}`\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * Safe fetch helper that returns empty string on error\r\n * @param url - The URL to fetch\r\n * @returns The fetched content or empty string\r\n */\r\nexport const safeFetch = async (url: string): Promise<string> => {\r\n try {\r\n const res = await fetch(url);\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n return await res.text();\r\n } catch (err) {\r\n logger.error(`Failed to fetch resource at ${url}:`, err);\r\n return \"\";\r\n }\r\n};\r\n","import { RegexPatterns } from \"../types/LadrilloTypes\";\r\n\r\nexport const REGEX_PATTERNS: RegexPatterns = {\r\n bindings: /{([^}]+)}/g,\r\n comments: {\r\n js: /\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*$/gm,\r\n css: /\\/\\*[\\s\\S]*?\\*\\//g,\r\n html: /<!--[\\s\\S]*?-->/g,\r\n },\r\n};\r\n","import {\r\n ExternalScriptElement,\r\n LadrillosComponent,\r\n ScriptElement,\r\n} from \"../types/LadrilloTypes\";\r\nimport { REGEX_PATTERNS } from \"../utils/regex\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { safeFetch } from \"./componentSource\";\r\n\r\nconst parser = new DOMParser();\r\n\r\n/**\r\n * Parses component HTML and extracts scripts and styles\r\n * @param source - The HTML source of the component\r\n * @param name - The name of the component\r\n * @returns Parsed component object\r\n */\r\nexport const parseComponent = async (\r\n source: string,\r\n name: string\r\n): Promise<LadrillosComponent> => {\r\n const doc = parseComponentHTML(source);\r\n const { scripts, externalScripts } = extractScripts(doc);\r\n const styles = await extractStyles(doc);\r\n const template = doc.body.innerHTML.trim();\r\n\r\n return {\r\n tagName: name,\r\n template,\r\n scripts,\r\n externalScripts,\r\n styles,\r\n };\r\n};\r\n\r\n/**\r\n * Parses HTML content and removes comments\r\n * @param source - The HTML source to parse\r\n * @returns Parsed DOM document\r\n */\r\nexport const parseComponentHTML = (source: string): Document => {\r\n return parser.parseFromString(\r\n source.replace(REGEX_PATTERNS.comments.html, \"\"),\r\n \"text/html\"\r\n );\r\n};\r\n\r\n/**\r\n * Checks if a script URL is a development server script that should be ignored.\r\n * Dev server scripts (Vite, Webpack HMR, etc.) are injected by the dev environment\r\n * and should not be processed as part of the component.\r\n */\r\nconst isDevServerScript = (src: string): boolean => {\r\n const devPatterns = [\r\n \"/@vite/\", // Vite dev client\r\n \"/__vite\", // Vite internal\r\n \"/webpack-dev-server\", // Webpack dev server\r\n \"/hot-update\", // Webpack HMR\r\n \"/__webpack_hmr\", // Webpack HMR\r\n \"/browser-sync/\", // Browser Sync\r\n \"/livereload.js\", // LiveReload\r\n ];\r\n\r\n return devPatterns.some((pattern) => src.includes(pattern));\r\n};\r\n\r\n/**\r\n * Extracts and processes script elements from the document\r\n * @param doc - The parsed document\r\n * @returns Object containing scripts and external scripts\r\n */\r\nexport const extractScripts = (\r\n doc: Document\r\n): {\r\n scripts: ScriptElement[];\r\n externalScripts: ExternalScriptElement[];\r\n} => {\r\n const scripts: ScriptElement[] = [];\r\n const externalScripts: ExternalScriptElement[] = [];\r\n\r\n for (const el of doc.querySelectorAll(\"script\")) {\r\n if (el.src) {\r\n // Skip dev server scripts (Vite, Webpack, etc.)\r\n if (isDevServerScript(el.src)) {\r\n el.remove();\r\n continue;\r\n }\r\n\r\n // Only mark as external if the 'external' attribute is explicitly present\r\n const isExternal = el.hasAttribute(\"external\");\r\n\r\n externalScripts.push({\r\n src: el.getAttribute(\"src\") || el.src, // Use getAttribute to preserve relative paths\r\n type: el.type ?? null,\r\n external: isExternal,\r\n });\r\n } else if (el.textContent) {\r\n let content = el.textContent.trim();\r\n // strip JavaScript comments (single‑line and block)\r\n content = content.replace(REGEX_PATTERNS.comments.js, \"\").trim();\r\n scripts.push({\r\n content,\r\n type: el.type ?? null,\r\n });\r\n }\r\n el.remove();\r\n }\r\n\r\n return { scripts, externalScripts };\r\n};\r\n\r\n/**\r\n * Extracts CSS content from various response formats\r\n * Handles:\r\n * - Vite dev server (wrapped in __vite__css variable)\r\n * - Plain CSS files (production/CDN)\r\n * - Other build tool formats\r\n */\r\nconst extractCSSFromResponse = (response: string): string => {\r\n // Check if this is a Vite HMR response (contains __vite__css)\r\n // Use a regex that properly handles escaped quotes within the string\r\n const viteMatch = response.match(/const __vite__css = \"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (viteMatch && viteMatch[1]) {\r\n // Unescape the CSS string\r\n return viteMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // Check for other module formats (e.g., \"export default ...\")\r\n const exportMatch = response.match(/export\\s+default\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/);\r\n if (exportMatch && exportMatch[1]) {\r\n return exportMatch[1]\r\n .replace(/\\\\r\\\\n/g, \"\\n\")\r\n .replace(/\\\\n/g, \"\\n\")\r\n .replace(/\\\\t/g, \"\\t\")\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, \"\\\\\");\r\n }\r\n\r\n // If it looks like JavaScript (not CSS), warn and return empty\r\n if (response.includes(\"import\") || response.includes(\"export\")) {\r\n logger.warn(\r\n \"CSS file returned JavaScript module format. CSS may not load correctly.\"\r\n );\r\n return \"\";\r\n }\r\n\r\n // If not a module format, assume it's plain CSS (production or direct file)\r\n return response;\r\n};\r\n\r\n/**\r\n * Extracts and processes style elements from the document\r\n * @param doc - The parsed document\r\n * @returns Concatenated CSS content\r\n */\r\nexport const extractStyles = async (doc: Document): Promise<string> => {\r\n let style = \"\";\r\n\r\n // Process styles in document order (inline styles and external stylesheets)\r\n const styleElements = doc.querySelectorAll(\"style, link[rel='stylesheet']\");\r\n\r\n for (const element of styleElements) {\r\n if (element.tagName === \"LINK\") {\r\n const linkElement = element as HTMLLinkElement;\r\n const response = await safeFetch(linkElement.href);\r\n const cssContent = extractCSSFromResponse(response);\r\n if (cssContent) {\r\n style += \"\\n\" + cssContent;\r\n }\r\n } else if (element.tagName === \"STYLE\") {\r\n const styleEl = element as HTMLStyleElement;\r\n if (styleEl.textContent) {\r\n let css = styleEl.textContent.trim();\r\n // strip CSS comments\r\n css = css.replace(REGEX_PATTERNS.comments.css, \"\").trim();\r\n style += \"\\n\" + css;\r\n }\r\n }\r\n element.remove();\r\n }\r\n\r\n return style.trim();\r\n};\r\n","import { LadrillosComponent } from \"../types/LadrilloTypes\";\r\nimport { logger } from \"../utils/logger\";\r\nimport { fetchComponentSource } from \"./componentSource\";\r\nimport { parseComponent } from \"./componentParser\";\r\n\r\nclass Ladrillos {\r\n // properties\r\n components: Record<string, LadrillosComponent>;\r\n\r\n constructor() {\r\n // Initialize the Ladrillos instance\r\n this.components = {};\r\n }\r\n\r\n async registerComponent(\r\n name: string,\r\n path: string,\r\n useShadowDOM: boolean = true\r\n ): Promise<void> {\r\n if (this.components[name]) {\r\n logger.warn(`Component with name \"${name}\" is already registered.`);\r\n return;\r\n }\r\n\r\n try {\r\n const source = await fetchComponentSource(path);\r\n const component = await parseComponent(source!, name);\r\n\r\n this.components[name] = {\r\n tagName: name,\r\n template: component.template,\r\n scripts: component.scripts,\r\n externalScripts: component.externalScripts,\r\n styles: component.styles,\r\n sourcePath: path,\r\n };\r\n\r\n // Define the web component\r\n logger.log(`Component ${name} registered successfully`);\r\n await this.#defineWebComponent(name, useShadowDOM);\r\n } catch (error) {\r\n logger.error(\r\n `Failed to register component \"${name}\": ${(error as Error).message}`\r\n );\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * Defines the web component using the webcomponent module\r\n * @param name - Component name\r\n * @param useShadowDOM - Whether to use Shadow DOM\r\n */\r\n async #defineWebComponent(\r\n name: string,\r\n useShadowDOM: boolean\r\n ): Promise<void> {\r\n const { defineWebComponent } = await import(\"./webcomponent\");\r\n\r\n // safety check\r\n if (this.components[name]) {\r\n defineWebComponent(this.components[name], useShadowDOM);\r\n }\r\n }\r\n}\r\n\r\nexport const ladrillos = new Ladrillos();\r\n","/**\r\n * Global Event Bus for component-to-component communication\r\n * Allows components to emit events and listen to events from other components\r\n */\r\n\r\ntype EventCallback = (data?: any) => void | Promise<void>;\r\ntype EventListeners = Map<string, Set<EventCallback>>;\r\n\r\nclass EventBus {\r\n private listeners: EventListeners = new Map();\r\n\r\n /**\r\n * Emit an event with optional data\r\n * @param eventName - The name of the event to emit\r\n * @param data - Optional data to pass to listeners\r\n * @returns Promise that resolves when all listeners have been called\r\n */\r\n emit(eventName: string, data?: any): Promise<void> {\r\n // Also dispatch as a native DOM CustomEvent so document.addEventListener works\r\n const customEvent = new CustomEvent(eventName, {\r\n detail: data,\r\n bubbles: true,\r\n composed: true,\r\n });\r\n document.dispatchEvent(customEvent);\r\n\r\n const callbacks = this.listeners.get(eventName);\r\n\r\n if (!callbacks || callbacks.size === 0) {\r\n // No listeners, resolve immediately\r\n return Promise.resolve();\r\n }\r\n\r\n // Execute all callbacks and collect promises\r\n const promises: Promise<void>[] = [];\r\n\r\n callbacks.forEach((callback) => {\r\n try {\r\n const result = callback(data);\r\n // If callback returns a promise, add it to promises array\r\n if (result instanceof Promise) {\r\n promises.push(result);\r\n }\r\n } catch (error) {\r\n console.error(`Error in event listener for \"${eventName}\":`, error);\r\n promises.push(Promise.reject(error));\r\n }\r\n });\r\n\r\n // If any callbacks returned promises, wait for all of them\r\n if (promises.length > 0) {\r\n return Promise.all(promises).then(() => undefined);\r\n }\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * Listen to an event\r\n * @param eventName - The name of the event to listen for\r\n * @param callback - Function to call when event is emitted\r\n * @returns Function to remove the listener\r\n */\r\n listen(eventName: string, callback: EventCallback): () => void {\r\n if (!this.listeners.has(eventName)) {\r\n this.listeners.set(eventName, new Set());\r\n }\r\n\r\n this.listeners.get(eventName)!.add(callback);\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n this.off(eventName, callback);\r\n };\r\n }\r\n\r\n /**\r\n * Remove a specific event listener\r\n * @param eventName - The name of the event\r\n * @param callback - The callback to remove\r\n */\r\n off(eventName: string, callback: EventCallback): void {\r\n const callbacks = this.listeners.get(eventName);\r\n if (callbacks) {\r\n callbacks.delete(callback);\r\n // Clean up empty sets\r\n if (callbacks.size === 0) {\r\n this.listeners.delete(eventName);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event, or all listeners if no event specified\r\n * @param eventName - Optional event name to clear listeners for\r\n */\r\n clear(eventName?: string): void {\r\n if (eventName) {\r\n this.listeners.delete(eventName);\r\n } else {\r\n this.listeners.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Get count of listeners for an event\r\n * @param eventName - The event name\r\n * @returns Number of listeners\r\n */\r\n listenerCount(eventName: string): number {\r\n return this.listeners.get(eventName)?.size ?? 0;\r\n }\r\n}\r\n\r\n// Export singleton instance\r\nexport const eventBus = new EventBus();\r\n","import { ladrillos } from \"./core/main.js\";\r\nimport { eventBus } from \"./core/eventBus.js\";\r\n\r\ndeclare global {\r\n interface Window {\r\n ladrillosjs: {\r\n registerComponent: typeof registerComponent;\r\n registerComponents: typeof registerComponents;\r\n };\r\n $listen: typeof $listen;\r\n $emit: typeof $emit;\r\n $querySelector: typeof $querySelector;\r\n $querySelectorAll: typeof $querySelectorAll;\r\n $reactive: typeof $reactive;\r\n $setState: typeof $setState;\r\n $getState: typeof $getState;\r\n }\r\n}\r\n\r\nexport const registerComponent = (\r\n name: string,\r\n path: string,\r\n useShadowDOM?: boolean\r\n) => ladrillos.registerComponent(name, path, useShadowDOM);\r\n\r\nexport const registerComponents = async (\r\n components: Array<{ name: string; path: string; useShadowDOM?: boolean }>\r\n): Promise<void> => {\r\n await Promise.all(\r\n components.map(({ name, path, useShadowDOM }) =>\r\n ladrillos.registerComponent(name, path, useShadowDOM)\r\n )\r\n );\r\n};\r\n\r\n// Event bus helper functions\r\nexport const $listen = (event: string, callback: (data?: any) => void) => {\r\n return eventBus.listen(event, callback);\r\n};\r\n\r\nexport const $emit = (event: string, data?: any) => {\r\n eventBus.emit(event, data);\r\n};\r\n\r\n// Component context management\r\n// Maps script URLs to their component contexts for persistent association\r\nconst scriptContextMap = new Map<\r\n string,\r\n { shadowRoot?: ShadowRoot; element?: HTMLElement }\r\n>();\r\nconst activeContext: { shadowRoot?: ShadowRoot; element?: HTMLElement } | null =\r\n null;\r\n\r\n/**\r\n * Internal: Set component context for a script\r\n * Called by the framework when loading scripts from components\r\n */\r\nexport const __setComponentContext = (\r\n shadowRoot?: ShadowRoot,\r\n element?: HTMLElement\r\n) => {\r\n // Store in the global registry by component tag name\r\n if (element) {\r\n const tagName = element.tagName.toLowerCase();\r\n if (!(window as any).__ladrilloContexts) {\r\n (window as any).__ladrilloContexts = new Map();\r\n }\r\n (window as any).__ladrilloContexts.set(tagName, { shadowRoot, element });\r\n }\r\n};\r\n\r\n/**\r\n * Internal: Get component context for the current script\r\n */\r\nconst getComponentContext = () => {\r\n const registry = (window as any).__ladrilloContexts as Map<string, any>;\r\n if (registry && registry.size > 0) {\r\n // For now, return the last registered context\r\n // In the future, we could track which script belongs to which component\r\n const contexts = Array.from(registry.values());\r\n return contexts[contexts.length - 1];\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Get the component's reactive state (for use in module scripts with bind attribute)\r\n * Returns a Proxy that allows direct property access to component.state\r\n * @returns Proxy to component state or empty object if no component context\r\n */\r\nexport const $getState = (): any => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.element) {\r\n return (ctx.element as any).state || {};\r\n }\r\n return {};\r\n};\r\n\r\n/**\r\n * Set component state (for use in module scripts with bind attribute)\r\n * @param updates - Object with state updates\r\n */\r\nexport const $setState = (updates: any) => {\r\n const ctx = getComponentContext();\r\n if (ctx && ctx.setState) {\r\n ctx.setState(updates);\r\n }\r\n};\r\n\r\n/**\r\n * Creates a reactive variable that automatically updates the component when changed.\r\n * For use in ES module scripts with the bind attribute.\r\n * @param name - The variable name (must match the binding in the template)\r\n * @param initialValue - The initial value\r\n * @returns A setter function to update the value\r\n *\r\n * @example\r\n * ```javascript\r\n * import { $reactive } from 'ladrillosjs';\r\n *\r\n * // In your module script:\r\n * const setBeers = $reactive('beers', 'loading...');\r\n *\r\n * // Later, update it:\r\n * setBeers('<card>...</card>');\r\n * ```\r\n */\r\nexport const $reactive = <T = any>(\r\n name: string,\r\n initialValue: T\r\n): ((value: T) => void) => {\r\n // Initialize the state\r\n $setState({ [name]: initialValue });\r\n\r\n // Return a setter function\r\n return (value: T) => {\r\n $setState({ [name]: value });\r\n };\r\n};\r\n\r\n// DOM query helpers with smart component context detection\r\n// Automatically searches within component context when appropriate\r\nexport const $querySelector = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): Element | null => {\r\n if (root) {\r\n return root.querySelector(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelector(selector);\r\n if (result) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelector(selector);\r\n};\r\n\r\nexport const $querySelectorAll = (\r\n selector: string,\r\n root?: Element | Document | ShadowRoot\r\n): NodeListOf<Element> => {\r\n if (root) {\r\n return root.querySelectorAll(selector);\r\n }\r\n\r\n // Try to get component context\r\n const ctx = getComponentContext();\r\n if (ctx) {\r\n const searchRoot = ctx.shadowRoot || ctx.element;\r\n if (searchRoot) {\r\n const result = searchRoot.querySelectorAll(selector);\r\n if (result.length > 0) return result;\r\n }\r\n }\r\n\r\n // Fallback to document\r\n return document.querySelectorAll(selector);\r\n};\r\n\r\n// for a browser‑global via <script src=\"…ladrillosjs.js\"></script>\r\nif (typeof window !== \"undefined\") {\r\n window.ladrillosjs = {\r\n registerComponent,\r\n registerComponents,\r\n };\r\n\r\n // Expose helper functions globally for non-module scripts\r\n window.$listen = $listen;\r\n window.$emit = $emit;\r\n window.$querySelector = $querySelector;\r\n window.$querySelectorAll = $querySelectorAll;\r\n window.$reactive = $reactive;\r\n window.$setState = $setState;\r\n window.$getState = $getState;\r\n}\r\n"],"names":["isDevelopment","e","logger","message","args","cache","maxCacheSize","getCached","path","cached","setCache","content","firstKey","fetchComponentSource","__async","response","text","error","safeFetch","url","res","err","REGEX_PATTERNS","parser","parseComponent","source","name","doc","parseComponentHTML","scripts","externalScripts","extractScripts","styles","extractStyles","template","isDevServerScript","src","pattern","_a","_b","el","isExternal","extractCSSFromResponse","viteMatch","exportMatch","style","styleElements","element","cssContent","styleEl","css","_Ladrillos_instances","defineWebComponent_fn","Ladrillos","__privateAdd","useShadowDOM","component","__privateMethod","defineWebComponent","ladrillos","EventBus","eventName","data","customEvent","callbacks","promises","callback","result","eventBus","registerComponent","registerComponents","components","$listen","event","$emit","__setComponentContext","shadowRoot","tagName","getComponentContext","registry","contexts","$getState","ctx","$setState","updates","$reactive","initialValue","value","$querySelector","selector","root","searchRoot","$querySelectorAll"],"mappings":"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"}
|
package/dist/ladrillosjs.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-63mcJ9Hl.js");exports.$emit=e.$emit;exports.$getState=e.$getState;exports.$listen=e.$listen;exports.$querySelector=e.$querySelector;exports.$querySelectorAll=e.$querySelectorAll;exports.$reactive=e.$reactive;exports.$setState=e.$setState;exports.__setComponentContext=e.__setComponentContext;exports.registerComponent=e.registerComponent;exports.registerComponents=e.registerComponents;
|
|
2
2
|
//# sourceMappingURL=ladrillosjs.cjs.js.map
|
package/dist/ladrillosjs.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as s, c as a, $ as r, g as o, h as n, f as $, d as i, _ as l, r as m, a as c } from "./index-
|
|
1
|
+
import { b as s, c as a, $ as r, g as o, h as n, f as $, d as i, _ as l, r as m, a as c } from "./index-CUJmLlUh.mjs";
|
|
2
2
|
export {
|
|
3
3
|
s as $emit,
|
|
4
4
|
a as $getState,
|
package/dist/ladrillosjs.umd.js
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(h,b){typeof exports=="object"&&typeof module!="undefined"?b(exports):typeof define=="function"&&define.amd?define(["exports"],b):(h=typeof globalThis!="undefined"?globalThis:h||self,b(h.ladrillosjs={}))})(this,(function(h){"use strict";var rt=Object.defineProperty,it=Object.defineProperties;var ct=Object.getOwnPropertyDescriptors;var xe=Object.getOwnPropertySymbols;var at=Object.prototype.hasOwnProperty,lt=Object.prototype.propertyIsEnumerable;var Ce=h=>{throw TypeError(h)};var Ae=(h,b,w)=>b in h?rt(h,b,{enumerable:!0,configurable:!0,writable:!0,value:w}):h[b]=w,B=(h,b)=>{for(var w in b||(b={}))at.call(b,w)&&Ae(h,w,b[w]);if(xe)for(var w of xe(b))lt.call(b,w)&&Ae(h,w,b[w]);return h},_e=(h,b)=>it(h,ct(b));var oe=(h,b,w)=>b.has(h)||Ce("Cannot "+w);var C=(h,b,w)=>(oe(h,b,"read from private field"),w?w.call(h):b.get(h)),O=(h,b,w)=>b.has(h)?Ce("Cannot add the same private member more than once"):b instanceof WeakSet?b.add(h):b.set(h,w),q=(h,b,w,_)=>(oe(h,b,"write to private field"),_?_.call(h,w):b.set(h,w),w),W=(h,b,w)=>(oe(h,b,"access private method"),w);var L=(h,b,w)=>new Promise((_,z)=>{var G=R=>{try{H(w.next(R))}catch(j){z(j)}},Y=R=>{try{H(w.throw(R))}catch(j){z(j)}},H=R=>R.done?_(R.value):Promise.resolve(R.value).then(G,Y);H((w=w.apply(h,b)).next())});var Z,Te;const b=()=>{try{return!1}catch(t){return process.env.NODE_ENV==="development"}},w={log(t,...e){b()&&console.log(t,...e)},error(t,...e){console.error(t,...e)},warn(t,...e){b()&&console.warn(t,...e)}},_=new Map,z=25,G=t=>{const e=_.get(t);return e&&(_.delete(t),_.set(t,e)),e},Y=(t,e)=>{if(_.has(t))_.delete(t);else if(_.size>=z){const s=_.keys().next().value;s&&_.delete(s)}_.set(t,e)},H=t=>L(null,null,function*(){if(!t)throw new Error("Path cannot be null or empty");const e=G(t);if(e)return e;try{const s=yield fetch(t);if(!s.ok)throw new Error(`Failed to fetch component from ${t}: ${s.statusText}`);const n=yield s.text();return Y(t,n),n}catch(s){w.error(`Error fetching component from ${t}: ${s.message}`)}}),R=t=>L(null,null,function*(){try{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);return yield e.text()}catch(e){return w.error(`Failed to fetch resource at ${t}:`,e),""}}),j={bindings:/{([^}]+)}/g,comments:{js:/\/\*[\s\S]*?\*\/|\/\/.*$/gm,css:/\/\*[\s\S]*?\*\//g,html:/<!--[\s\S]*?-->/g}},Ne=new DOMParser,Oe=(t,e)=>L(null,null,function*(){const s=Re(t),{scripts:n,externalScripts:o}=Fe(s),r=yield Me(s),i=s.body.innerHTML.trim();return{tagName:e,template:i,scripts:n,externalScripts:o,styles:r}}),Re=t=>Ne.parseFromString(t.replace(j.comments.html,""),"text/html"),je=t=>["/@vite/","/__vite","/webpack-dev-server","/hot-update","/__webpack_hmr","/browser-sync/","/livereload.js"].some(s=>t.includes(s)),Fe=t=>{var n,o;const e=[],s=[];for(const r of t.querySelectorAll("script")){if(r.src){if(je(r.src)){r.remove();continue}const i=r.hasAttribute("external");s.push({src:r.getAttribute("src")||r.src,type:(n=r.type)!=null?n:null,external:i})}else if(r.textContent){let i=r.textContent.trim();i=i.replace(j.comments.js,"").trim(),e.push({content:i,type:(o=r.type)!=null?o:null})}r.remove()}return{scripts:e,externalScripts:s}},Be=t=>{const e=t.match(/const __vite__css = "((?:[^"\\]|\\.)*)"/);if(e&&e[1])return e[1].replace(/\\r\\n/g,`
|
|
2
2
|
`).replace(/\\n/g,`
|
|
3
|
-
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const
|
|
3
|
+
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const s=t.match(/export\s+default\s+"((?:[^"\\]|\\.)*)"/);return s&&s[1]?s[1].replace(/\\r\\n/g,`
|
|
4
4
|
`).replace(/\\n/g,`
|
|
5
|
-
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):t.includes("import")||t.includes("export")?(
|
|
6
|
-
`+i)}else if(
|
|
7
|
-
`+
|
|
5
|
+
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):t.includes("import")||t.includes("export")?(w.warn("CSS file returned JavaScript module format. CSS may not load correctly."),""):t},Me=t=>L(null,null,function*(){let e="";const s=t.querySelectorAll("style, link[rel='stylesheet']");for(const n of s){if(n.tagName==="LINK"){const r=yield R(n.href),i=Be(r);i&&(e+=`
|
|
6
|
+
`+i)}else if(n.tagName==="STYLE"){const o=n;if(o.textContent){let r=o.textContent.trim();r=r.replace(j.comments.css,"").trim(),e+=`
|
|
7
|
+
`+r}}n.remove()}return e.trim()});class Ve{constructor(){O(this,Z);this.components={}}registerComponent(e,s,n=!0){return L(this,null,function*(){if(this.components[e]){w.warn(`Component with name "${e}" is already registered.`);return}try{const o=yield H(s),r=yield Oe(o,e);this.components[e]={tagName:e,template:r.template,scripts:r.scripts,externalScripts:r.externalScripts,styles:r.styles,sourcePath:s},w.log(`Component ${e} registered successfully`),yield W(this,Z,Te).call(this,e,n)}catch(o){w.error(`Failed to register component "${e}": ${o.message}`);return}})}}Z=new WeakSet,Te=function(e,s){return L(this,null,function*(){const{defineWebComponent:n}=yield Promise.resolve().then(()=>ot);this.components[e]&&n(this.components[e],s)})};const ie=new Ve;class Pe{constructor(){this.listeners=new Map}emit(e,s){const n=new CustomEvent(e,{detail:s,bubbles:!0,composed:!0});document.dispatchEvent(n);const o=this.listeners.get(e);if(!o||o.size===0)return Promise.resolve();const r=[];return o.forEach(i=>{try{const c=i(s);c instanceof Promise&&r.push(c)}catch(c){console.error(`Error in event listener for "${e}":`,c),r.push(Promise.reject(c))}}),r.length>0?Promise.all(r).then(()=>{}):Promise.resolve()}listen(e,s){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(s),()=>{this.off(e,s)}}off(e,s){const n=this.listeners.get(e);n&&(n.delete(s),n.size===0&&this.listeners.delete(e))}clear(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var s,n;return(n=(s=this.listeners.get(e))==null?void 0:s.size)!=null?n:0}}const Q=new Pe,ce=(t,e,s)=>ie.registerComponent(t,e,s),ae=t=>L(null,null,function*(){yield Promise.all(t.map(({name:e,path:s,useShadowDOM:n})=>ie.registerComponent(e,s,n)))}),le=(t,e)=>Q.listen(t,e),ue=(t,e)=>{Q.emit(t,e)},qe=(t,e)=>{if(e){const s=e.tagName.toLowerCase();window.__ladrilloContexts||(window.__ladrilloContexts=new Map),window.__ladrilloContexts.set(s,{shadowRoot:t,element:e})}},I=()=>{const t=window.__ladrilloContexts;if(t&&t.size>0){const e=Array.from(t.values());return e[e.length-1]}return null},de=()=>{const t=I();return t&&t.element?t.element.state||{}:{}},U=t=>{const e=I();e&&e.setState&&e.setState(t)},fe=(t,e)=>(U({[t]:e}),s=>{U({[t]:s})}),he=(t,e)=>{if(e)return e.querySelector(t);const s=I();if(s){const n=s.shadowRoot||s.element;if(n){const o=n.querySelector(t);if(o)return o}}return document.querySelector(t)},pe=(t,e)=>{if(e)return e.querySelectorAll(t);const s=I();if(s){const n=s.shadowRoot||s.element;if(n){const o=n.querySelectorAll(t);if(o.length>0)return o}}return document.querySelectorAll(t)};typeof window!="undefined"&&(window.ladrillosjs={registerComponent:ce,registerComponents:ae},window.$listen=le,window.$emit=ue,window.$querySelector=he,window.$querySelectorAll=pe,window.$reactive=fe,window.$setState=U,window.$getState=de);const We=(t,e,s)=>{if(!e)return;const n=document.createElement("style");n.textContent=e,s?t.appendChild(n):document.head.appendChild(n)},He=(t,e)=>{t.innerHTML=e;const s=ze(t),n=Ie(t),o=Ue(t),r=Ze(t);return{bindings:s,twoWayBindings:n,conditionals:o,loops:r}},me=t=>{const e=[],s=t.match(/\((.*)\)/);if(!s)return e;const n=s[1].trim();return n&&n.split(",").map(r=>r.trim()).forEach(r=>{if(/^['"]/.test(r)||/^\d+/.test(r))return;const i=r.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)/);i&&e.push(i[1])}),e},ze=t=>{const e=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,null),s=[];let n;const o=i=>{let c=i.parentElement;for(;c;){if(c.hasAttribute&&c.hasAttribute("$for"))return!0;c=c.parentElement}return!1};for(;n=e.nextNode();){if(o(n))continue;const i=[...n.textContent.matchAll(j.bindings)];if(i.length>0){const c=n.textContent,g=i.map(l=>{const a=l[1].trim(),u=a.includes("(")&&a.includes(")"),p=/[+*/%<>=!&|]/.test(a)||/\s-\s/.test(a)||/\.(?![\s}])[a-zA-Z_$][\w]*\(/.test(a)||/\bnew\s+/.test(a)||/\b(typeof|instanceof|void|delete)\b/.test(a),x=u?[a.split("(")[0].trim()]:a.split(".").map(v=>v.trim()),m=u?me(a):[];return{raw:a,path:x,isFunction:u,isExpression:p,functionArgs:m}});s.push({node:n,bindings:g,original:c})}}return t.querySelectorAll("*").forEach(i=>{if(!(i.hasAttribute("$for")||o(i)))for(const c of i.attributes){if(c.name==="$if"||c.name==="$else-if"||c.name==="$else"||c.name==="$bind")continue;const g=[...c.value.matchAll(j.bindings)];if(g.length>0){const l=c.value,a=g.map(u=>{const d=u[1].trim(),p=d.includes("(")&&d.includes(")"),m=/[+*/%<>=!&|]/.test(d)||/\s-\s/.test(d)||/\.(?![\s}])[a-zA-Z_$][\w]*\(/.test(d)||/\bnew\s+/.test(d)||/\b(typeof|instanceof|void|delete)\b/.test(d),v=p?[d.split("(")[0].trim()]:d.split(".").map(ne=>ne.trim()),T=p?me(d):[];return{raw:d,path:v,isFunction:p,isExpression:m,functionArgs:T}});s.push({node:i,bindings:a,original:l,isAttribute:!0,attributeName:c.name})}}}),s},Ie=t=>{const e=[];return t.querySelectorAll("[\\$bind]").forEach(n=>{var c;const o=n.getAttribute("$bind");if(!o)return;const r=o.trim(),i=r.split(".").map(g=>g.trim());n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement?(e.push({element:n,path:i,raw:r,isContentEditable:!1,initialValue:n.value||""}),n.removeAttribute("$bind")):n instanceof HTMLElement&&n.hasAttribute("contenteditable")&&(e.push({element:n,path:i,raw:r,isContentEditable:!0,initialValue:((c=n.textContent)==null?void 0:c.trim())||""}),n.removeAttribute("$bind"))}),e},Ue=t=>{const e=[],s=new Set;return t.querySelectorAll("[\\$if]").forEach(o=>{if(s.has(o))return;const r=[];let i=o;for(;i;){const c=i.hasAttribute("$if"),g=i.hasAttribute("$else-if"),l=i.hasAttribute("$else");if(!c&&!g&&!l)break;s.add(i);let a,u="";c?(a="if",u=i.getAttribute("$if")||"",i.removeAttribute("$if")):g?(a="else-if",u=i.getAttribute("$else-if")||"",i.removeAttribute("$else-if")):(a="else",i.removeAttribute("$else"));const d=document.createComment(`conditional:${a}:${u}`),p=i.parentElement||t,x=i.nextSibling;p.insertBefore(d,i);const m={element:i,condition:u.trim(),type:a,placeholder:d,group:[],originalParent:p,nextSibling:x};r.push(m);const v=i.nextElementSibling;if(i.remove(),i=v,v&&!v.hasAttribute("$else-if")&&!v.hasAttribute("$else"))break}r.forEach(c=>{c.group=r}),e.push(r)}),e},De=t=>{const e=new Set;return t.forEach(s=>{s.forEach(n=>{let o=n.condition;o=o.replace(/\{([^}]+)\}/g,"$1");const r=/\b([a-zA-Z_$][a-zA-Z0-9_$]*(?:\.[a-zA-Z_$][a-zA-Z0-9_$]*)*)\b/g,i=new Set(["true","false","null","undefined","typeof","instanceof","new","return","if","else","for","while","do","switch","case","break","continue"]);let c;for(;(c=r.exec(o))!==null;){const l=c[1].split(".")[0];i.has(l)||e.add(l)}})}),e},Ze=t=>{const e=[];return t.querySelectorAll("[\\$for]").forEach(n=>{var p;const o=n.getAttribute("$for");if(!o)return;const r=n.getAttribute("$key")||void 0,i=o.match(/^\s*(?:\(([^,]+),\s*([^)]+)\)|([^\s]+))\s+(?:in|of)\s+(.+)\s*$/);if(!i){console.error(`Invalid $for expression: "${o}"`);return}const c=(i[1]||i[3]).trim(),g=(p=i[2])==null?void 0:p.trim(),l=i[4].trim(),a=document.createComment(`loop:${o}`),u=n.parentElement||t;u.insertBefore(a,n),n.removeAttribute("$for"),r&&n.removeAttribute("$key"),n.remove();const d={template:n,expression:o,itemName:c,indexName:g,arrayName:l,keyAttribute:r,placeholder:a,renderedElements:[],originalParent:u};e.push(d)}),e},Xe=t=>{const e=new Set;return t.forEach(s=>{const n=s.arrayName.split(".")[0];e.add(n)}),e},M=new Map,Je=100,ee=t=>{const e=M.get(t);if(e)return M.delete(t),M.set(t,e),e;const s=new Function("component",`
|
|
8
|
+
const { Date, Array, Math, String, Number, Boolean, Object, JSON, RegExp } = globalThis;
|
|
9
|
+
with(component) {
|
|
10
|
+
return ${t};
|
|
11
|
+
}
|
|
12
|
+
`);if(M.size>=Je){const n=M.keys().next().value;n&&M.delete(n)}return M.set(t,s),s},D=(t,e)=>e.reduce((s,n)=>{if(!(s==null||typeof s!="object"))return s[n]},t),te=(t,e,s)=>{if(e.length===0)return;const n=e[e.length-1],o=e.slice(0,-1);let r=t;for(const i of o)(r[i]===void 0||r[i]===null)&&(r[i]={}),r=r[i];r[n]=s},ge=(t,e,s)=>{for(const n of t){let o=n.original;for(const{raw:r,path:i,isFunction:c,isExpression:g}of n.bindings){let l;if(g||c)try{const u=ee(r),d=typeof e=="object"&&e!==null?B(B({},e),s||{}):s||{};l=u(d)}catch(u){console.error(`Error executing expression binding {${r}}:`,u),l=void 0}else l=D(e,i);if(l===void 0)continue;const a=String(l!=null?l:"");o=o.replace(`{${r}}`,a)}if(n.node.nodeType===Node.TEXT_NODE){const r=n.node,i=r.parentElement,c=o.trim().startsWith("<")&&o.includes(">");i&&c?i.innerHTML=o:r.textContent=o}else{const r=n.node;n.isAttribute&&n.attributeName&&r.setAttribute(n.attributeName,o)}}},Ke=(t,e,s)=>{if(!t)return!0;let n=t.trim();n=n.replace(/\{([^}]+)\}/g,"$1");try{return new Function("context","component",`
|
|
8
13
|
with (context) {
|
|
9
14
|
try {
|
|
10
|
-
return Boolean(${
|
|
15
|
+
return Boolean(${n});
|
|
11
16
|
} catch (e) {
|
|
12
17
|
return false;
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
|
-
`)(e,
|
|
20
|
+
`)(e,s)}catch(o){return console.error(`Error evaluating condition "${t}":`,o),!1}},be=(t,e)=>{const s=["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","keydown","keyup","keypress","focus","blur","change","input","submit","reset","scroll","resize","load","unload","touchstart","touchend","touchmove","touchcancel","dragstart","drag","dragend","dragenter","dragover","dragleave","drop"];[t,...t.querySelectorAll("*")].forEach(o=>{s.forEach(r=>{const i=`on${r}`,c=o.getAttribute(i);if(c){const g=`__processed_${i}`;if(o[g])return;o.removeAttribute(i),o.addEventListener(r,function(l){try{new Function("event","component",`
|
|
21
|
+
with(component) {
|
|
22
|
+
${c}
|
|
23
|
+
}
|
|
24
|
+
`).call(this,l,e)}catch(a){console.error(`Error executing ${r} handler:`,a,c)}}),o[g]=!0}})})},we=(t,e,s)=>{var n;for(const o of t){let r=!1;for(const i of o){const{element:c,condition:g,type:l,placeholder:a,originalParent:u}=i;let d=!1;l==="else"?d=!r:r||(d=Ke(g,e,s),d&&(r=!0));const p=c.parentNode!==null;d&&!p?((n=a.parentNode)==null||n.insertBefore(c,a.nextSibling),s&&be(c,s)):!d&&p&&c.remove()}}},ye=(t,e,s)=>{for(const n of t){const{template:o,itemName:r,indexName:i,arrayName:c,placeholder:g,renderedElements:l}=n,a=D(e,c.split("."));if(a!==void 0&&!Array.isArray(a)){console.warn(`$for: "${c}" is not an array, got:`,a),l.forEach(u=>u.remove()),l.length=0;return}if(!a)return;l.forEach(u=>u.remove()),l.length=0,a.forEach((u,d)=>{var v;const p=o.cloneNode(!0),x=_e(B({},e),{[r]:u});i&&(x[i]=d),Ge(p,x,s);const m=l.length>0?l[l.length-1]:g;(v=m.parentNode)==null||v.insertBefore(p,m.nextSibling),l.push(p),s&&be(p,s)})}},Ge=(t,e,s)=>{const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,null);let o;for(;o=n.nextNode();)if(o.textContent&&o.textContent.includes("{")){let i=o.textContent;[...o.textContent.matchAll(/\{([^}]+)\}/g)].forEach(g=>{const l=g[1].trim(),a=l.includes("(")&&l.includes(")"),d=/[+*/%<>=!&|]/.test(l)||/\s-\s/.test(l)||/\.(?![\s}])[a-zA-Z_$][\w]*\(/.test(l)||/\bnew\s+/.test(l)||/\b(typeof|instanceof|void|delete)\b/.test(l);let p;if(d||a)try{const x=ee(l),m=typeof e=="object"&&e!==null?B(B({},e),s||{}):s||{};p=x(m)}catch(x){console.error(`Error executing expression in loop {${l}}:`,x),p=void 0}else{const x=l.split(".").map(m=>m.trim());p=D(e,x)}p!==void 0&&(i=i.replace(`{${l}}`,String(p!=null?p:"")))}),o.textContent=i}[t,...t.querySelectorAll("*")].forEach(i=>{Array.from(i.attributes).forEach(c=>{if(c.value.includes("{")){let g=c.value;[...c.value.matchAll(/\{([^}]+)\}/g)].forEach(a=>{const u=a[1].trim(),d=u.includes("(")&&u.includes(")"),x=/[+*/%<>=!&|]/.test(u)||/\s-\s/.test(u)||/\.(?![\s}])[a-zA-Z_$][\w]*\(/.test(u)||/\bnew\s+/.test(u)||/\b(typeof|instanceof|void|delete)\b/.test(u);let m;if(x||d)try{const v=ee(u),T=typeof e=="object"&&e!==null?B(B({},e),s||{}):s||{};m=v(T)}catch(v){console.error(`Error executing expression in loop attribute {${u}}:`,v),m=void 0}else{const v=u.split(".").map(T=>T.trim());m=D(e,v)}m!==void 0&&(g=g.replace(`{${u}}`,String(m!=null?m:"")))}),i.setAttribute(c.name,g)}})})},$e=t=>t instanceof ShadowRoot?t.host:t,Ye=(t,e)=>{const s=new Set;e.forEach(({path:o})=>{const r=o[0];s.add(r)});const n=[];return s.forEach(o=>{n.push(`
|
|
16
25
|
if (!Object.getOwnPropertyDescriptor(component, '${o}')) {
|
|
17
26
|
Object.defineProperty(component, '${o}', {
|
|
18
27
|
get() { return this.state.${o}; },
|
|
@@ -21,10 +30,10 @@
|
|
|
21
30
|
configurable: true
|
|
22
31
|
});
|
|
23
32
|
}
|
|
24
|
-
`)}),{injectedCode:"",componentInjections:
|
|
25
|
-
`),bindVarNames:
|
|
26
|
-
`),{stateBindings:
|
|
27
|
-
`),
|
|
33
|
+
`)}),{injectedCode:"",componentInjections:n.join(`
|
|
34
|
+
`),bindVarNames:s}},Qe=(t,e,s=new Set)=>{const n=[],o=new Set;e.forEach(c=>{c.bindings.forEach(g=>{const l=g.path[0];o.add(l),g.isFunction&&g.functionArgs&&g.functionArgs.forEach(a=>{o.add(a)})})}),s.forEach(c=>{o.add(c)});const r=/(?:const|let|var)\s+(\w+)\s*=\s*([^;]+);?/g;let i;for(;(i=r.exec(t))!==null;){const c=i[1];o.has(c)&&n.push(`component.state.${c} = ${c};`)}return{stateBindings:n,boundVarNames:o}},et=(t,e)=>{if(e.size===0)return t;let s=t;return e.forEach(n=>{const o=new RegExp(`\\b${n}\\.(\\w+(?:\\.\\w+)*)\\s*([=+\\-*/%&|^]|\\+\\+|\\-\\-)`,"g");s=s.replace(o,`component.state.${n}.$1 $2`);const r=new RegExp(`(?<!component\\.state\\.)(?<!const\\s${n}\\s*=\\s*{[^}]*)\\b${n}\\.(\\w+(?:\\.\\w+)*)(?![=+\\-*/%&|^]|\\+\\+|\\-\\-)`,"g");s=s.replace(r,`component.state.${n}.$1`);const i=new RegExp(`(?<!\\.)\\b(\\+\\+|\\-\\-)${n}\\b|\\b${n}(\\+\\+|\\-\\-)`,"g");s=s.replace(i,l=>{if(l.startsWith("++")||l.startsWith("--"))return`${l.substring(0,2)}component.state.${n}`;{const a=l.substring(l.length-2);return`component.state.${n}${a}`}});const c=new RegExp(`(?<!\\.)\\b${n}\\s*(\\+=|\\-=|\\*=|\\/=|%=|\\*\\*=|<<=|>>=|>>>=|&=|\\|=|\\^=)`,"g");s=s.replace(c,`component.state.${n}$1`);const g=new RegExp(`(?<!const\\s)(?<!let\\s)(?<!var\\s)(?<!\\.)\\b${n}\\s*=\\s*([^=])`,"g");s=s.replace(g,`component.state.${n} = $1`)}),s},Ee=(t,e,s,n,o,r=new Set)=>{try{const{injectedCode:i,componentInjections:c,bindVarNames:g}=Ye(t,s),l=/function\s+(\w+)|const\s+(\w+)\s*=\s*(?:\([^)]*\)|[\w\s]*)\s*=>/g,a=[];let u;for(;(u=l.exec(t))!==null;){const k=u[1]||u[2];k&&a.push(k)}const d=a.map(k=>`component.${k} = typeof ${k} !== 'undefined' ? ${k}.bind(component) : undefined;`).join(`
|
|
35
|
+
`),{stateBindings:p,boundVarNames:x}=Qe(t,e,r),m=new Set([...x,...g]),v=p.join(`
|
|
36
|
+
`),T=et(t,m),ne=`
|
|
28
37
|
(function() {
|
|
29
38
|
// Create component scope with direct access to state
|
|
30
39
|
const component = this;
|
|
@@ -59,18 +68,18 @@
|
|
|
59
68
|
|
|
60
69
|
// Execute script content within component scope so $bind variables are accessible
|
|
61
70
|
with(component) {
|
|
62
|
-
${
|
|
71
|
+
${T}
|
|
63
72
|
|
|
64
73
|
// Auto-bind variables to component state (e.g., const name = "value" → this.state.name = "value")
|
|
65
|
-
${
|
|
74
|
+
${v}
|
|
66
75
|
|
|
67
76
|
// Auto-attach all detected functions to component for onclick access
|
|
68
|
-
${
|
|
77
|
+
${d}
|
|
69
78
|
}
|
|
70
79
|
}).call(arguments[0], arguments[0], arguments[1], arguments[2])
|
|
71
|
-
`;new Function(
|
|
80
|
+
`;new Function(ne)(o,n,Q)}catch(i){console.error("Script execution failed:",i)}},ve=(t,e)=>{["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","keydown","keyup","keypress","focus","blur","change","input","submit","reset","scroll","resize","load","unload","touchstart","touchend","touchmove","touchcancel","dragstart","drag","dragend","dragenter","dragover","dragleave","drop"].forEach(n=>{const o=`on${n}`;(t instanceof ShadowRoot?t.querySelectorAll(`[${o}]`):e.querySelectorAll(`[${o}]`)).forEach(i=>{const c=`${o}`;if(i[`__processed_${c}`])return;const g=i.getAttribute(o);g&&(i.removeAttribute(o),i.addEventListener(n,function(l){new Function("event","component",`
|
|
72
81
|
with(component) {
|
|
73
|
-
${
|
|
82
|
+
${g}
|
|
74
83
|
}
|
|
75
|
-
`).call(this,
|
|
84
|
+
`).call(this,l,e)}),i[`__processed_${c}`]=!0)})})},tt=(r,i,c,...g)=>L(null,[r,i,c,...g],function*(t,e,s,n=[],o=new Set){if(!(e!=null&&e.length))return;const l=$e(t);for(const a of e)a.content&&Ee(a.content,s,n,t,l,o);ve(t,l)}),nt=(t,e)=>new Promise((s,n)=>{const o=document.querySelector(`script[src="${t}"]`);if(o){if(o.dataset.loaded==="true"){s();return}o.addEventListener("load",()=>s(),{once:!0}),o.addEventListener("error",()=>n(new Error(`Failed to load external script: ${t}`)),{once:!0});return}const r=document.createElement("script");r.src=t,e&&(r.type=e),r.onload=()=>{r.dataset.loaded="true",s()},r.onerror=()=>n(new Error(`Failed to load external script: ${t}`)),document.head.appendChild(r)}),st=(i,c,g,...l)=>L(null,[i,c,g,...l],function*(t,e,s,n=[],o=new Set,r){var u;const a=$e(t);for(const d of e){let p;r?r.startsWith("http://")||r.startsWith("https://")?p=r:p=new URL(r,window.location.href).href:p=window.location.href;const x=new URL(d.src,p).href;if(d.external)yield nt(x,d.type);else if(d.type==="module"){const m=a.tagName.toLowerCase();window.__ladrilloContexts||(window.__ladrilloContexts=new Map),window.__ladrilloContexts.set(m,{host:t,shadowRoot:t instanceof ShadowRoot?t:null,element:a,state:a.state,setState:(u=a.setState)==null?void 0:u.bind(a)});const v=document.createElement("script");v.type="module",v.src=x,v.setAttribute("data-component",m),document.head.appendChild(v)}else yield fetch(x).then(m=>{if(!m.ok)throw new Error(`HTTP ${m.status}: ${m.statusText}`);const v=m.headers.get("content-type");if(v&&!v.includes("javascript")&&!v.includes("text/plain"))throw new Error(`Expected JavaScript but got ${v}`);return m.text()}).then(m=>{Ee(m,s,n,t,a,o)}).catch(m=>{console.error(`Failed to load external script: ${d.src}`,m)})}ve(t,a)}),ot=Object.freeze(Object.defineProperty({__proto__:null,defineWebComponent:(t,e)=>{var l,a,u,d,p,x,m,re,T,ke,Le;const{tagName:s,template:n,scripts:o,externalScripts:r,styles:i,sourcePath:c}=t,k=class k extends HTMLElement{constructor(){super();O(this,m);O(this,l,[]);O(this,a,[]);O(this,u,[]);O(this,d,[]);O(this,p,[]);O(this,x,c);e&&this.attachShadow({mode:"open"});const f={},$=()=>{ge(C(this,l),this.state,this),we(C(this,u),this.state,this),ye(C(this,d),this.state,this),W(this,m,Le).call(this)};this.state=new Proxy(f,{get:(S,y)=>S[y],set:(S,y,E)=>{const N=S[y];return Object.is(N,E)||(E!==null&&typeof E=="object"?S[y]=W(this,m,re).call(this,E,$):S[y]=E,Object.getOwnPropertyDescriptor(this,y)||Object.defineProperty(this,y,{get(){return this.state[y]},set(V){this.state[y]=V},enumerable:!0,configurable:!0}),$()),!0}})}setState(f){Object.assign(this.state,f)}connectedCallback(){return L(this,null,function*(){const f=e?this.shadowRoot:this,{bindings:$,twoWayBindings:S,conditionals:y,loops:E}=He(f,n);q(this,l,$),q(this,a,S),q(this,u,y),q(this,d,E);const N=De(y),V=Xe(E);We(f,i,e),this._initializeStateFromAttributes(),this._setupTwoWayBindings(),yield st(f,r,C(this,l),C(this,a),new Set([...N,...V]),C(this,x)),yield tt(f,o,C(this,l),C(this,a),new Set([...N,...V])),ge(C(this,l),this.state,this),we(C(this,u),this.state,this),ye(C(this,d),this.state,this),this._setupAttributeObserver()})}disconnectedCallback(){this.__attributeObserver&&(this.__attributeObserver.disconnect(),this.__attributeObserver=null),C(this,p).forEach($=>{try{$()}catch(S){console.error("Error cleaning up two-way binding:",S)}}),q(this,p,[]);const f=this.__eventUnsubscribers;f&&Array.isArray(f)&&(f.forEach($=>{try{$()}catch(S){console.error("Error unsubscribing from event:",S)}}),this.__eventUnsubscribers=[])}_setupAttributeObserver(){const f=new MutationObserver($=>{$.forEach(S=>{if(S.type==="attributes"&&S.attributeName){const y=this.getAttribute(S.attributeName);this._handleAttributeChange(S.attributeName,y)}})});f.observe(this,{attributes:!0,attributeOldValue:!0}),this.__attributeObserver=f}_initializeStateFromAttributes(){this.getAttributeNames().forEach(f=>{const $=this.getAttribute(f);this._handleAttributeChange(f,$)})}_handleAttributeChange(f,$){var y;if(f){const E="this.state.";f.startsWith(E)&&(f=f.slice(E.length))}const S=W(y=k,T,ke).call(y,$);this.state[f]=S}_setupTwoWayBindings(){C(this,a).forEach(({element:f,path:$,raw:S,isContentEditable:y,initialValue:E})=>{var V,Se;if(this._getNestedValue($)===void 0){const A=E||"";te(this.state,$,A)}if(y){const A=f;A.textContent=(V=this._getNestedValue($))!=null?V:"";const X=se=>{const F=se.target.textContent||"";te(this.state,$,F)};A.addEventListener("input",X);const P=()=>{A.removeEventListener("input",X)};C(this,p).push(P)}else{const A=f,X=A instanceof HTMLInputElement&&A.type==="checkbox";A instanceof HTMLInputElement&&A.type,X?A.checked=!!this._getNestedValue($):A.value=(Se=this._getNestedValue($))!=null?Se:"";const P=J=>{const F=J.target;let K;F instanceof HTMLInputElement&&F.type==="checkbox"?K=F.checked:(F instanceof HTMLInputElement&&F.type,K=F.value),te(this.state,$,K)};A.addEventListener("input",P);const se=()=>{A.removeEventListener("input",P)};if(C(this,p).push(se),A instanceof HTMLSelectElement||A instanceof HTMLInputElement&&["checkbox","radio","file"].includes(A.type)){A.addEventListener("change",P);const J=()=>{A.removeEventListener("change",P)};C(this,p).push(J)}}})}_getNestedValue(f){return f.reduce(($,S)=>$==null?void 0:$[S],this.state)}};l=new WeakMap,a=new WeakMap,u=new WeakMap,d=new WeakMap,p=new WeakMap,x=new WeakMap,m=new WeakSet,re=function(f,$){return f===null||typeof f!="object"||f instanceof HTMLElement||f instanceof Node?f:new Proxy(f,{get:(S,y)=>{const E=S[y];return E!==null&&typeof E=="object"?W(this,m,re).call(this,E,$):E},set:(S,y,E)=>{const N=S[y];return Object.is(N,E)||(S[y]=E,$()),!0}})},T=new WeakSet,ke=function(f){if(f===null||f==="")return null;if(f!=="undefined")try{return JSON.parse(f)}catch($){return f}},Le=function(){C(this,a).forEach(({element:f,path:$,isContentEditable:S})=>{const y=this._getNestedValue($);if(S){const E=f;E.textContent!==y&&(E.textContent=y!=null?y:"")}else{const E=f;if(E instanceof HTMLInputElement&&E.type==="checkbox"){const N=!!y;E.checked!==N&&(E.checked=N)}else E.value!==y&&(E.value=y!=null?y:"")}})},O(k,T);let g=k;customElements.define(s,g),w.log(`Web component defined: <${s}></${s}>`)}},Symbol.toStringTag,{value:"Module"}));h.$emit=ue,h.$getState=de,h.$listen=le,h.$querySelector=he,h.$querySelectorAll=pe,h.$reactive=fe,h.$setState=U,h.__setComponentContext=qe,h.registerComponent=ce,h.registerComponents=ae,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
|
76
85
|
//# sourceMappingURL=ladrillosjs.umd.js.map
|