alpine-rc 0.1.1 → 0.1.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 CHANGED
@@ -35,8 +35,14 @@ A component is an `.html` file with a `<template>` wrapper:
35
35
  <!-- components/card.html -->
36
36
  <template>
37
37
  <style scoped>
38
- .card { border: 1px solid #ddd; padding: 16px; border-radius: 8px; }
39
- .card h2 { margin: 0; }
38
+ .card {
39
+ border: 1px solid #ddd;
40
+ padding: 16px;
41
+ border-radius: 8px;
42
+ }
43
+ .card h2 {
44
+ margin: 0;
45
+ }
40
46
  </style>
41
47
 
42
48
  <div class="card">
@@ -85,8 +91,7 @@ Pass data to the component via `:attr` or `x-bind:attr` bindings on the host ele
85
91
  :title="post.title"
86
92
  :count="post.likes"
87
93
  :active="selectedId === post.id"
88
- >
89
- </div>
94
+ ></div>
90
95
  ```
91
96
 
92
97
  Inside the component template, props are available directly:
@@ -169,7 +174,9 @@ No configuration needed. Tailwind, CSS, SCSS, and any `<link>` stylesheets apply
169
174
  <template>
170
175
  <style>
171
176
  /* Injected into <head> once — global scope */
172
- .card { padding: 16px; }
177
+ .card {
178
+ padding: 16px;
179
+ }
173
180
  </style>
174
181
  <div class="card"></div>
175
182
  </template>
@@ -188,12 +195,16 @@ No configuration needed. Tailwind, CSS, SCSS, and any `<link>` stylesheets apply
188
195
  <template>
189
196
  <style scoped>
190
197
  /* Scoped: only applies inside this component */
191
- .card { padding: 16px; }
198
+ .card {
199
+ padding: 16px;
200
+ }
192
201
  </style>
193
202
 
194
203
  <style>
195
204
  /* Still global — injected to <head> as-is */
196
- .badge { border-radius: 99px; }
205
+ .badge {
206
+ border-radius: 99px;
207
+ }
197
208
  </style>
198
209
 
199
210
  <div class="card">...</div>
@@ -220,12 +231,12 @@ To adopt global stylesheets into the shadow root:
220
231
 
221
232
  ## Modifiers reference
222
233
 
223
- | Modifier | Description |
224
- |---|---|
225
- | `.url` | Load template from a same-origin URL |
226
- | `.url.external` | Load template from a cross-origin URL |
227
- | `.scoped` | Scope `<style scoped>` via data attribute |
228
- | `.isolated` | Render in Shadow DOM |
234
+ | Modifier | Description |
235
+ | ----------------------- | ---------------------------------------------- |
236
+ | `.url` | Load template from a same-origin URL |
237
+ | `.url.external` | Load template from a cross-origin URL |
238
+ | `.scoped` | Scope `<style scoped>` via data attribute |
239
+ | `.isolated` | Render in Shadow DOM |
229
240
  | `.isolated.with-styles` | Shadow DOM + adopt global document stylesheets |
230
241
 
231
242
  ---
@@ -236,15 +247,15 @@ All events bubble and are dispatched on the host element.
236
247
 
237
248
  ```js
238
249
  el.addEventListener('rc:loading', ({ detail }) => console.log('loading', detail.source))
239
- el.addEventListener('rc:loaded', ({ detail }) => console.log('loaded', detail.source))
240
- el.addEventListener('rc:error', ({ detail }) => console.log('error', detail.error))
250
+ el.addEventListener('rc:loaded', ({ detail }) => console.log('loaded', detail.source))
251
+ el.addEventListener('rc:error', ({ detail }) => console.log('error', detail.error))
241
252
  ```
242
253
 
243
- | Event | Fires when | Detail |
244
- |---|---|---|
245
- | `rc:loading` | URL fetch starts (`.url` only) | `{ source }` |
246
- | `rc:loaded` | Component rendered | `{ source }` |
247
- | `rc:error` | Expression, fetch, or render failed | `{ source, error }` |
254
+ | Event | Fires when | Detail |
255
+ | ------------ | ----------------------------------- | ------------------- |
256
+ | `rc:loading` | URL fetch starts (`.url` only) | `{ source }` |
257
+ | `rc:loaded` | Component rendered | `{ source }` |
258
+ | `rc:error` | Expression, fetch, or render failed | `{ source, error }` |
248
259
 
249
260
  ---
250
261
 
@@ -285,8 +296,24 @@ npm i -D vite-plugin-bake-alpine-components
285
296
  import bakeAlpineComponents from 'vite-plugin-bake-alpine-components'
286
297
 
287
298
  export default {
288
- plugins: [bakeAlpineComponents()]
299
+ plugins: [bakeAlpineComponents()],
289
300
  }
290
301
  ```
291
302
 
292
- The plugin evaluates `x-for`, `x-text`, and `x-component.url` at build time and outputs plain HTML with all data already inlined — no Alpine runtime needed for the initial render.
303
+ Use an explicit split between build-time and runtime directives:
304
+
305
+ - `s-*` directives are baked at build time by the Vite plugin.
306
+ - `x-*`, `:*`, and `@*` directives are left untouched for Alpine runtime.
307
+
308
+ `alpine-rc` also normalizes `s-*` to their Alpine equivalents in dev/runtime mode so behavior stays consistent:
309
+
310
+ - `s-text -> x-text`
311
+ - `s-html -> x-html`
312
+ - `s-class -> :class`
313
+ - `s-style -> :style`
314
+ - `s-show -> x-show`
315
+ - `s-bind:attr -> :attr`
316
+ - `<template s-for> -> <template x-for>`
317
+ - `<template s-if> -> <template x-if>`
318
+
319
+ This keeps component authoring simple: use `s-*` for baked/static output and `x-*` for client reactivity.
@@ -1,6 +1,6 @@
1
- var O=new Set(["component","data","init","ignore","ref","bind","on","model","show","if","for","id","class","style"]);function U(t,e){let o={};for(let r of t.attributes){let n=null;if(r.name.startsWith(":")?n=r.name.slice(1):r.name.startsWith("x-bind:")&&(n=r.name.slice(7)),!(!n||O.has(n)||n.startsWith("component")))try{o[n]=e(r.value)}catch{o[n]=r.value}}return o}function A(t){let e={};for(let o of t.querySelectorAll(":scope > template[x-slot]")){let r=(o.getAttribute("x-slot")||"default").trim()||"default";e[r]=o.content.cloneNode(!0)}if(!e.default){let o=[...t.childNodes].filter(r=>!(r.nodeName==="TEMPLATE"&&r.hasAttribute("x-slot")));if(o.length){let r=document.createDocumentFragment();o.forEach(n=>r.appendChild(n.cloneNode(!0))),e.default=r}}return e}function k(t,e){for(let o of t.querySelectorAll("slot[name]")){let r=o.getAttribute("name"),n=e[r];n?o.replaceWith(n.cloneNode(!0)):o.replaceWith(...o.childNodes)}for(let o of t.querySelectorAll("slot:not([name])")){let r=e.default;r?o.replaceWith(r.cloneNode(!0)):o.replaceWith(...o.childNodes)}}function E(t=100){let e=new Map;return e.maxEntries=t,e}function d(t,e,o){for(t.set(e,o);t.size>t.maxEntries;)t.delete(t.keys().next().value)}var w=E(200),y=E(200),p=E(100);function T(t){let e=5381;for(let o=0;o<t.length;o++)e=((e<<5)+e^t.charCodeAt(o))>>>0;return e.toString(36)}function K(t,e){return t.split(",").map(o=>{let r=o.trim();return!r||r===":root"||r==="html"||r==="body"?r:r.replace(/(::[\w-]+)?$/,`[${e}]$1`)}).join(", ")}function F(t,e){if(t.selectorText!==void 0)return`${K(t.selectorText,e)} { ${t.style.cssText} }`;if(t.cssRules){let o=t.cssText.match(/^([^{]+)\{/)?.[1]?.trim()??"",r=Array.from(t.cssRules).map(n=>F(n,e)).join(`
1
+ var O=new Set(["component","data","init","ignore","ref","bind","on","model","show","if","for","id","class","style"]);function L(e,t){let o={};for(let r of e.attributes){let n=null;if(r.name.startsWith(":")?n=r.name.slice(1):r.name.startsWith("x-bind:")&&(n=r.name.slice(7)),!(!n||O.has(n)||n.startsWith("component")))try{o[n]=t(r.value)}catch{o[n]=r.value}}return o}function U(e){let t={};for(let o of e.querySelectorAll(":scope > template[x-slot]")){let r=(o.getAttribute("x-slot")||"default").trim()||"default";t[r]=o.content.cloneNode(!0)}if(!t.default){let o=[...e.childNodes].filter(r=>!(r.nodeName==="TEMPLATE"&&r.hasAttribute("x-slot")));if(o.length){let r=document.createDocumentFragment();o.forEach(n=>r.appendChild(n.cloneNode(!0))),t.default=r}}return t}function k(e,t){for(let o of e.querySelectorAll("slot[name]")){let r=o.getAttribute("name"),n=t[r];n?o.replaceWith(n.cloneNode(!0)):o.replaceWith(...o.childNodes)}for(let o of e.querySelectorAll("slot:not([name])")){let r=t.default;r?o.replaceWith(r.cloneNode(!0)):o.replaceWith(...o.childNodes)}}function T(e=100){let t=new Map;return t.maxEntries=e,t}function p(e,t,o){for(e.set(t,o);e.size>e.maxEntries;)e.delete(e.keys().next().value)}var g=T(200),y=T(200),d=T(100);function w(e){let t=5381;for(let o=0;o<e.length;o++)t=((t<<5)+t^e.charCodeAt(o))>>>0;return t.toString(36)}function K(e,t){return e.split(",").map(o=>{let r=o.trim();return!r||r===":root"||r==="html"||r==="body"?r:r.replace(/(::[\w-]+)?$/,`[${t}]$1`)}).join(", ")}function F(e,t){if(e.selectorText!==void 0)return`${K(e.selectorText,t)} { ${e.style.cssText} }`;if(e.cssRules){let o=e.cssText.match(/^([^{]+)\{/)?.[1]?.trim()??"",r=Array.from(e.cssRules).map(n=>F(n,t)).join(`
2
2
  `);return`${o} {
3
3
  ${r}
4
- }`}return t.cssText}function z(t,e){let o=new CSSStyleSheet;try{o.replaceSync(t)}catch{return t}return Array.from(o.cssRules).map(r=>F(r,e)).join(`
5
- `)}function j(t,e){if(document.getElementById(t))return;let o=document.createElement("style");o.id=t,o.textContent=e,document.head.appendChild(o)}function M(t,e,o,r){let n=[...t.querySelectorAll("style")];if(!n.length)return null;if(r){for(let i of n)i.removeAttribute("scoped");return null}let u=null;for(let i of n){let a=i.textContent.trim(),g=i.hasAttribute("scoped");if(i.remove(),!!a)if(g&&o){let c=`scoped:${e}`;if(!p.has(c)){let S=`data-arc-${T(e)}`,h=z(a,S);d(p,c,S),j(`arc-scoped-${T(e)}`,h)}u=p.get(c)}else{let c=`global:${e}:${T(a)}`;p.has(c)||(d(p,c,!0),j(`arc-global-${T(e+a)}`,a))}}return u}function W(t,e){let o=r=>{r.nodeType===Node.ELEMENT_NODE&&r.setAttribute(e,"");for(let n of r.childNodes)o(n)};for(let r of t.childNodes)o(r)}function B(t){let e=[...document.styleSheets].filter(o=>{try{return o.href&&new URL(o.href,location.href),!o.href||new URL(o.href).origin===location.origin}catch{return!1}}).map(o=>{try{let r=new CSSStyleSheet,n=[...o.cssRules].map(u=>u.cssText).join(`
6
- `);return r.replaceSync(n),r}catch{return null}}).filter(Boolean);t.adoptedStyleSheets=e}function D(t){let e=document.createElement("template");return e.innerHTML=t,e.content}function G(t){let e=t.match(/^\s*<template[^>]*>([\s\S]*)<\/template>\s*$/i);return e?e[1].trim():t.trim()}function H(t,e){let o=(t??"").trim();if(!o)throw new Error("[alpine-rc] Empty URL");let r=new URL(o,location.href);if(!["http:","https:"].includes(r.protocol))throw new Error(`[alpine-rc] Unsupported protocol: ${r.protocol}`);if(!e&&r.origin!==location.origin)throw new Error(`[alpine-rc] Cross-origin URL blocked: ${r.href}`);return r.href}function P(t){let e=(t??"").trim();if(!e)return null;if(!w.has(e)){let o=document.getElementById(e);if(!o)return console.warn(`[alpine-rc] Template not found: "${e}"`),null;d(w,e,o.innerHTML)}return D(w.get(e)).cloneNode(!0)}async function _(t,{allowExternal:e=!1}={}){let o=H(t,e);y.has(o)||d(y,o,fetch(o).then(r=>{if(!r.ok)throw new Error(`[alpine-rc] Fetch failed (${r.status}): ${o}`);return r.text()}).then(G));try{let r=await y.get(o);return D(r).cloneNode(!0)}catch(r){throw y.delete(o),r}}function b(t,e,o={}){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:o}))}function J(t,e){if(!t)return"";try{let o=e(t);return o==null||o===!1?"":String(o).trim()}catch(o){return console.error("[alpine-rc] Expression error:",o),""}}function C(t,e,o){if(o)t.shadowRoot&&(e.destroyTree(t.shadowRoot),t.shadowRoot.replaceChildren());else{for(let r of[...t.children])e.destroyTree(r);t.replaceChildren(),delete t._x_dataStack}}function $(t){t.directive("component",(e,{expression:o,modifiers:r},{effect:n,cleanup:u,evaluate:i})=>{let a=r.includes("url"),g=r.includes("external"),c=r.includes("isolated"),S=r.includes("scoped"),h=0,f=!1,v=null,m=t.reactive({});n(()=>{let l=J(o,i),R=U(e,i);for(let s of Object.keys(m))s in R||delete m[s];if(Object.assign(m,R),f&&l===v)return;if(v=l,!l){f&&C(e,t,c),f=!1;return}let q=++h;(async()=>{try{a&&b(e,"rc:loading",{source:l});let s=a?await _(l,{allowExternal:g}):P(l);if(q!==h||!s)return;let I=A(e),L=M(s,l,S,c);if(k(s,I),L&&W(s,L),f&&C(e,t,c),c){let x=e.shadowRoot||e.attachShadow({mode:"open"});r.includes("with-styles")&&B(x),t.addScopeToNode(x,m,e),x.replaceChildren(s),t.initTree(x)}else t.addScopeToNode(e,m),e.replaceChildren(s),t.initTree(e);f=!0,b(e,"rc:loaded",{source:l})}catch(s){console.error("[alpine-rc]",s),b(e,"rc:error",{source:l,error:s})}})()}),u(()=>{h++,f&&C(e,t,c)})})}function N(t){$(t)}var ue=N;export{ue as default};
4
+ }`}return e.cssText}function G(e,t){let o=new CSSStyleSheet;try{o.replaceSync(e)}catch{return e}return Array.from(o.cssRules).map(r=>F(r,t)).join(`
5
+ `)}function j(e,t){if(document.getElementById(e))return;let o=document.createElement("style");o.id=e,o.textContent=t,document.head.appendChild(o)}function D(e,t,o,r){let n=[...e.querySelectorAll("style")];if(!n.length)return null;if(r){for(let i of n)i.removeAttribute("scoped");return null}let f=null;for(let i of n){let a=i.textContent.trim(),b=i.hasAttribute("scoped");if(i.remove(),!!a)if(b&&o){let c=`scoped:${t}`;if(!d.has(c)){let S=`data-arc-${w(t)}`,h=G(a,S);p(d,c,S),j(`arc-scoped-${w(t)}`,h)}f=d.get(c)}else{let c=`global:${t}:${w(a)}`;d.has(c)||(p(d,c,!0),j(`arc-global-${w(t+a)}`,a))}}return f}function M(e,t){let o=r=>{r.nodeType===Node.ELEMENT_NODE&&r.setAttribute(t,"");for(let n of r.childNodes)o(n)};for(let r of e.childNodes)o(r)}function W(e){let t=[...document.styleSheets].filter(o=>{try{return o.href&&new URL(o.href,location.href),!o.href||new URL(o.href).origin===location.origin}catch{return!1}}).map(o=>{try{let r=new CSSStyleSheet,n=[...o.cssRules].map(f=>f.cssText).join(`
6
+ `);return r.replaceSync(n),r}catch{return null}}).filter(Boolean);e.adoptedStyleSheets=t}function B(e){let t=document.createElement("template");return t.innerHTML=e,t.content}function H(e){let t=e.match(/^\s*<template[^>]*>([\s\S]*)<\/template>\s*$/i);return t?t[1].trim():e.trim()}function P(e){return e.replace(/\bs-text=/g,"x-text=").replace(/\bs-html=/g,"x-html=").replace(/\bs-class=/g,":class=").replace(/\bs-style=/g,":style=").replace(/\bs-show=/g,"x-show=").replace(/\bs-bind:([a-zA-Z][a-zA-Z0-9-]*)=/g,":$1=").replace(/(<template\b[^>]*\s)s-for=/g,"$1x-for=").replace(/(<template\b[^>]*\s)s-if=/g,"$1x-if=").replace(/\bs-if=/g,"x-if=")}function Z(e,t){let o=(e??"").trim();if(!o)throw new Error("[alpine-rc] Empty URL");let r=new URL(o,location.href);if(!["http:","https:"].includes(r.protocol))throw new Error(`[alpine-rc] Unsupported protocol: ${r.protocol}`);if(!t&&r.origin!==location.origin)throw new Error(`[alpine-rc] Cross-origin URL blocked: ${r.href}`);return r.href}function _(e){let t=(e??"").trim();if(!t)return null;if(!g.has(t)){let o=document.getElementById(t);if(!o)return console.warn(`[alpine-rc] Template not found: "${t}"`),null;p(g,t,P(o.innerHTML))}return B(g.get(t)).cloneNode(!0)}async function q(e,{allowExternal:t=!1}={}){let o=Z(e,t);y.has(o)||p(y,o,fetch(o).then(r=>{if(!r.ok)throw new Error(`[alpine-rc] Fetch failed (${r.status}): ${o}`);return r.text()}).then(H).then(P));try{let r=await y.get(o);return B(r).cloneNode(!0)}catch(r){throw y.delete(o),r}}function E(e,t,o={}){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,composed:!0,detail:o}))}function J(e,t){if(!e)return"";try{let o=t(e);return o==null||o===!1?"":String(o).trim()}catch(o){return console.error("[alpine-rc] Expression error:",o),""}}function $(e,t,o){if(o)e.shadowRoot&&(t.destroyTree(e.shadowRoot),e.shadowRoot.replaceChildren());else{for(let r of[...e.children])t.destroyTree(r);e.replaceChildren(),delete e._x_dataStack}}function C(e){e.directive("component",(t,{expression:o,modifiers:r},{effect:n,cleanup:f,evaluate:i})=>{let a=r.includes("url"),b=r.includes("external"),c=r.includes("isolated"),S=r.includes("scoped"),h=0,u=!1,N=null,m=e.reactive({});n(()=>{let l=J(o,i),R=L(t,i);for(let s of Object.keys(m))s in R||delete m[s];if(Object.assign(m,R),u&&l===N)return;if(N=l,!l){u&&$(t,e,c),u=!1;return}let z=++h;(async()=>{try{a&&E(t,"rc:loading",{source:l});let s=a?await q(l,{allowExternal:b}):_(l);if(z!==h||!s)return;let I=U(t),A=D(s,l,S,c);if(k(s,I),A&&M(s,A),u&&$(t,e,c),c){let x=t.shadowRoot||t.attachShadow({mode:"open"});r.includes("with-styles")&&W(x),e.addScopeToNode(x,m,t),x.replaceChildren(s),e.initTree(x)}else e.addScopeToNode(t,m),t.replaceChildren(s),e.initTree(t);u=!0,E(t,"rc:loaded",{source:l})}catch(s){console.error("[alpine-rc]",s),E(t,"rc:error",{source:l,error:s})}})()}),f(()=>{h++,u&&$(t,e,c)})})}function v(e){C(e)}var ue=v;export{ue as default};
@@ -1,6 +1,6 @@
1
- (()=>{var O=new Set(["component","data","init","ignore","ref","bind","on","model","show","if","for","id","class","style"]);function A(t,e){let o={};for(let r of t.attributes){let n=null;if(r.name.startsWith(":")?n=r.name.slice(1):r.name.startsWith("x-bind:")&&(n=r.name.slice(7)),!(!n||O.has(n)||n.startsWith("component")))try{o[n]=e(r.value)}catch{o[n]=r.value}}return o}function U(t){let e={};for(let o of t.querySelectorAll(":scope > template[x-slot]")){let r=(o.getAttribute("x-slot")||"default").trim()||"default";e[r]=o.content.cloneNode(!0)}if(!e.default){let o=[...t.childNodes].filter(r=>!(r.nodeName==="TEMPLATE"&&r.hasAttribute("x-slot")));if(o.length){let r=document.createDocumentFragment();o.forEach(n=>r.appendChild(n.cloneNode(!0))),e.default=r}}return e}function k(t,e){for(let o of t.querySelectorAll("slot[name]")){let r=o.getAttribute("name"),n=e[r];n?o.replaceWith(n.cloneNode(!0)):o.replaceWith(...o.childNodes)}for(let o of t.querySelectorAll("slot:not([name])")){let r=e.default;r?o.replaceWith(r.cloneNode(!0)):o.replaceWith(...o.childNodes)}}function E(t=100){let e=new Map;return e.maxEntries=t,e}function d(t,e,o){for(t.set(e,o);t.size>t.maxEntries;)t.delete(t.keys().next().value)}var x=E(200),y=E(200),p=E(100);function g(t){let e=5381;for(let o=0;o<t.length;o++)e=((e<<5)+e^t.charCodeAt(o))>>>0;return e.toString(36)}function K(t,e){return t.split(",").map(o=>{let r=o.trim();return!r||r===":root"||r==="html"||r==="body"?r:r.replace(/(::[\w-]+)?$/,`[${e}]$1`)}).join(", ")}function F(t,e){if(t.selectorText!==void 0)return`${K(t.selectorText,e)} { ${t.style.cssText} }`;if(t.cssRules){let o=t.cssText.match(/^([^{]+)\{/)?.[1]?.trim()??"",r=Array.from(t.cssRules).map(n=>F(n,e)).join(`
1
+ (()=>{var O=new Set(["component","data","init","ignore","ref","bind","on","model","show","if","for","id","class","style"]);function L(e,t){let o={};for(let r of e.attributes){let n=null;if(r.name.startsWith(":")?n=r.name.slice(1):r.name.startsWith("x-bind:")&&(n=r.name.slice(7)),!(!n||O.has(n)||n.startsWith("component")))try{o[n]=t(r.value)}catch{o[n]=r.value}}return o}function U(e){let t={};for(let o of e.querySelectorAll(":scope > template[x-slot]")){let r=(o.getAttribute("x-slot")||"default").trim()||"default";t[r]=o.content.cloneNode(!0)}if(!t.default){let o=[...e.childNodes].filter(r=>!(r.nodeName==="TEMPLATE"&&r.hasAttribute("x-slot")));if(o.length){let r=document.createDocumentFragment();o.forEach(n=>r.appendChild(n.cloneNode(!0))),t.default=r}}return t}function k(e,t){for(let o of e.querySelectorAll("slot[name]")){let r=o.getAttribute("name"),n=t[r];n?o.replaceWith(n.cloneNode(!0)):o.replaceWith(...o.childNodes)}for(let o of e.querySelectorAll("slot:not([name])")){let r=t.default;r?o.replaceWith(r.cloneNode(!0)):o.replaceWith(...o.childNodes)}}function T(e=100){let t=new Map;return t.maxEntries=e,t}function p(e,t,o){for(e.set(t,o);e.size>e.maxEntries;)e.delete(e.keys().next().value)}var g=T(200),y=T(200),d=T(100);function w(e){let t=5381;for(let o=0;o<e.length;o++)t=((t<<5)+t^e.charCodeAt(o))>>>0;return t.toString(36)}function K(e,t){return e.split(",").map(o=>{let r=o.trim();return!r||r===":root"||r==="html"||r==="body"?r:r.replace(/(::[\w-]+)?$/,`[${t}]$1`)}).join(", ")}function F(e,t){if(e.selectorText!==void 0)return`${K(e.selectorText,t)} { ${e.style.cssText} }`;if(e.cssRules){let o=e.cssText.match(/^([^{]+)\{/)?.[1]?.trim()??"",r=Array.from(e.cssRules).map(n=>F(n,t)).join(`
2
2
  `);return`${o} {
3
3
  ${r}
4
- }`}return t.cssText}function z(t,e){let o=new CSSStyleSheet;try{o.replaceSync(t)}catch{return t}return Array.from(o.cssRules).map(r=>F(r,e)).join(`
5
- `)}function j(t,e){if(document.getElementById(t))return;let o=document.createElement("style");o.id=t,o.textContent=e,document.head.appendChild(o)}function M(t,e,o,r){let n=[...t.querySelectorAll("style")];if(!n.length)return null;if(r){for(let i of n)i.removeAttribute("scoped");return null}let u=null;for(let i of n){let a=i.textContent.trim(),T=i.hasAttribute("scoped");if(i.remove(),!!a)if(T&&o){let c=`scoped:${e}`;if(!p.has(c)){let S=`data-arc-${g(e)}`,h=z(a,S);d(p,c,S),j(`arc-scoped-${g(e)}`,h)}u=p.get(c)}else{let c=`global:${e}:${g(a)}`;p.has(c)||(d(p,c,!0),j(`arc-global-${g(e+a)}`,a))}}return u}function W(t,e){let o=r=>{r.nodeType===Node.ELEMENT_NODE&&r.setAttribute(e,"");for(let n of r.childNodes)o(n)};for(let r of t.childNodes)o(r)}function B(t){let e=[...document.styleSheets].filter(o=>{try{return o.href&&new URL(o.href,location.href),!o.href||new URL(o.href).origin===location.origin}catch{return!1}}).map(o=>{try{let r=new CSSStyleSheet,n=[...o.cssRules].map(u=>u.cssText).join(`
6
- `);return r.replaceSync(n),r}catch{return null}}).filter(Boolean);t.adoptedStyleSheets=e}function D(t){let e=document.createElement("template");return e.innerHTML=t,e.content}function G(t){let e=t.match(/^\s*<template[^>]*>([\s\S]*)<\/template>\s*$/i);return e?e[1].trim():t.trim()}function H(t,e){let o=(t??"").trim();if(!o)throw new Error("[alpine-rc] Empty URL");let r=new URL(o,location.href);if(!["http:","https:"].includes(r.protocol))throw new Error(`[alpine-rc] Unsupported protocol: ${r.protocol}`);if(!e&&r.origin!==location.origin)throw new Error(`[alpine-rc] Cross-origin URL blocked: ${r.href}`);return r.href}function P(t){let e=(t??"").trim();if(!e)return null;if(!x.has(e)){let o=document.getElementById(e);if(!o)return console.warn(`[alpine-rc] Template not found: "${e}"`),null;d(x,e,o.innerHTML)}return D(x.get(e)).cloneNode(!0)}async function _(t,{allowExternal:e=!1}={}){let o=H(t,e);y.has(o)||d(y,o,fetch(o).then(r=>{if(!r.ok)throw new Error(`[alpine-rc] Fetch failed (${r.status}): ${o}`);return r.text()}).then(G));try{let r=await y.get(o);return D(r).cloneNode(!0)}catch(r){throw y.delete(o),r}}function b(t,e,o={}){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:o}))}function J(t,e){if(!t)return"";try{let o=e(t);return o==null||o===!1?"":String(o).trim()}catch(o){return console.error("[alpine-rc] Expression error:",o),""}}function C(t,e,o){if(o)t.shadowRoot&&(e.destroyTree(t.shadowRoot),t.shadowRoot.replaceChildren());else{for(let r of[...t.children])e.destroyTree(r);t.replaceChildren(),delete t._x_dataStack}}function $(t){t.directive("component",(e,{expression:o,modifiers:r},{effect:n,cleanup:u,evaluate:i})=>{let a=r.includes("url"),T=r.includes("external"),c=r.includes("isolated"),S=r.includes("scoped"),h=0,f=!1,N=null,m=t.reactive({});n(()=>{let l=J(o,i),R=A(e,i);for(let s of Object.keys(m))s in R||delete m[s];if(Object.assign(m,R),f&&l===N)return;if(N=l,!l){f&&C(e,t,c),f=!1;return}let q=++h;(async()=>{try{a&&b(e,"rc:loading",{source:l});let s=a?await _(l,{allowExternal:T}):P(l);if(q!==h||!s)return;let I=U(e),L=M(s,l,S,c);if(k(s,I),L&&W(s,L),f&&C(e,t,c),c){let w=e.shadowRoot||e.attachShadow({mode:"open"});r.includes("with-styles")&&B(w),t.addScopeToNode(w,m,e),w.replaceChildren(s),t.initTree(w)}else t.addScopeToNode(e,m),e.replaceChildren(s),t.initTree(e);f=!0,b(e,"rc:loaded",{source:l})}catch(s){console.error("[alpine-rc]",s),b(e,"rc:error",{source:l,error:s})}})()}),u(()=>{h++,f&&C(e,t,c)})})}function v(t){$(t)}document.addEventListener("alpine:init",()=>window.Alpine.plugin(v));})();
4
+ }`}return e.cssText}function G(e,t){let o=new CSSStyleSheet;try{o.replaceSync(e)}catch{return e}return Array.from(o.cssRules).map(r=>F(r,t)).join(`
5
+ `)}function j(e,t){if(document.getElementById(e))return;let o=document.createElement("style");o.id=e,o.textContent=t,document.head.appendChild(o)}function D(e,t,o,r){let n=[...e.querySelectorAll("style")];if(!n.length)return null;if(r){for(let i of n)i.removeAttribute("scoped");return null}let f=null;for(let i of n){let a=i.textContent.trim(),b=i.hasAttribute("scoped");if(i.remove(),!!a)if(b&&o){let c=`scoped:${t}`;if(!d.has(c)){let S=`data-arc-${w(t)}`,h=G(a,S);p(d,c,S),j(`arc-scoped-${w(t)}`,h)}f=d.get(c)}else{let c=`global:${t}:${w(a)}`;d.has(c)||(p(d,c,!0),j(`arc-global-${w(t+a)}`,a))}}return f}function M(e,t){let o=r=>{r.nodeType===Node.ELEMENT_NODE&&r.setAttribute(t,"");for(let n of r.childNodes)o(n)};for(let r of e.childNodes)o(r)}function W(e){let t=[...document.styleSheets].filter(o=>{try{return o.href&&new URL(o.href,location.href),!o.href||new URL(o.href).origin===location.origin}catch{return!1}}).map(o=>{try{let r=new CSSStyleSheet,n=[...o.cssRules].map(f=>f.cssText).join(`
6
+ `);return r.replaceSync(n),r}catch{return null}}).filter(Boolean);e.adoptedStyleSheets=t}function B(e){let t=document.createElement("template");return t.innerHTML=e,t.content}function H(e){let t=e.match(/^\s*<template[^>]*>([\s\S]*)<\/template>\s*$/i);return t?t[1].trim():e.trim()}function P(e){return e.replace(/\bs-text=/g,"x-text=").replace(/\bs-html=/g,"x-html=").replace(/\bs-class=/g,":class=").replace(/\bs-style=/g,":style=").replace(/\bs-show=/g,"x-show=").replace(/\bs-bind:([a-zA-Z][a-zA-Z0-9-]*)=/g,":$1=").replace(/(<template\b[^>]*\s)s-for=/g,"$1x-for=").replace(/(<template\b[^>]*\s)s-if=/g,"$1x-if=").replace(/\bs-if=/g,"x-if=")}function Z(e,t){let o=(e??"").trim();if(!o)throw new Error("[alpine-rc] Empty URL");let r=new URL(o,location.href);if(!["http:","https:"].includes(r.protocol))throw new Error(`[alpine-rc] Unsupported protocol: ${r.protocol}`);if(!t&&r.origin!==location.origin)throw new Error(`[alpine-rc] Cross-origin URL blocked: ${r.href}`);return r.href}function _(e){let t=(e??"").trim();if(!t)return null;if(!g.has(t)){let o=document.getElementById(t);if(!o)return console.warn(`[alpine-rc] Template not found: "${t}"`),null;p(g,t,P(o.innerHTML))}return B(g.get(t)).cloneNode(!0)}async function q(e,{allowExternal:t=!1}={}){let o=Z(e,t);y.has(o)||p(y,o,fetch(o).then(r=>{if(!r.ok)throw new Error(`[alpine-rc] Fetch failed (${r.status}): ${o}`);return r.text()}).then(H).then(P));try{let r=await y.get(o);return B(r).cloneNode(!0)}catch(r){throw y.delete(o),r}}function E(e,t,o={}){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,composed:!0,detail:o}))}function J(e,t){if(!e)return"";try{let o=t(e);return o==null||o===!1?"":String(o).trim()}catch(o){return console.error("[alpine-rc] Expression error:",o),""}}function $(e,t,o){if(o)e.shadowRoot&&(t.destroyTree(e.shadowRoot),e.shadowRoot.replaceChildren());else{for(let r of[...e.children])t.destroyTree(r);e.replaceChildren(),delete e._x_dataStack}}function C(e){e.directive("component",(t,{expression:o,modifiers:r},{effect:n,cleanup:f,evaluate:i})=>{let a=r.includes("url"),b=r.includes("external"),c=r.includes("isolated"),S=r.includes("scoped"),h=0,u=!1,N=null,m=e.reactive({});n(()=>{let l=J(o,i),R=L(t,i);for(let s of Object.keys(m))s in R||delete m[s];if(Object.assign(m,R),u&&l===N)return;if(N=l,!l){u&&$(t,e,c),u=!1;return}let z=++h;(async()=>{try{a&&E(t,"rc:loading",{source:l});let s=a?await q(l,{allowExternal:b}):_(l);if(z!==h||!s)return;let I=U(t),A=D(s,l,S,c);if(k(s,I),A&&M(s,A),u&&$(t,e,c),c){let x=t.shadowRoot||t.attachShadow({mode:"open"});r.includes("with-styles")&&W(x),e.addScopeToNode(x,m,t),x.replaceChildren(s),e.initTree(x)}else e.addScopeToNode(t,m),t.replaceChildren(s),e.initTree(t);u=!0,E(t,"rc:loaded",{source:l})}catch(s){console.error("[alpine-rc]",s),E(t,"rc:error",{source:l,error:s})}})()}),f(()=>{h++,u&&$(t,e,c)})})}function v(e){C(e)}document.addEventListener("alpine:init",()=>window.Alpine.plugin(v));})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alpine-rc",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Alpine.js component plugin — global styles by default, scoped styles on demand, reactive props, slots",
5
5
  "keywords": [
6
6
  "alpinejs",
package/src/template.js CHANGED
@@ -11,6 +11,28 @@ function stripOuterTemplate(html) {
11
11
  return m ? m[1].trim() : html.trim()
12
12
  }
13
13
 
14
+ // Convert s-* build-time directives to their Alpine runtime equivalents so
15
+ // components work identically in dev mode (without the bake plugin).
16
+ //
17
+ // s-text → x-text s-html → x-html
18
+ // s-class → :class s-style → :style
19
+ // s-show → x-show s-bind:attr → :attr
20
+ // <template s-for> → <template x-for>
21
+ // <template s-if> → <template x-if>
22
+ // s-if (on any element) → x-if
23
+ function convertServerDirectives(html) {
24
+ return html
25
+ .replace(/\bs-text=/g, 'x-text=')
26
+ .replace(/\bs-html=/g, 'x-html=')
27
+ .replace(/\bs-class=/g, ':class=')
28
+ .replace(/\bs-style=/g, ':style=')
29
+ .replace(/\bs-show=/g, 'x-show=')
30
+ .replace(/\bs-bind:([a-zA-Z][a-zA-Z0-9-]*)=/g, ':$1=')
31
+ .replace(/(<template\b[^>]*\s)s-for=/g, '$1x-for=')
32
+ .replace(/(<template\b[^>]*\s)s-if=/g, '$1x-if=')
33
+ .replace(/\bs-if=/g, 'x-if=')
34
+ }
35
+
14
36
  function resolveUrl(url, allowExternal) {
15
37
  const normalized = (url ?? '').trim()
16
38
  if (!normalized) throw new Error('[alpine-rc] Empty URL')
@@ -38,7 +60,7 @@ export function loadFromTemplate(id) {
38
60
  console.warn(`[alpine-rc] Template not found: "${key}"`)
39
61
  return null
40
62
  }
41
- setBounded(templateCache, key, el.innerHTML)
63
+ setBounded(templateCache, key, convertServerDirectives(el.innerHTML))
42
64
  }
43
65
 
44
66
  return toFragment(templateCache.get(key)).cloneNode(true)
@@ -56,7 +78,8 @@ export async function loadFromUrl(url, { allowExternal = false } = {}) {
56
78
  if (!r.ok) throw new Error(`[alpine-rc] Fetch failed (${r.status}): ${resolved}`)
57
79
  return r.text()
58
80
  })
59
- .then(stripOuterTemplate),
81
+ .then(stripOuterTemplate)
82
+ .then(convertServerDirectives)
60
83
  )
61
84
  }
62
85