atmx-web 0.44.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.
@@ -1,4 +1,4 @@
1
- let wasm_bindgen = (function(exports) {
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.atmx={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=function(e){return e[e.Complete=0]=`Complete`,e[e.NetworkSuccess=1]=`NetworkSuccess`,e[e.CacheHit=2]=`CacheHit`,e[e.CacheHitAndFetching=3]=`CacheHitAndFetching`,e[e.Error=4]=`Error`,e}({}),n=new Map;function r(e){window.axiom_web_callback=(r,i,a,o,s,c,l)=>{let u=n.get(r);if(!u){o&&e.axiom_free_memory(o,s),c&&e.axiom_free_memory(c,l);return}let d=null,f=null;if(o!==0&&s>0){let t=new Uint8Array(e.memory.buffer);d=new Uint8Array(t.subarray(o,o+s)),e.axiom_free_memory(o,s)}if(c!==0&&l>0){let t=new Uint8Array(e.memory.buffer),n=new Uint8Array(t.subarray(c,c+l));f=new TextDecoder().decode(n),e.axiom_free_memory(c,l)}if(i===t.Complete){u.onComplete(),n.delete(r);return}if(i===t.Error){let e;if(f)try{e=JSON.parse(f)}catch(t){e={stage:`ffiBoundary`,category:`runtime`,code:`JsonParseFailure`,message:`Parse failed: ${t}`,retryable:!1}}else e={stage:`runtime`,category:`unknown`,code:a.toString(),message:`Internal Wasm error`,retryable:!1};u.onResponse({eventType:i,error:e}),u.onComplete(),n.delete(r);return}if(d)try{let e=new TextDecoder().decode(d),a=JSON.parse(e);u.onResponse({eventType:i,data:a,isFetching:i===t.CacheHitAndFetching,isStreamChunk:u.isStream}),!u.isStream&&i===t.NetworkSuccess&&(u.onComplete(),n.delete(r))}catch(e){console.error(`ATMX: Failed to parse JSON response from Axiom`,e)}}}var i=new Map;function a(e,t){let n=t?.ir?.endpoints;if(!n)return;let r=Array.isArray(n)?n:Object.values(n);r.forEach(t=>{let n=`${e}.${t.name}`,r=t.parameters?.find(e=>e.source===`body`)?.name||null;i.set(n,{id:t.id,namespace:e,name:t.name,method:t.method?t.method.toUpperCase():`GET`,pathTemplate:t.path,isStream:t.isStream||!1,auth:t.auth||null,bodyParam:r})}),console.log(`🛣️ ATMX Router: Mapped ${r.length} endpoints for '${e}'.`)}function o(e){return i.get(e.trim())||null}function s(e,t){let n=e.pathTemplate,r={...t},i=n.match(/\{([^}]+)\}/g);if(i&&i.forEach(e=>{let t=e.replace(/[{}]/g,``);r[t]!==void 0&&(n=n.replace(e,encodeURIComponent(String(r[t]))),delete r[t])}),e.method===`GET`&&Object.keys(r).length>0){let e=new URLSearchParams;for(let[t,n]of Object.entries(r))n!=null&&e.append(t,String(n));let t=n.includes(`?`)?`&`:`?`;n+=`${t}${e.toString()}`;for(let e of Object.keys(r))delete r[e]}return{path:n,remainingArgs:r}}var c=`let wasm_bindgen = (function(exports) {
2
2
  let script_src;
3
3
  if (typeof document !== 'undefined' && document.currentScript !== null) {
4
4
  script_src = new URL(document.currentScript.src, location.href).toString();
@@ -492,32 +492,32 @@ let wasm_bindgen = (function(exports) {
492
492
  return addHeapObject(ret);
493
493
  },
494
494
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
495
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 198, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
495
+ // Cast intrinsic for \`Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 198, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref\`.
496
496
  const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2406);
497
497
  return addHeapObject(ret);
498
498
  },
499
499
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
500
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 62, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
500
+ // Cast intrinsic for \`Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 62, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref\`.
501
501
  const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2239);
502
502
  return addHeapObject(ret);
503
503
  },
504
504
  __wbindgen_cast_0000000000000003: function(arg0, arg1) {
505
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 62, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
505
+ // Cast intrinsic for \`Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 62, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref\`.
506
506
  const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2239_2);
507
507
  return addHeapObject(ret);
508
508
  },
509
509
  __wbindgen_cast_0000000000000004: function(arg0, arg1) {
510
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 111, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
510
+ // Cast intrinsic for \`Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 111, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref\`.
511
511
  const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2246);
512
512
  return addHeapObject(ret);
513
513
  },
514
514
  __wbindgen_cast_0000000000000005: function(arg0, arg1) {
515
- // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
515
+ // Cast intrinsic for \`Ref(Slice(U8)) -> NamedExternref("Uint8Array")\`.
516
516
  const ret = getArrayU8FromWasm0(arg0, arg1);
517
517
  return addHeapObject(ret);
518
518
  },
519
519
  __wbindgen_cast_0000000000000006: function(arg0, arg1) {
520
- // Cast intrinsic for `Ref(String) -> Externref`.
520
+ // Cast intrinsic for \`Ref(String) -> Externref\`.
521
521
  const ret = getStringFromWasm0(arg0, arg1);
522
522
  return addHeapObject(ret);
523
523
  },
@@ -587,23 +587,23 @@ let wasm_bindgen = (function(exports) {
587
587
  // primitive types
588
588
  const type = typeof val;
589
589
  if (type == 'number' || type == 'boolean' || val == null) {
590
- return `${val}`;
590
+ return \`\${val}\`;
591
591
  }
592
592
  if (type == 'string') {
593
- return `"${val}"`;
593
+ return \`"\${val}"\`;
594
594
  }
595
595
  if (type == 'symbol') {
596
596
  const description = val.description;
597
597
  if (description == null) {
598
598
  return 'Symbol';
599
599
  } else {
600
- return `Symbol(${description})`;
600
+ return \`Symbol(\${description})\`;
601
601
  }
602
602
  }
603
603
  if (type == 'function') {
604
604
  const name = val.name;
605
605
  if (typeof name == 'string' && name.length > 0) {
606
- return `Function(${name})`;
606
+ return \`Function(\${name})\`;
607
607
  } else {
608
608
  return 'Function';
609
609
  }
@@ -622,7 +622,7 @@ let wasm_bindgen = (function(exports) {
622
622
  return debug;
623
623
  }
624
624
  // Test for built-in
625
- const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
625
+ const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));
626
626
  let className;
627
627
  if (builtInMatches && builtInMatches.length > 1) {
628
628
  className = builtInMatches[1];
@@ -633,7 +633,7 @@ let wasm_bindgen = (function(exports) {
633
633
  if (className == 'Object') {
634
634
  // we're a user defined class or Object
635
635
  // JSON.stringify avoids problems with cycles, and is generally much
636
- // easier than looping through ownProperties of `val`.
636
+ // easier than looping through ownProperties of \`val\`.
637
637
  try {
638
638
  return 'Object(' + JSON.stringify(val) + ')';
639
639
  } catch (_) {
@@ -642,9 +642,9 @@ let wasm_bindgen = (function(exports) {
642
642
  }
643
643
  // errors
644
644
  if (val instanceof Error) {
645
- return `${val.name}: ${val.message}\n${val.stack}`;
645
+ return \`\${val.name}: \${val.message}\\n\${val.stack}\`;
646
646
  }
647
- // TODO we could test for more things here, like `Set`s and `Map`s.
647
+ // TODO we could test for more things here, like \`Set\`s and \`Map\`s.
648
648
  return className;
649
649
  }
650
650
 
@@ -809,7 +809,7 @@ let wasm_bindgen = (function(exports) {
809
809
  const validResponse = module.ok && expectedResponseType(module.type);
810
810
 
811
811
  if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
812
- console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
812
+ console.warn("\`WebAssembly.instantiateStreaming\` failed because your server does not serve Wasm with \`application/wasm\` MIME type. Falling back to \`WebAssembly.instantiate\` which is slower. Original error:\\n", e);
813
813
 
814
814
  } else { throw e; }
815
815
  }
@@ -843,7 +843,7 @@ let wasm_bindgen = (function(exports) {
843
843
  if (Object.getPrototypeOf(module) === Object.prototype) {
844
844
  ({module} = module)
845
845
  } else {
846
- console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
846
+ console.warn('using deprecated parameters for \`initSync()\`; pass a single object instead')
847
847
  }
848
848
  }
849
849
 
@@ -868,7 +868,7 @@ let wasm_bindgen = (function(exports) {
868
868
  }
869
869
 
870
870
  if (module_or_path === undefined && script_src !== undefined) {
871
- module_or_path = script_src.replace(/\.js$/, "_bg.wasm");
871
+ module_or_path = script_src.replace(/\\.js$/, "_bg.wasm");
872
872
  }
873
873
  const imports = __wbg_get_imports();
874
874
 
@@ -883,3 +883,5 @@ let wasm_bindgen = (function(exports) {
883
883
 
884
884
  return Object.assign(__wbg_init, { initSync }, exports);
885
885
  })({ __proto__: null });
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`;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
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "atmx-web",
3
- "version": "0.44.0",
3
+ "files": [
4
+ "dist"
5
+ ],
6
+ "version": "0.47.0",
4
7
  "description": "Axiom ATMX Core Runtime for Vanilla Web",
5
8
  "type": "module",
6
9
  "main": "./dist/atmx.umd.js",
@@ -14,6 +17,7 @@
14
17
  "devDependencies": {
15
18
  "tslib": "^2.8.1",
16
19
  "typescript": "^5.9.3",
17
- "vite": "^8.0.0"
20
+ "vite": "^8.0.0",
21
+ "vite-plugin-dts": "^5.0.0"
18
22
  }
19
23
  }
package/justfile DELETED
@@ -1,8 +0,0 @@
1
- default:
2
- @just --list
3
-
4
- build:
5
- npm run build
6
-
7
- upload:
8
- ./scripts/upload.sh
package/scripts/upload.sh DELETED
@@ -1,61 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- # 1. Load credentials from .env
5
- if [ -f .env ]; then
6
- set -a
7
- source .env
8
- set +a
9
- else
10
- echo "❌ Error: .env file not found."
11
- exit 1
12
- fi
13
-
14
- if [ -z "$CLOUDFLARE_ACCOUNT_ID" ] || [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
15
- echo "❌ Error: Missing credentials in .env file."
16
- exit 1
17
- fi
18
-
19
- # 2. Setup Variables
20
- BUCKET_NAME="atmx"
21
- ENDPOINT="https://${CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com"
22
- DIST_DIR="./dist"
23
-
24
- # Grab the version directly from package.json (e.g., "0.1.0")
25
- VERSION=$(node -p "require('./package.json').version")
26
-
27
- # We will upload to a versioned folder (v0.1.0) AND a "latest" folder
28
- FOLDERS=("v$VERSION" "latest")
29
-
30
- echo "🚀 Starting Upload for ATMX v$VERSION to Cloudflare R2..."
31
-
32
- # 3. Upload loop
33
- for FOLDER in "${FOLDERS[@]}"; do
34
- echo "📁 Uploading to /$FOLDER/..."
35
-
36
- # Upload UMD JS (for <script> tags)
37
- aws s3 cp "$DIST_DIR/atmx.umd.js" "s3://$BUCKET_NAME/$FOLDER/atmx.umd.js" \
38
- --endpoint-url "$ENDPOINT" \
39
- --content-type "application/javascript" \
40
- --cache-control "max-age=3600" \
41
- --no-progress
42
-
43
- # Upload ES JS (for ES module imports)
44
- aws s3 cp "$DIST_DIR/atmx.es.js" "s3://$BUCKET_NAME/$FOLDER/atmx.es.js" \
45
- --endpoint-url "$ENDPOINT" \
46
- --content-type "application/javascript" \
47
- --cache-control "max-age=3600" \
48
- --no-progress
49
-
50
- # Upload WASM (CRITICAL: Sets the application/wasm content-type)
51
- aws s3 cp "$DIST_DIR/axiom_runtime.wasm" "s3://$BUCKET_NAME/$FOLDER/axiom_runtime.wasm" \
52
- --endpoint-url "$ENDPOINT" \
53
- --content-type "application/wasm" \
54
- --cache-control "max-age=3600" \
55
- --no-progress
56
- done
57
-
58
- echo "✅ Upload Complete!"
59
- echo "🌐 Your files are now available at:"
60
- echo " - https://atmx.axiomcore.dev/v$VERSION/atmx.umd.js"
61
- echo " - https://atmx.axiomcore.dev/latest/atmx.umd.js"
@@ -1,92 +0,0 @@
1
- // FILE: src/core/callback.ts
2
- import { EventType, AxiomError, AxiomResponse } from './types';
3
-
4
- // Store the active requests. We need to store a config object now, not just a callback function.
5
- export const pendingRequests = new Map<number, {
6
- isStream: boolean,
7
- onResponse: (res: AxiomResponse) => void,
8
- onComplete: () => void
9
- }>();
10
-
11
- export function setupWebCallback(wasm: any) {
12
- (window as any).axiom_web_callback = (
13
- reqId: number, eventType: number, errorCode: number,
14
- dataPtr: number, dataLen: number, errPtr: number, errLen: number
15
- ) => {
16
- const handler = pendingRequests.get(reqId);
17
- if (!handler) {
18
- // Memory must be freed even if JS abandoned the request!
19
- if (dataPtr) wasm.axiom_free_memory(dataPtr, dataLen);
20
- if (errPtr) wasm.axiom_free_memory(errPtr, errLen);
21
- return;
22
- }
23
-
24
- let dataBytes: Uint8Array | null = null;
25
- let errorJson: string | null = null;
26
-
27
- // 1. Read Payload Memory
28
- if (dataPtr !== 0 && dataLen > 0) {
29
- const memory = new Uint8Array(wasm.memory.buffer);
30
- dataBytes = new Uint8Array(memory.subarray(dataPtr, dataPtr + dataLen));
31
- wasm.axiom_free_memory(dataPtr, dataLen);
32
- }
33
-
34
- // 2. Read Error Memory
35
- if (errPtr !== 0 && errLen > 0) {
36
- const memory = new Uint8Array(wasm.memory.buffer);
37
- const errBytes = new Uint8Array(memory.subarray(errPtr, errPtr + errLen));
38
- errorJson = new TextDecoder().decode(errBytes);
39
- wasm.axiom_free_memory(errPtr, errLen);
40
- }
41
-
42
- // 3. Handle Completion Signal
43
- if (eventType === EventType.Complete) {
44
- handler.onComplete();
45
- pendingRequests.delete(reqId);
46
- return;
47
- }
48
-
49
- // 4. Handle Errors
50
- if (eventType === EventType.Error) {
51
- let richError: AxiomError;
52
- if (errorJson) {
53
- try { richError = JSON.parse(errorJson); }
54
- catch (e) { richError = { stage: 'ffiBoundary', category: 'runtime', code: 'JsonParseFailure', message: `Parse failed: ${e}`, retryable: false }; }
55
- } else {
56
- richError = { stage: 'runtime', category: 'unknown', code: errorCode.toString(), message: 'Internal Wasm error', retryable: false };
57
- }
58
-
59
- handler.onResponse({ eventType, error: richError });
60
-
61
- // Clean up the request on a fatal error
62
- handler.onComplete();
63
- pendingRequests.delete(reqId);
64
- return;
65
- }
66
-
67
- // 5. Handle Data (Success, Cache, or Stream Chunk)
68
- if (dataBytes) {
69
- try {
70
- const jsonString = new TextDecoder().decode(dataBytes);
71
- const jsonData = JSON.parse(jsonString);
72
-
73
- // Pass the data up to the Reactive Engine
74
- handler.onResponse({
75
- eventType,
76
- data: jsonData,
77
- isFetching: eventType === EventType.CacheHitAndFetching,
78
- isStreamChunk: handler.isStream
79
- });
80
-
81
- // If it's NOT a stream, a NetworkSuccess means the request is fully complete.
82
- if (!handler.isStream && eventType === EventType.NetworkSuccess) {
83
- handler.onComplete();
84
- pendingRequests.delete(reqId);
85
- }
86
-
87
- } catch (e) {
88
- console.error("ATMX: Failed to parse JSON response from Axiom", e);
89
- }
90
- }
91
- };
92
- }
@@ -1,56 +0,0 @@
1
- // FILE: src/core/context.ts
2
- import { renderContext } from '../resolver/render';
3
-
4
- export type AtmxState = 'idle' | 'loading' | 'mutating' | 'data' | 'success' | 'error';
5
-
6
- export interface AtmxContextData {
7
- state: AtmxState;
8
- isFetching: boolean;
9
- isMutating: boolean;
10
- source: 'cache' | 'network' | null;
11
- data: any;
12
- error: any;
13
- }
14
-
15
- const contextRegistry = new WeakMap<HTMLElement, AtmxContextData>();
16
-
17
- export function getContext(element: HTMLElement): AtmxContextData {
18
- if (!contextRegistry.has(element)) {
19
- contextRegistry.set(element, {
20
- state: 'idle', isFetching: false, isMutating: false,
21
- source: null, data: null, error: null
22
- });
23
- }
24
- return contextRegistry.get(element)!;
25
- }
26
-
27
- /**
28
- * NEW: Recursively finds the nearest parent context that has actual data.
29
- * This allows nested buttons to access $data from their parent queries.
30
- */
31
- export function getClosestData(element: HTMLElement): any {
32
- let current: HTMLElement | null = element.parentElement;
33
- while (current) {
34
- if (current.hasAttribute('ax-query') || current.hasAttribute('ax-mutate')) {
35
- const ctx = contextRegistry.get(current);
36
- if (ctx && ctx.data) return ctx.data;
37
- }
38
- current = current.parentElement;
39
- }
40
- return {}; // Return empty object if no parent data found
41
- }
42
-
43
- export function updateContext(element: HTMLElement, updates: Partial<AtmxContextData>) {
44
- const current = getContext(element);
45
- Object.assign(current, updates);
46
-
47
- if (updates.state === 'loading') current.isFetching = true;
48
- if (updates.state === 'mutating') current.isMutating = true;
49
- if (updates.state === 'success' || (updates.state === 'data' && updates.isFetching === false)) {
50
- current.isFetching = false;
51
- current.isMutating = false;
52
- }
53
-
54
- contextRegistry.set(element, current);
55
- renderContext(element, current);
56
- }