atmx-web 0.46.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/atmx.es.js CHANGED
@@ -393,8 +393,8 @@ function O(e, t) {
393
393
  }
394
394
  function k(e, t, n) {
395
395
  if (!V.debug) return;
396
- let r = e === "OUT" ? "#7c3aed" : "#059669", i = e === "OUT" ? "➔ WASM CALL" : "← WASM RESP";
397
- console.groupCollapsed(`%c${i} [#${t}]`, `color: ${r}; font-weight: bold;`), console.log("Details:", n), console.groupEnd();
396
+ let r = e === "OUT" ? "#7c3aed" : "#059669";
397
+ console.groupCollapsed(`%c${e === "OUT" ? "➔ WASM CALL" : "← WASM RESP"} [#${t}]`, `color: ${r}; font-weight: bold;`), console.log("Details:", n), console.groupEnd();
398
398
  }
399
399
  function A(e, t) {
400
400
  let n = t.trim().match(/^([\w\.]+)(?:\((.*)\))?$/);
@@ -647,7 +647,7 @@ var z = class extends HTMLElement {
647
647
  typeof window < "u" && !customElements.get("ax-engine-status") && customElements.define("ax-engine-status", z);
648
648
  //#endregion
649
649
  //#region src/index.ts
650
- var B = "0.46.0", V = new class {
650
+ var B = "0.47.0", V = new class {
651
651
  version = B;
652
652
  initialized = !1;
653
653
  debug = !1;
@@ -676,4 +676,4 @@ var B = "0.46.0", V = new class {
676
676
  }();
677
677
  typeof window < "u" && (window.atmx = V);
678
678
  //#endregion
679
- export { B as ATMX_VERSION, V as atmx };
679
+ export { B as ATMX_VERSION, l as allocBytes, u as allocString, V as atmx, o as buildRequestPath, m as clearAuthToken, f as initWasm, t as pendingRequests, a as resolveRoute, p as setAuthToken, c as wasmEngine };
package/dist/atmx.umd.js CHANGED
@@ -884,4 +884,4 @@
884
884
  return Object.assign(__wbg_init, { initSync }, exports);
885
885
  })({ __proto__: null });
886
886
  `,l=null;function u(e){if(e.length===0)return 0;let t=l.axiom_malloc(e.length);return new Uint8Array(l.memory.buffer).set(e,t),t}function d(e){if(!e)return{ptr:0,len:0};let t=new TextEncoder().encode(e);return{ptr:u(t),len:t.length}}function f(){return`https://atmx.axiomcore.dev/latest/axiom_runtime.wasm`}async function p(e){let t=performance.now(),n={ok:!1,contracts:{},initDurationMs:0};try{if(!window.wasm_bindgen){let e=document.createElement(`script`);e.type=`text/javascript`,e.text=`${c}\nwindow.wasm_bindgen = wasm_bindgen;`,document.head.appendChild(e)}let t=window.wasm_bindgen,i=`${f()}?t=${Date.now()}`;try{l=await t(fetch(i))}catch(e){throw{stage:`ffiBoundary`,category:`network`,code:`WasmFetchFailed`,message:`Failed to download WASM engine: ${e.message}`,retryable:!0}}r(l),setInterval(()=>{l&&l.axiom_process_responses()},16);let o=d(``),s=l.axiom_wasm_initialize(o.ptr,o.len);if(l.axiom_free_memory(o.ptr,o.len),s!==0)throw{stage:`runtime`,category:`server`,code:`InitFailed`,message:`Engine init failed (Code: ${s})`,retryable:!1};for(let[t,r]of Object.entries(e.contracts))try{let i=await fetch(r.contractUrl);if(!i.ok)throw Error(`HTTP ${i.status}`);let o=await i.arrayBuffer(),s=0;try{let e=new TextDecoder().decode(o),n=JSON.parse(e),r=n?.ir?.endpoints;r&&(s=Array.isArray(r)?r.length:Object.keys(r).length),a(t,n)}catch(e){console.error(`ATMX: Failed to parse .axiom contract for '${t}'`,e)}let c=new Uint8Array(o),f=u(c),p=d(t),m=d(r.baseUrl),h=l.axiom_wasm_load_contract(p.ptr,p.len,m.ptr,m.len,f,c.length,0,0,0,0);if(l.axiom_free_memory(f,c.length),l.axiom_free_memory(p.ptr,p.len),l.axiom_free_memory(m.ptr,m.len),h!==0&&h!==-1)throw Error(`Load error (Code: ${h})`);e.debug&&console.log(`%c🔒 Axiom Contract Loaded: ${t} (${s} endpoints)`,`color: #10b981; font-weight: bold;`),n.contracts[t]={loaded:!0,endpointCount:s},document.dispatchEvent(new CustomEvent(`atmx:contract-loaded`,{detail:{namespace:t,endpointCount:s}}))}catch(e){n.contracts[t]={loaded:!1,endpointCount:0,error:e.message},console.error(`ATMX: Contract failed for ${t}`,e)}n.ok=!0}catch(e){n.ok=!1,n.error=e.stage?e:{stage:`runtime`,category:`unknown`,code:`FatalError`,message:e.message||String(e),retryable:!1}}return n.initDurationMs=Math.round(performance.now()-t),n}function m(e,t,n){if(!l)return;let r=d(e),i=d(t),a=d(n);l.axiom_wasm_set_auth_token(r.ptr,r.len,i.ptr,i.len,a.ptr,a.len),l.axiom_free_memory(r.ptr,r.len),l.axiom_free_memory(i.ptr,i.len),l.axiom_free_memory(a.ptr,a.len)}function h(e,t){if(!l)return;let n=d(e),r=d(t);l.axiom_wasm_clear_auth_token(n.ptr,n.len,r.ptr,r.len),l.axiom_free_memory(n.ptr,n.len),l.axiom_free_memory(r.ptr,r.len)}function g(e,t,n={}){if(e)try{let r=Object.keys(n),i=Object.values(n);return Function(`$data`,`$error`,`$state`,...r,`return (${e});`)(t.data||{},t.error||{},t,...i)}catch(t){console.error(`ATMX Eval Error: ${e}`,t);return}}function _(e,t,n={}){if(e)try{let r=Object.keys(n),i=Object.values(n);Function(`$data`,`$error`,`$state`,...r,e)(t.data||{},t.error||{},t,...i)}catch(t){console.error(`ATMX Action Error: ${e}`,t)}}function v(e,t){y(e,t,!0,{})}function y(e,t,n,r){if(!(!n&&(e.hasAttribute(`ax-query`)||e.hasAttribute(`ax-mutate`)))){if(e.hasAttribute(`ax-for`)){b(e,t,r);return}if(e.hasAttribute(`ax-when`)&&(e.getAttribute(`ax-when`).split(`,`).map(e=>e.trim()).includes(t.state)?(e.removeAttribute(`hidden`),e.style.removeProperty(`display`)):(e.setAttribute(`hidden`,`true`),e.style.setProperty(`display`,`none`,`important`))),e.hasAttribute(`ax-if`)&&(g(e.getAttribute(`ax-if`),t,r)?(e.removeAttribute(`hidden`),e.style.removeProperty(`display`)):(e.setAttribute(`hidden`,``),e.style.setProperty(`display`,`none`,`important`))),e.hasAttribute(`ax-text`)){let n=g(e.getAttribute(`ax-text`),t,r);e.textContent=n==null?``:String(n)}if(e.hasAttribute(`ax-error-for`)){let n=e.getAttribute(`ax-error-for`),r=``;if(t.state===`error`&&t.error?.code===`ValidationError`){let e=(t.error.details||``).split(`
887
- `);for(let t of e)if(t.startsWith(n+`:`)){r=t.substring(n.length+1).trim();break}}r?(e.textContent=r,e.removeAttribute(`hidden`),e.style.removeProperty(`display`)):(e.setAttribute(`hidden`,``),e.style.setProperty(`display`,`none`,`important`))}Array.from(e.attributes).forEach(n=>{if(n.name.startsWith(`ax-bind:`)){let i=n.name.substring(8),a=g(n.value,t,r);a===!1||a==null?e.removeAttribute(i):e.setAttribute(i,a===!0?i:String(a))}}),Array.from(e.children).forEach(e=>{y(e,t,!1,r)})}}function b(e,t,n){e.style.display=`none`,e.hasAttribute(`data-ax-for-id`)||e.setAttribute(`data-ax-for-id`,Math.random().toString(36).substr(2,9));let r=e.getAttribute(`data-ax-for-id`),i=e.getAttribute(`ax-for`).match(/^\s*(?:(?:\(\s*([\w\$]+)\s*,\s*([\w\$]+)\s*\))|([\w\$]+))\s+in\s+(.+)$/);if(!i)return;let a=i[1]||i[3],o=i[2],s=i[4],c=g(s,t,n),l=e.parentElement;if(!l)return;let u=Array.from(l.querySelectorAll(`[data-ax-clone-of="${r}"]`));if(!c||!Array.isArray(c)){u.forEach(e=>e.remove());return}let d=e.getAttribute(`ax-key`),f=[];c.forEach((i,s)=>{let c={...n,[a]:i};o&&(c[o]=s);let p=String(s);d&&(p=String(g(d,t,c)));let m=u.find(e=>e.getAttribute(`data-ax-key`)===p);m||(m=e.cloneNode(!0),m.removeAttribute(`ax-for`),m.style.removeProperty(`display`),m.style.length===0&&m.removeAttribute(`style`),m.setAttribute(`data-ax-clone-of`,r),m.setAttribute(`data-ax-key`,p)),l.insertBefore(m,e),y(m,t,!1,c),f.push(m)}),u.forEach(e=>{f.includes(e)||e.remove()})}var x=new WeakMap;function S(e){return x.has(e)||x.set(e,{state:`idle`,isFetching:!1,isMutating:!1,source:null,data:null,error:null}),x.get(e)}function C(e){let t=e.parentElement;for(;t;){if(t.hasAttribute(`ax-query`)||t.hasAttribute(`ax-mutate`)){let e=x.get(t);if(e&&e.data)return e.data}t=t.parentElement}return{}}function w(e,t){let n=S(e);Object.assign(n,t),t.state===`loading`&&(n.isFetching=!0),t.state===`mutating`&&(n.isMutating=!0),(t.state===`success`||t.state===`data`&&t.isFetching===!1)&&(n.isFetching=!1,n.isMutating=!1),x.set(e,n),v(e,n)}var T=0,E=class{key;route;args;state;listeners=new Set;currentReqId=null;constructor(e,t,n){this.key=e,this.route=t,this.args=n,this.state={state:`idle`,isFetching:!1,source:null,data:null,error:null}}subscribe(e){this.listeners.add(e),e(this.state)}update(e){this.state={...this.state,...e},this.listeners.forEach(e=>e(this.state))}fetch(e=!1){if(this.state.isFetching&&!e)return;this.update({state:this.state.data?`data`:`loading`,isFetching:!0,error:null});let r=++T;this.currentReqId=r;let{path:i,remainingArgs:a}=s(this.route,this.args),o=new Uint8Array;Object.keys(a).length>0&&(o=new TextEncoder().encode(JSON.stringify(a))),H.debug&&(console.groupCollapsed(`%c➔ WASM QUERY [#${r}]`,`color: #7c3aed; font-weight: bold;`),console.log(`Namespace:`,this.route.namespace),console.log(`Endpoint ID:`,this.route.id),console.log(`Path:`,i),console.groupEnd()),n.set(r,{isStream:this.route.isStream,onResponse:e=>{if(this.currentReqId===r){if(H.debug){let t=e.eventType===1?`NetworkSuccess`:e.eventType===2?`CacheHit`:e.eventType===3?`CacheHitAndFetching`:e.eventType===4?`Error`:`Complete`;console.groupCollapsed(`%c← WASM RESP [#${r}]`,`color: #059669; font-weight: bold;`),console.log(`Event Type:`,t),e.data&&console.log(`Data:`,e.data),e.error&&console.log(`Error:`,e.error),console.groupEnd()}if(e.eventType===t.Error){this.update({state:`error`,error:e.error,isFetching:!1});return}if(e.data){let n=`network`,r=!1;e.eventType===t.CacheHit?(n=`cache`,r=!1):e.eventType===t.CacheHitAndFetching?(n=`cache`,r=!0):e.eventType===t.NetworkSuccess&&(n=`network`,r=!1),this.update({state:`data`,data:e.data,source:n,isFetching:r})}}},onComplete:()=>{this.currentReqId===r&&(H.debug&&console.log(`%c✔ Stream Complete [#${r}]`,`color: #94a3b8;`),this.update({isFetching:!1}))}});let c=d(this.route.namespace),f=d(this.route.method),p=d(i),m=u(o),h=d(``),g=d(``);l.axiom_wasm_call(r,c.ptr,c.len,this.route.id,f.ptr,f.len,p.ptr,p.len,h.ptr,h.len,g.ptr,g.len,m,o.length),l.axiom_free_memory(c.ptr,c.len),l.axiom_free_memory(f.ptr,f.len),l.axiom_free_memory(p.ptr,p.len),l.axiom_free_memory(h.ptr,h.len),l.axiom_free_memory(g.ptr,g.len)}},D=new Map,O=0;function k(e,t){let n=`ax-on:${t}`;e.hasAttribute(n)&&_(e.getAttribute(n),S(e))}function A(e,t,n){if(!H.debug)return;let r=e===`OUT`?`#7c3aed`:`#059669`,i=e===`OUT`?`➔ WASM CALL`:`← WASM RESP`;console.groupCollapsed(`%c${i} [#${t}]`,`color: ${r}; font-weight: bold;`),console.log(`Details:`,n),console.groupEnd()}function j(e,t){let n=t.trim().match(/^([\w\.]+)(?:\((.*)\))?$/);if(!n)return null;let r=n[1],i={};if(n[2]&&n[2].trim()!==``)try{let t=S(e),r=t.data||C(e);i=Function(`$data`,`$state`,`return (${n[2]});`)(r,t)||{}}catch(e){console.error(`ATMX Scope Error in "${t}":`,e)}return{target:r,args:i}}function M(e){let t=e.getAttribute(`ax-query`);if(!t)return;let n=j(e,t);if(!n)return;let r=o(n.target);if(!r){w(e,{state:`error`,error:{message:`Route not found: ${n.target}`}});return}let i=`${r.namespace}:${r.id}:${JSON.stringify(n.args)}`,a=D.get(i);a||(a=new E(i,r,n.args),D.set(i,a)),e._axListener||(e._axListener=t=>{w(e,t),(t.state===`data`||t.state===`error`)&&(k(e,t.state),e.dispatchEvent(new CustomEvent(`atmx:${t.state}`,{bubbles:!0,detail:t.data||t.error})))},a.subscribe(e._axListener)),a.fetch()}function N(e){let t=e.getAttribute(`ax-mutate`);if(!t)return;let n=j(e,t);if(!n)return;let r=o(n.target);if(!r){w(e,{state:`error`,error:{message:`Route not found: ${n.target}`}}),k(e,`error`);return}w(e,{state:`mutating`,error:null,data:null}),k(e,`mutating`);let i={};e instanceof HTMLFormElement&&new FormData(e).forEach((t,n)=>{let r=e.elements.namedItem(n),a=!1;r instanceof HTMLInputElement?a=r.type===`number`:r instanceof RadioNodeList&&r.length>0&&(a=r[0].type===`number`);let o=a&&t!==``?Number(t):t;if(n.includes(`.`)){let e=n.split(`.`),t=i;for(let n=0;n<e.length-1;n++)t[e[n]]||(t[e[n]]={}),t=t[e[n]];t[e[e.length-1]]=o}else i[n]=o});let{path:a,remainingArgs:c}=s(r,{...i,...n.args}),l=c;r.bodyParam&&c[r.bodyParam]!==void 0&&(l=c[r.bodyParam]);let u={},d=e.getAttribute(`ax-headers`);if(d)try{u=Function(`return (`+d+`);`)()||{}}catch(e){console.error(`ATMX: Invalid ax-headers syntax`,e)}let f=Object.entries(u).some(([e,t])=>e.toLowerCase()===`content-type`&&t.includes(`application/x-www-form-urlencoded`)),p=new Uint8Array;if(Object.keys(l).length>0)if(f){let e=new URLSearchParams;for(let[t,n]of Object.entries(l))e.append(t,String(n));p=new TextEncoder().encode(e.toString())}else p=new TextEncoder().encode(JSON.stringify(l));P(e,r.namespace,r.id,r.method,a,p,r.isStream,!0,u,f)}function P(e,t,r,i,a,o,s,c,f={},p=!1){let m=++O;A(`OUT`,m,{namespace:t,endpointId:r,method:i,path:a,headers:f,payload:o.length>0?p?new TextDecoder().decode(o):JSON.parse(new TextDecoder().decode(o)):null}),n.set(m,{isStream:s,onResponse:t=>F(e,t,c,m),onComplete:()=>{H.debug&&console.log(`%c✔ Stream Complete [#${m}]`,`color: #94a3b8;`)}});let h=d(t),g=d(i),_=d(a),v=d(``),y=d(Object.keys(f).length>0?JSON.stringify(f):``),b=u(o);l.axiom_wasm_call(m,h.ptr,h.len,r,g.ptr,g.len,_.ptr,_.len,v.ptr,v.len,y.ptr,y.len,b,o.length),l.axiom_free_memory(h.ptr,h.len),l.axiom_free_memory(g.ptr,g.len),l.axiom_free_memory(_.ptr,_.len),l.axiom_free_memory(v.ptr,v.len),l.axiom_free_memory(y.ptr,y.len),b&&l.axiom_free_memory(b,o.length)}function F(e,n,r,i){if(A(`IN`,i,{eventType:t[n.eventType],data:n.data,error:n.error}),n.eventType===t.Error){w(e,{state:`error`,error:n.error,isFetching:!1,isMutating:!1}),k(e,`error`),e.dispatchEvent(new CustomEvent(`atmx:error`,{bubbles:!0,detail:n.error}));return}if(n.data){let i=`network`,a=!1;n.eventType===t.CacheHit?i=`cache`:n.eventType===t.CacheHitAndFetching?(i=`cache`,a=!0):n.eventType===t.NetworkSuccess&&(i=`network`);let s=r?`success`:`data`;if(w(e,{state:s,data:n.data,source:i,isFetching:a,isMutating:!1}),r){let t=e.getAttribute(`ax-store-token`);if(t){let n=g(t,S(e));if(n){let t=o(j(e,e.getAttribute(`ax-mutate`)).target),r=e.getAttribute(`ax-token-header`)||`Authorization`;H.setAuthToken(t?.namespace||`default`,r,n)}}if(e.hasAttribute(`ax-clear-token`)){let t=o(j(e,e.getAttribute(`ax-mutate`)).target),n=e.getAttribute(`ax-token-header`)||`Authorization`;H.clearAuthToken(t?.namespace||`default`,n)}let n=e.getAttribute(`ax-refresh`);if(n){let e=n.split(`,`).map(e=>e.trim());for(let[t,n]of D.entries()){let t=`${n.route.namespace}.${n.route.name}`;e.includes(t)&&n.fetch(!0)}}}k(e,s),e.dispatchEvent(new CustomEvent(r?`atmx:success`:`atmx:data`,{bubbles:!0,detail:n.data}))}}var I=new IntersectionObserver(e=>{e.forEach(e=>{if(e.isIntersecting){let t=e.target;t.hasAttribute(`ax-query`)&&M(t),I.unobserve(t)}})});function L(e){e.querySelectorAll(`[\\:ax-query], [\\:ax-mutate]`).forEach(e=>{if(e.hasAttribute(`:ax-query`)){let t=g(e.getAttribute(`:ax-query`),S(e));t&&e.setAttribute(`ax-query`,String(t)),e.removeAttribute(`:ax-query`)}if(e.hasAttribute(`:ax-mutate`)){let t=g(e.getAttribute(`:ax-mutate`),S(e));t&&e.setAttribute(`ax-mutate`,String(t)),e.removeAttribute(`:ax-mutate`)}})}function R(e=document){L(e),e.querySelectorAll(`[ax-query]`).forEach(e=>{let t=e;w(t,{});let n=t.getAttribute(`ax-trigger`)||`load`;n===`load`?M(t):n===`intersect`?I.observe(t):t.addEventListener(n,e=>{e.preventDefault(),M(t)})}),e.querySelectorAll(`[ax-mutate]`).forEach(e=>{let t=e;w(t,{});let n=t.tagName===`FORM`?`submit`:`click`;t.addEventListener(n,e=>{(t.tagName===`A`||t.tagName===`BUTTON`||t.tagName===`FORM`)&&e.preventDefault(),N(t)})}),e.querySelectorAll(`[ax-trigger="refresh"]`).forEach(e=>{let t=e;t.addEventListener(`click`,e=>{e.preventDefault();let n=t.closest(`[ax-query]`);if(n){let e=j(n,n.getAttribute(`ax-query`));if(e){let t=o(e.target);if(t){let r=`${t.namespace}:${t.id}:${JSON.stringify(e.args)}`,i=D.get(r);i?i.fetch(!0):M(n)}}}})})}function z(){new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e instanceof HTMLElement&&R(e)})})}).observe(document.body,{childList:!0,subtree:!0})}var B=class extends HTMLElement{constructor(){super()}connectedCallback(){let e=this.getAttribute(`loading-text`)||`Initializing...`,t=this.getAttribute(`ready-text`)||`Online`,n=this.getAttribute(`error-text`)||`Failed to Connect`;this.renderState(`loading`,e,`text-amber-500 animate-pulse`),document.addEventListener(`atmx:ready`,()=>{this.renderState(`ready`,t,`text-green-600`)}),document.addEventListener(`atmx:error`,e=>{let t=e;t.detail&&t.detail.stage===`runtime`&&this.renderState(`error`,`${n}: ${t.detail.message}`,`text-red-600`)})}renderState(e,t,n){this.setAttribute(`data-state`,e);let r=this.querySelectorAll(`[data-ax-when]`);r.length>0?r.forEach(t=>{t.getAttribute(`data-ax-when`)===e?t.removeAttribute(`hidden`):t.setAttribute(`hidden`,``)}):(this.innerText=t,this.getAttribute(`class`)||(this.className=`text-xs font-bold ${n}`))}};typeof window<`u`&&!customElements.get(`ax-engine-status`)&&customElements.define(`ax-engine-status`,B);var V=`0.46.0`,H=new class{version=V;initialized=!1;debug=!1;async init(e){if(this.initialized)return{ok:!0,contracts:{},initDurationMs:0};let t=await p(e);return t.ok?(this.debug=e.debug||!1,z(),R(document.body),this.initialized=!0,this.debug&&console.log(`%c🚀 ATMX Debug Mode: Enabled`,`color: #2563eb; font-weight: bold;`),console.log(`✅ ATMX v${this.version} Online (${t.initDurationMs}ms). Reactive Engine Started.`),document.dispatchEvent(new CustomEvent(`atmx:ready`,{detail:t}))):(console.error(`❌ ATMX Initialization Failed:`,t.error),document.dispatchEvent(new CustomEvent(`atmx:error`,{detail:t.error}))),t}triggerQuery(e){let t=typeof e==`string`?document.querySelector(e):e;t&&t instanceof HTMLElement&&t.hasAttribute(`ax-query`)&&M(t)}on(e,t){document.addEventListener(`atmx:${e}`,t)}setAuthToken(e,t,n){m(e,t,n)}clearAuthToken(e,t){h(e,t)}};typeof window<`u`&&(window.atmx=H),e.ATMX_VERSION=V,e.atmx=H});
887
+ `);for(let t of e)if(t.startsWith(n+`:`)){r=t.substring(n.length+1).trim();break}}r?(e.textContent=r,e.removeAttribute(`hidden`),e.style.removeProperty(`display`)):(e.setAttribute(`hidden`,``),e.style.setProperty(`display`,`none`,`important`))}Array.from(e.attributes).forEach(n=>{if(n.name.startsWith(`ax-bind:`)){let i=n.name.substring(8),a=g(n.value,t,r);a===!1||a==null?e.removeAttribute(i):e.setAttribute(i,a===!0?i:String(a))}}),Array.from(e.children).forEach(e=>{y(e,t,!1,r)})}}function b(e,t,n){e.style.display=`none`,e.hasAttribute(`data-ax-for-id`)||e.setAttribute(`data-ax-for-id`,Math.random().toString(36).substr(2,9));let r=e.getAttribute(`data-ax-for-id`),i=e.getAttribute(`ax-for`).match(/^\s*(?:(?:\(\s*([\w\$]+)\s*,\s*([\w\$]+)\s*\))|([\w\$]+))\s+in\s+(.+)$/);if(!i)return;let a=i[1]||i[3],o=i[2],s=i[4],c=g(s,t,n),l=e.parentElement;if(!l)return;let u=Array.from(l.querySelectorAll(`[data-ax-clone-of="${r}"]`));if(!c||!Array.isArray(c)){u.forEach(e=>e.remove());return}let d=e.getAttribute(`ax-key`),f=[];c.forEach((i,s)=>{let c={...n,[a]:i};o&&(c[o]=s);let p=String(s);d&&(p=String(g(d,t,c)));let m=u.find(e=>e.getAttribute(`data-ax-key`)===p);m||(m=e.cloneNode(!0),m.removeAttribute(`ax-for`),m.style.removeProperty(`display`),m.style.length===0&&m.removeAttribute(`style`),m.setAttribute(`data-ax-clone-of`,r),m.setAttribute(`data-ax-key`,p)),l.insertBefore(m,e),y(m,t,!1,c),f.push(m)}),u.forEach(e=>{f.includes(e)||e.remove()})}var x=new WeakMap;function S(e){return x.has(e)||x.set(e,{state:`idle`,isFetching:!1,isMutating:!1,source:null,data:null,error:null}),x.get(e)}function C(e){let t=e.parentElement;for(;t;){if(t.hasAttribute(`ax-query`)||t.hasAttribute(`ax-mutate`)){let e=x.get(t);if(e&&e.data)return e.data}t=t.parentElement}return{}}function w(e,t){let n=S(e);Object.assign(n,t),t.state===`loading`&&(n.isFetching=!0),t.state===`mutating`&&(n.isMutating=!0),(t.state===`success`||t.state===`data`&&t.isFetching===!1)&&(n.isFetching=!1,n.isMutating=!1),x.set(e,n),v(e,n)}var T=0,E=class{key;route;args;state;listeners=new Set;currentReqId=null;constructor(e,t,n){this.key=e,this.route=t,this.args=n,this.state={state:`idle`,isFetching:!1,source:null,data:null,error:null}}subscribe(e){this.listeners.add(e),e(this.state)}update(e){this.state={...this.state,...e},this.listeners.forEach(e=>e(this.state))}fetch(e=!1){if(this.state.isFetching&&!e)return;this.update({state:this.state.data?`data`:`loading`,isFetching:!0,error:null});let r=++T;this.currentReqId=r;let{path:i,remainingArgs:a}=s(this.route,this.args),o=new Uint8Array;Object.keys(a).length>0&&(o=new TextEncoder().encode(JSON.stringify(a))),H.debug&&(console.groupCollapsed(`%c➔ WASM QUERY [#${r}]`,`color: #7c3aed; font-weight: bold;`),console.log(`Namespace:`,this.route.namespace),console.log(`Endpoint ID:`,this.route.id),console.log(`Path:`,i),console.groupEnd()),n.set(r,{isStream:this.route.isStream,onResponse:e=>{if(this.currentReqId===r){if(H.debug){let t=e.eventType===1?`NetworkSuccess`:e.eventType===2?`CacheHit`:e.eventType===3?`CacheHitAndFetching`:e.eventType===4?`Error`:`Complete`;console.groupCollapsed(`%c← WASM RESP [#${r}]`,`color: #059669; font-weight: bold;`),console.log(`Event Type:`,t),e.data&&console.log(`Data:`,e.data),e.error&&console.log(`Error:`,e.error),console.groupEnd()}if(e.eventType===t.Error){this.update({state:`error`,error:e.error,isFetching:!1});return}if(e.data){let n=`network`,r=!1;e.eventType===t.CacheHit?(n=`cache`,r=!1):e.eventType===t.CacheHitAndFetching?(n=`cache`,r=!0):e.eventType===t.NetworkSuccess&&(n=`network`,r=!1),this.update({state:`data`,data:e.data,source:n,isFetching:r})}}},onComplete:()=>{this.currentReqId===r&&(H.debug&&console.log(`%c✔ Stream Complete [#${r}]`,`color: #94a3b8;`),this.update({isFetching:!1}))}});let c=d(this.route.namespace),f=d(this.route.method),p=d(i),m=u(o),h=d(``),g=d(``);l.axiom_wasm_call(r,c.ptr,c.len,this.route.id,f.ptr,f.len,p.ptr,p.len,h.ptr,h.len,g.ptr,g.len,m,o.length),l.axiom_free_memory(c.ptr,c.len),l.axiom_free_memory(f.ptr,f.len),l.axiom_free_memory(p.ptr,p.len),l.axiom_free_memory(h.ptr,h.len),l.axiom_free_memory(g.ptr,g.len)}},D=new Map,O=0;function k(e,t){let n=`ax-on:${t}`;e.hasAttribute(n)&&_(e.getAttribute(n),S(e))}function A(e,t,n){if(!H.debug)return;let r=e===`OUT`?`#7c3aed`:`#059669`;console.groupCollapsed(`%c${e===`OUT`?`➔ WASM CALL`:`← WASM RESP`} [#${t}]`,`color: ${r}; font-weight: bold;`),console.log(`Details:`,n),console.groupEnd()}function j(e,t){let n=t.trim().match(/^([\w\.]+)(?:\((.*)\))?$/);if(!n)return null;let r=n[1],i={};if(n[2]&&n[2].trim()!==``)try{let t=S(e),r=t.data||C(e);i=Function(`$data`,`$state`,`return (${n[2]});`)(r,t)||{}}catch(e){console.error(`ATMX Scope Error in "${t}":`,e)}return{target:r,args:i}}function M(e){let t=e.getAttribute(`ax-query`);if(!t)return;let n=j(e,t);if(!n)return;let r=o(n.target);if(!r){w(e,{state:`error`,error:{message:`Route not found: ${n.target}`}});return}let i=`${r.namespace}:${r.id}:${JSON.stringify(n.args)}`,a=D.get(i);a||(a=new E(i,r,n.args),D.set(i,a)),e._axListener||(e._axListener=t=>{w(e,t),(t.state===`data`||t.state===`error`)&&(k(e,t.state),e.dispatchEvent(new CustomEvent(`atmx:${t.state}`,{bubbles:!0,detail:t.data||t.error})))},a.subscribe(e._axListener)),a.fetch()}function N(e){let t=e.getAttribute(`ax-mutate`);if(!t)return;let n=j(e,t);if(!n)return;let r=o(n.target);if(!r){w(e,{state:`error`,error:{message:`Route not found: ${n.target}`}}),k(e,`error`);return}w(e,{state:`mutating`,error:null,data:null}),k(e,`mutating`);let i={};e instanceof HTMLFormElement&&new FormData(e).forEach((t,n)=>{let r=e.elements.namedItem(n),a=!1;r instanceof HTMLInputElement?a=r.type===`number`:r instanceof RadioNodeList&&r.length>0&&(a=r[0].type===`number`);let o=a&&t!==``?Number(t):t;if(n.includes(`.`)){let e=n.split(`.`),t=i;for(let n=0;n<e.length-1;n++)t[e[n]]||(t[e[n]]={}),t=t[e[n]];t[e[e.length-1]]=o}else i[n]=o});let{path:a,remainingArgs:c}=s(r,{...i,...n.args}),l=c;r.bodyParam&&c[r.bodyParam]!==void 0&&(l=c[r.bodyParam]);let u={},d=e.getAttribute(`ax-headers`);if(d)try{u=Function(`return (`+d+`);`)()||{}}catch(e){console.error(`ATMX: Invalid ax-headers syntax`,e)}let f=Object.entries(u).some(([e,t])=>e.toLowerCase()===`content-type`&&t.includes(`application/x-www-form-urlencoded`)),p=new Uint8Array;if(Object.keys(l).length>0)if(f){let e=new URLSearchParams;for(let[t,n]of Object.entries(l))e.append(t,String(n));p=new TextEncoder().encode(e.toString())}else p=new TextEncoder().encode(JSON.stringify(l));P(e,r.namespace,r.id,r.method,a,p,r.isStream,!0,u,f)}function P(e,t,r,i,a,o,s,c,f={},p=!1){let m=++O;A(`OUT`,m,{namespace:t,endpointId:r,method:i,path:a,headers:f,payload:o.length>0?p?new TextDecoder().decode(o):JSON.parse(new TextDecoder().decode(o)):null}),n.set(m,{isStream:s,onResponse:t=>F(e,t,c,m),onComplete:()=>{H.debug&&console.log(`%c✔ Stream Complete [#${m}]`,`color: #94a3b8;`)}});let h=d(t),g=d(i),_=d(a),v=d(``),y=d(Object.keys(f).length>0?JSON.stringify(f):``),b=u(o);l.axiom_wasm_call(m,h.ptr,h.len,r,g.ptr,g.len,_.ptr,_.len,v.ptr,v.len,y.ptr,y.len,b,o.length),l.axiom_free_memory(h.ptr,h.len),l.axiom_free_memory(g.ptr,g.len),l.axiom_free_memory(_.ptr,_.len),l.axiom_free_memory(v.ptr,v.len),l.axiom_free_memory(y.ptr,y.len),b&&l.axiom_free_memory(b,o.length)}function F(e,n,r,i){if(A(`IN`,i,{eventType:t[n.eventType],data:n.data,error:n.error}),n.eventType===t.Error){w(e,{state:`error`,error:n.error,isFetching:!1,isMutating:!1}),k(e,`error`),e.dispatchEvent(new CustomEvent(`atmx:error`,{bubbles:!0,detail:n.error}));return}if(n.data){let i=`network`,a=!1;n.eventType===t.CacheHit?i=`cache`:n.eventType===t.CacheHitAndFetching?(i=`cache`,a=!0):n.eventType===t.NetworkSuccess&&(i=`network`);let s=r?`success`:`data`;if(w(e,{state:s,data:n.data,source:i,isFetching:a,isMutating:!1}),r){let t=e.getAttribute(`ax-store-token`);if(t){let n=g(t,S(e));if(n){let t=o(j(e,e.getAttribute(`ax-mutate`)).target),r=e.getAttribute(`ax-token-header`)||`Authorization`;H.setAuthToken(t?.namespace||`default`,r,n)}}if(e.hasAttribute(`ax-clear-token`)){let t=o(j(e,e.getAttribute(`ax-mutate`)).target),n=e.getAttribute(`ax-token-header`)||`Authorization`;H.clearAuthToken(t?.namespace||`default`,n)}let n=e.getAttribute(`ax-refresh`);if(n){let e=n.split(`,`).map(e=>e.trim());for(let[t,n]of D.entries()){let t=`${n.route.namespace}.${n.route.name}`;e.includes(t)&&n.fetch(!0)}}}k(e,s),e.dispatchEvent(new CustomEvent(r?`atmx:success`:`atmx:data`,{bubbles:!0,detail:n.data}))}}var I=new IntersectionObserver(e=>{e.forEach(e=>{if(e.isIntersecting){let t=e.target;t.hasAttribute(`ax-query`)&&M(t),I.unobserve(t)}})});function L(e){e.querySelectorAll(`[\\:ax-query], [\\:ax-mutate]`).forEach(e=>{if(e.hasAttribute(`:ax-query`)){let t=g(e.getAttribute(`:ax-query`),S(e));t&&e.setAttribute(`ax-query`,String(t)),e.removeAttribute(`:ax-query`)}if(e.hasAttribute(`:ax-mutate`)){let t=g(e.getAttribute(`:ax-mutate`),S(e));t&&e.setAttribute(`ax-mutate`,String(t)),e.removeAttribute(`:ax-mutate`)}})}function R(e=document){L(e),e.querySelectorAll(`[ax-query]`).forEach(e=>{let t=e;w(t,{});let n=t.getAttribute(`ax-trigger`)||`load`;n===`load`?M(t):n===`intersect`?I.observe(t):t.addEventListener(n,e=>{e.preventDefault(),M(t)})}),e.querySelectorAll(`[ax-mutate]`).forEach(e=>{let t=e;w(t,{});let n=t.tagName===`FORM`?`submit`:`click`;t.addEventListener(n,e=>{(t.tagName===`A`||t.tagName===`BUTTON`||t.tagName===`FORM`)&&e.preventDefault(),N(t)})}),e.querySelectorAll(`[ax-trigger="refresh"]`).forEach(e=>{let t=e;t.addEventListener(`click`,e=>{e.preventDefault();let n=t.closest(`[ax-query]`);if(n){let e=j(n,n.getAttribute(`ax-query`));if(e){let t=o(e.target);if(t){let r=`${t.namespace}:${t.id}:${JSON.stringify(e.args)}`,i=D.get(r);i?i.fetch(!0):M(n)}}}})})}function z(){new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e instanceof HTMLElement&&R(e)})})}).observe(document.body,{childList:!0,subtree:!0})}var B=class extends HTMLElement{constructor(){super()}connectedCallback(){let e=this.getAttribute(`loading-text`)||`Initializing...`,t=this.getAttribute(`ready-text`)||`Online`,n=this.getAttribute(`error-text`)||`Failed to Connect`;this.renderState(`loading`,e,`text-amber-500 animate-pulse`),document.addEventListener(`atmx:ready`,()=>{this.renderState(`ready`,t,`text-green-600`)}),document.addEventListener(`atmx:error`,e=>{let t=e;t.detail&&t.detail.stage===`runtime`&&this.renderState(`error`,`${n}: ${t.detail.message}`,`text-red-600`)})}renderState(e,t,n){this.setAttribute(`data-state`,e);let r=this.querySelectorAll(`[data-ax-when]`);r.length>0?r.forEach(t=>{t.getAttribute(`data-ax-when`)===e?t.removeAttribute(`hidden`):t.setAttribute(`hidden`,``)}):(this.innerText=t,this.getAttribute(`class`)||(this.className=`text-xs font-bold ${n}`))}};typeof window<`u`&&!customElements.get(`ax-engine-status`)&&customElements.define(`ax-engine-status`,B);var V=`0.47.0`,H=new class{version=V;initialized=!1;debug=!1;async init(e){if(this.initialized)return{ok:!0,contracts:{},initDurationMs:0};let t=await p(e);return t.ok?(this.debug=e.debug||!1,z(),R(document.body),this.initialized=!0,this.debug&&console.log(`%c🚀 ATMX Debug Mode: Enabled`,`color: #2563eb; font-weight: bold;`),console.log(`✅ ATMX v${this.version} Online (${t.initDurationMs}ms). Reactive Engine Started.`),document.dispatchEvent(new CustomEvent(`atmx:ready`,{detail:t}))):(console.error(`❌ ATMX Initialization Failed:`,t.error),document.dispatchEvent(new CustomEvent(`atmx:error`,{detail:t.error}))),t}triggerQuery(e){let t=typeof e==`string`?document.querySelector(e):e;t&&t instanceof HTMLElement&&t.hasAttribute(`ax-query`)&&M(t)}on(e,t){document.addEventListener(`atmx:${e}`,t)}setAuthToken(e,t,n){m(e,t,n)}clearAuthToken(e,t){h(e,t)}};typeof window<`u`&&(window.atmx=H),e.ATMX_VERSION=V,e.allocBytes=u,e.allocString=d,e.atmx=H,e.buildRequestPath=s,e.clearAuthToken=h,e.initWasm=p,e.pendingRequests=n,e.resolveRoute=o,e.setAuthToken=m,Object.defineProperty(e,`wasmEngine`,{enumerable:!0,get:function(){return l}})});
@@ -0,0 +1,7 @@
1
+ import { AxiomResponse } from './types';
2
+ export declare const pendingRequests: Map<number, {
3
+ isStream: boolean;
4
+ onResponse: (res: AxiomResponse) => void;
5
+ onComplete: () => void;
6
+ }>;
7
+ export declare function setupWebCallback(wasm: any): void;
@@ -0,0 +1,16 @@
1
+ export type AtmxState = 'idle' | 'loading' | 'mutating' | 'data' | 'success' | 'error';
2
+ export interface AtmxContextData {
3
+ state: AtmxState;
4
+ isFetching: boolean;
5
+ isMutating: boolean;
6
+ source: 'cache' | 'network' | null;
7
+ data: any;
8
+ error: any;
9
+ }
10
+ export declare function getContext(element: HTMLElement): AtmxContextData;
11
+ /**
12
+ * NEW: Recursively finds the nearest parent context that has actual data.
13
+ * This allows nested buttons to access $data from their parent queries.
14
+ */
15
+ export declare function getClosestData(element: HTMLElement): any;
16
+ export declare function updateContext(element: HTMLElement, updates: Partial<AtmxContextData>): void;
@@ -0,0 +1,17 @@
1
+ import { Route } from './router';
2
+ import { AtmxContextData } from './context';
3
+ type Listener = (state: Partial<AtmxContextData>) => void;
4
+ export declare class ActiveQuery {
5
+ key: string;
6
+ route: Route;
7
+ args: Record<string, any>;
8
+ state: Partial<AtmxContextData>;
9
+ listeners: Set<Listener>;
10
+ currentReqId: number | null;
11
+ constructor(key: string, route: Route, args: Record<string, any>);
12
+ subscribe(listener: Listener): void;
13
+ update(newState: Partial<AtmxContextData>): void;
14
+ fetch(force?: boolean): void;
15
+ }
16
+ export declare const queryRegistry: Map<string, ActiveQuery>;
17
+ export {};
@@ -0,0 +1,20 @@
1
+ export interface RouteAuth {
2
+ required: boolean;
3
+ methods: any[];
4
+ }
5
+ export interface Route {
6
+ id: number;
7
+ namespace: string;
8
+ name: string;
9
+ method: string;
10
+ pathTemplate: string;
11
+ isStream: boolean;
12
+ auth?: RouteAuth | null;
13
+ bodyParam?: string | null;
14
+ }
15
+ export declare function initRouter(namespace: string, contractJson: any): void;
16
+ export declare function resolveRoute(rpcCall: string): Route | null;
17
+ export declare function buildRequestPath(route: Route, args: Record<string, any>): {
18
+ path: string;
19
+ remainingArgs: Record<string, any>;
20
+ };
@@ -0,0 +1,44 @@
1
+ export interface AtmxContractConfig {
2
+ contractUrl: string;
3
+ baseUrl: string;
4
+ }
5
+ export interface AtmxConfig {
6
+ contracts: Record<string, AtmxContractConfig>;
7
+ debug?: boolean;
8
+ }
9
+ export declare enum EventType {
10
+ Complete = 0,
11
+ NetworkSuccess = 1,
12
+ CacheHit = 2,
13
+ CacheHitAndFetching = 3,
14
+ Error = 4
15
+ }
16
+ export interface AxiomError {
17
+ stage: string;
18
+ category: string;
19
+ code: string | Record<string, any>;
20
+ message: string;
21
+ retryable: boolean;
22
+ details?: string;
23
+ }
24
+ export interface AxiomResponse {
25
+ eventType: EventType;
26
+ data?: any;
27
+ error?: AxiomError;
28
+ isFetching?: boolean;
29
+ isStreamChunk?: boolean;
30
+ }
31
+ export interface InitResult {
32
+ ok: boolean;
33
+ error?: AxiomError;
34
+ contracts: Record<string, {
35
+ loaded: boolean;
36
+ endpointCount: number;
37
+ error?: string;
38
+ }>;
39
+ initDurationMs: number;
40
+ }
41
+ export interface ContractLoadedEvent {
42
+ namespace: string;
43
+ endpointCount: number;
44
+ }
@@ -0,0 +1,11 @@
1
+ import { AtmxConfig } from '../core/types';
2
+ import { InitResult } from './types';
3
+ export declare let wasmEngine: any;
4
+ export declare function allocBytes(bytes: Uint8Array): number;
5
+ export declare function allocString(str: string): {
6
+ ptr: number;
7
+ len: number;
8
+ };
9
+ export declare function initWasm(config: AtmxConfig): Promise<InitResult>;
10
+ export declare function setAuthToken(namespace: string, methodName: string, token: string): void;
11
+ export declare function clearAuthToken(namespace: string, methodName: string): void;
@@ -0,0 +1,5 @@
1
+ export declare class AxEngineStatusElement extends HTMLElement {
2
+ constructor();
3
+ connectedCallback(): void;
4
+ private renderState;
5
+ }
@@ -0,0 +1,2 @@
1
+ export declare function startRequest(reqId: number, triggerEl: HTMLElement): void;
2
+ export declare function endRequest(reqId: number): void;
@@ -0,0 +1,6 @@
1
+ export declare function parseRpcCall(element: HTMLElement, attrValue: string): {
2
+ target: string;
3
+ args: Record<string, any>;
4
+ } | null;
5
+ export declare function connectQuery(element: HTMLElement): void;
6
+ export declare function executeMutation(element: HTMLElement): void;
@@ -0,0 +1,2 @@
1
+ export declare function scanAndInitialize(root?: HTMLElement | Document): void;
2
+ export declare function initMutationObserver(): void;
@@ -0,0 +1,18 @@
1
+ import { AtmxConfig, InitResult } from './core/types';
2
+ export declare const ATMX_VERSION = "0.47.0";
3
+ declare class ATMX {
4
+ version: string;
5
+ initialized: boolean;
6
+ debug: boolean;
7
+ init(config: AtmxConfig): Promise<InitResult>;
8
+ triggerQuery(elementOrSelector: string | HTMLElement): void;
9
+ on(eventName: "ready" | "data" | "error" | "success" | "contract-loaded", callback: (e: any) => void): void;
10
+ setAuthToken(namespace: string, methodName: string, token: string): void;
11
+ clearAuthToken(namespace: string, methodName: string): void;
12
+ }
13
+ export declare const atmx: ATMX;
14
+ export { initWasm, wasmEngine, allocBytes, allocString, setAuthToken, clearAuthToken, } from './core/wasm';
15
+ export { resolveRoute, buildRequestPath } from './core/router';
16
+ export type { Route } from './core/router';
17
+ export { pendingRequests } from './core/callback';
18
+ export type { AtmxConfig, AxiomResponse, AxiomError, EventType, } from './core/types';
@@ -0,0 +1,6 @@
1
+ import { AtmxContextData } from '../core/context';
2
+ /**
3
+ * Safely evaluates a JS expression from an HTML attribute against the local ATMX Context.
4
+ */
5
+ export declare function evaluateExpression(expr: string, context: AtmxContextData, locals?: Record<string, any>): any;
6
+ export declare function executeAction(expr: string, context: AtmxContextData, locals?: Record<string, any>): void;
@@ -0,0 +1,2 @@
1
+ import { AtmxContextData } from '../core/context';
2
+ export declare function renderContext(rootEl: HTMLElement, context: AtmxContextData): void;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "files": [
4
4
  "dist"
5
5
  ],
6
- "version": "0.46.0",
6
+ "version": "0.47.0",
7
7
  "description": "Axiom ATMX Core Runtime for Vanilla Web",
8
8
  "type": "module",
9
9
  "main": "./dist/atmx.umd.js",
@@ -17,6 +17,7 @@
17
17
  "devDependencies": {
18
18
  "tslib": "^2.8.1",
19
19
  "typescript": "^5.9.3",
20
- "vite": "^8.0.0"
20
+ "vite": "^8.0.0",
21
+ "vite-plugin-dts": "^5.0.0"
21
22
  }
22
23
  }