atmx-web 0.44.0 → 0.46.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/src/core/types.ts DELETED
@@ -1,49 +0,0 @@
1
- export interface AtmxContractConfig {
2
- contractUrl: string;
3
- baseUrl: string;
4
- }
5
-
6
- export interface AtmxConfig {
7
- contracts: Record<string, AtmxContractConfig>;
8
- debug?: boolean; // Enable verbose logging
9
- }
10
-
11
- export enum EventType {
12
- Complete = 0,
13
- NetworkSuccess = 1,
14
- CacheHit = 2,
15
- CacheHitAndFetching = 3,
16
- Error = 4,
17
- }
18
-
19
- export interface AxiomError {
20
- stage: string;
21
- category: string;
22
- code: string | Record<string, any>;
23
- message: string;
24
- retryable: boolean;
25
- details?: string;
26
- }
27
-
28
- export interface AxiomResponse {
29
- eventType: EventType;
30
- data?: any;
31
- error?: AxiomError;
32
- isFetching?: boolean;
33
- isStreamChunk?: boolean;
34
- }
35
-
36
- export interface InitResult {
37
- ok: boolean;
38
- error?: AxiomError;
39
- contracts: Record<
40
- string,
41
- { loaded: boolean; endpointCount: number; error?: string }
42
- >;
43
- initDurationMs: number;
44
- }
45
-
46
- export interface ContractLoadedEvent {
47
- namespace: string;
48
- endpointCount: number;
49
- }
package/src/core/wasm.ts DELETED
@@ -1,223 +0,0 @@
1
- // FILE: src/core/wasm.ts
2
- import { setupWebCallback } from "./callback";
3
- import { AtmxConfig } from "../core/types";
4
- import { initRouter } from "./router";
5
- import { InitResult } from "./types";
6
-
7
- // @ts-ignore
8
- import wasmGlueCode from "./vendor/axiom_runtime.js?raw";
9
-
10
- export let wasmEngine: any = null;
11
-
12
- export function allocBytes(bytes: Uint8Array): number {
13
- if (bytes.length === 0) return 0;
14
- const ptr = wasmEngine.axiom_malloc(bytes.length);
15
- const mem = new Uint8Array(wasmEngine.memory.buffer);
16
- mem.set(bytes, ptr);
17
- return ptr;
18
- }
19
-
20
- export function allocString(str: string): { ptr: number; len: number } {
21
- if (!str) return { ptr: 0, len: 0 };
22
- const bytes = new TextEncoder().encode(str);
23
- const ptr = allocBytes(bytes);
24
- return { ptr, len: bytes.length };
25
- }
26
-
27
- function getWasmUrl(): string {
28
- return "https://atmx.axiomcore.dev/latest/axiom_runtime.wasm";
29
- }
30
-
31
- export async function initWasm(config: AtmxConfig): Promise<InitResult> {
32
- const startTime = performance.now();
33
- const result: InitResult = {
34
- ok: false,
35
- contracts: {},
36
- initDurationMs: 0,
37
- };
38
-
39
- try {
40
- if (!(window as any).wasm_bindgen) {
41
- const script = document.createElement("script");
42
- script.type = "text/javascript";
43
- script.text = `${wasmGlueCode}\nwindow.wasm_bindgen = wasm_bindgen;`;
44
- document.head.appendChild(script);
45
- }
46
-
47
- const wasmBindgen = (window as any).wasm_bindgen;
48
- const wasmLocation = getWasmUrl();
49
- const fetchUrl = `${wasmLocation}?t=${Date.now()}`;
50
-
51
- try {
52
- wasmEngine = await wasmBindgen(fetch(fetchUrl));
53
- } catch (e: any) {
54
- throw {
55
- stage: "ffiBoundary",
56
- category: "network",
57
- code: "WasmFetchFailed",
58
- message: `Failed to download WASM engine: ${e.message}`,
59
- retryable: true,
60
- };
61
- }
62
-
63
- setupWebCallback(wasmEngine);
64
-
65
- setInterval(() => {
66
- if (wasmEngine) wasmEngine.axiom_process_responses();
67
- }, 16);
68
-
69
- const dbPath = allocString("");
70
- const initResultCode = wasmEngine.axiom_wasm_initialize(
71
- dbPath.ptr,
72
- dbPath.len,
73
- );
74
- wasmEngine.axiom_free_memory(dbPath.ptr, dbPath.len);
75
-
76
- if (initResultCode !== 0) {
77
- throw {
78
- stage: "runtime",
79
- category: "server",
80
- code: "InitFailed",
81
- message: `Engine init failed (Code: ${initResultCode})`,
82
- retryable: false,
83
- };
84
- }
85
-
86
- for (const [namespace, contractConfig] of Object.entries(
87
- config.contracts,
88
- )) {
89
- try {
90
- const contractRes = await fetch(contractConfig.contractUrl);
91
- if (!contractRes.ok) {
92
- throw new Error(`HTTP ${contractRes.status}`);
93
- }
94
-
95
- const contractArrayBuffer = await contractRes.arrayBuffer();
96
- let endpointCount = 0;
97
-
98
- try {
99
- const jsonStr = new TextDecoder().decode(contractArrayBuffer);
100
- const contractJson = JSON.parse(jsonStr);
101
- const endpoints = contractJson?.ir?.endpoints;
102
- if (endpoints) {
103
- endpointCount = Array.isArray(endpoints)
104
- ? endpoints.length
105
- : Object.keys(endpoints).length;
106
- }
107
- initRouter(namespace, contractJson);
108
- } catch (e) {
109
- console.error(
110
- `ATMX: Failed to parse .axiom contract for '${namespace}'`,
111
- e,
112
- );
113
- }
114
-
115
- const contractBytes = new Uint8Array(contractArrayBuffer);
116
- const cPtr = allocBytes(contractBytes);
117
- const nsStr = allocString(namespace);
118
- const urlStr = allocString(contractConfig.baseUrl);
119
-
120
- const loadResult = wasmEngine.axiom_wasm_load_contract(
121
- nsStr.ptr,
122
- nsStr.len,
123
- urlStr.ptr,
124
- urlStr.len,
125
- cPtr,
126
- contractBytes.length,
127
- 0,
128
- 0,
129
- 0,
130
- 0,
131
- );
132
-
133
- wasmEngine.axiom_free_memory(cPtr, contractBytes.length);
134
- wasmEngine.axiom_free_memory(nsStr.ptr, nsStr.len);
135
- wasmEngine.axiom_free_memory(urlStr.ptr, urlStr.len);
136
-
137
- if (loadResult !== 0 && loadResult !== -1) {
138
- throw new Error(`Load error (Code: ${loadResult})`);
139
- }
140
-
141
- if (config.debug) {
142
- console.log(
143
- `%c🔒 Axiom Contract Loaded: ${namespace} (${endpointCount} endpoints)`,
144
- "color: #10b981; font-weight: bold;",
145
- );
146
- }
147
-
148
- result.contracts[namespace] = { loaded: true, endpointCount };
149
-
150
- // ✨ EVENT: Emit contract loaded
151
- document.dispatchEvent(
152
- new CustomEvent("atmx:contract-loaded", {
153
- detail: { namespace, endpointCount },
154
- }),
155
- );
156
- } catch (contractErr: any) {
157
- result.contracts[namespace] = {
158
- loaded: false,
159
- endpointCount: 0,
160
- error: contractErr.message,
161
- };
162
- console.error(`ATMX: Contract failed for ${namespace}`, contractErr);
163
- }
164
- }
165
-
166
- result.ok = true;
167
- } catch (fatalError: any) {
168
- result.ok = false;
169
- // Map native JS errors into structured AxiomErrors
170
- result.error = fatalError.stage
171
- ? fatalError
172
- : {
173
- stage: "runtime",
174
- category: "unknown",
175
- code: "FatalError",
176
- message: fatalError.message || String(fatalError),
177
- retryable: false,
178
- };
179
- }
180
-
181
- result.initDurationMs = Math.round(performance.now() - startTime);
182
- return result;
183
- }
184
-
185
- export function setAuthToken(
186
- namespace: string,
187
- methodName: string,
188
- token: string,
189
- ) {
190
- if (!wasmEngine) return;
191
- const nStr = allocString(namespace);
192
- const mStr = allocString(methodName);
193
- const tStr = allocString(token);
194
-
195
- wasmEngine.axiom_wasm_set_auth_token(
196
- nStr.ptr,
197
- nStr.len,
198
- mStr.ptr,
199
- mStr.len,
200
- tStr.ptr,
201
- tStr.len,
202
- );
203
-
204
- wasmEngine.axiom_free_memory(nStr.ptr, nStr.len);
205
- wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);
206
- wasmEngine.axiom_free_memory(tStr.ptr, tStr.len);
207
- }
208
-
209
- export function clearAuthToken(namespace: string, methodName: string) {
210
- if (!wasmEngine) return;
211
- const nStr = allocString(namespace);
212
- const mStr = allocString(methodName);
213
-
214
- wasmEngine.axiom_wasm_clear_auth_token(
215
- nStr.ptr,
216
- nStr.len,
217
- mStr.ptr,
218
- mStr.len,
219
- );
220
-
221
- wasmEngine.axiom_free_memory(nStr.ptr, nStr.len);
222
- wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);
223
- }
@@ -1,62 +0,0 @@
1
- // FILE: src/dom/components/engine-status.ts
2
-
3
- export class AxEngineStatusElement extends HTMLElement {
4
- constructor() {
5
- super();
6
- }
7
-
8
- connectedCallback() {
9
- const loadingText = this.getAttribute("loading-text") || "Initializing...";
10
- const readyText = this.getAttribute("ready-text") || "Online";
11
- const errorText = this.getAttribute("error-text") || "Failed to Connect";
12
-
13
- // Initial state
14
- this.renderState("loading", loadingText, "text-amber-500 animate-pulse");
15
-
16
- // Listen for ATMX engine events globally
17
- document.addEventListener("atmx:ready", () => {
18
- this.renderState("ready", readyText, "text-green-600");
19
- });
20
-
21
- document.addEventListener("atmx:error", (e: Event) => {
22
- const customEvent = e as CustomEvent;
23
- // Check if this is a fatal initialization error vs a normal query error
24
- if (customEvent.detail && customEvent.detail.stage === "runtime") {
25
- this.renderState(
26
- "error",
27
- `${errorText}: ${customEvent.detail.message}`,
28
- "text-red-600",
29
- );
30
- }
31
- });
32
- }
33
-
34
- private renderState(state: string, text: string, defaultClasses: string) {
35
- this.setAttribute("data-state", state);
36
-
37
- // If developer is using raw ax-engine-status directly with inner HTML template matching, we allow it.
38
- // Otherwise, we just swap the raw text node.
39
- const stateElements = this.querySelectorAll(`[data-ax-when]`);
40
-
41
- if (stateElements.length > 0) {
42
- stateElements.forEach((el) => {
43
- if (el.getAttribute("data-ax-when") === state) {
44
- el.removeAttribute("hidden");
45
- } else {
46
- el.setAttribute("hidden", "");
47
- }
48
- });
49
- } else {
50
- // No custom inner templates, just replace text
51
- this.innerText = text;
52
- if (!this.getAttribute("class")) {
53
- this.className = `text-xs font-bold ${defaultClasses}`;
54
- }
55
- }
56
- }
57
- }
58
-
59
- // Automatically register the web component
60
- if (typeof window !== "undefined" && !customElements.get("ax-engine-status")) {
61
- customElements.define("ax-engine-status", AxEngineStatusElement);
62
- }
@@ -1,36 +0,0 @@
1
- const activeRequests = new Map<number, { trigger: HTMLElement, indicators: HTMLElement[] }>();
2
-
3
- export function startRequest(reqId: number, triggerEl: HTMLElement) {
4
- // 1. Add 'ax-request' to the element that triggered the call (e.g., the button)
5
- triggerEl.classList.add('ax-request');
6
-
7
- // 2. Find any associated loading indicators
8
- let indicators: HTMLElement[] = [];
9
- const indicatorSelector = triggerEl.getAttribute('ax-indicator');
10
-
11
- if (indicatorSelector) {
12
- // If ax-indicator="#spinner" is explicitly defined
13
- indicators = Array.from(document.querySelectorAll(indicatorSelector));
14
- } else {
15
- // Fallback: Look for any children inside the trigger with the class 'ax-indicator'
16
- indicators = Array.from(triggerEl.querySelectorAll('.ax-indicator'));
17
- }
18
-
19
- // 3. Turn on the indicators
20
- indicators.forEach(el => el.classList.add('ax-loading'));
21
-
22
- // 4. Save state so we can turn them off later
23
- activeRequests.set(reqId, { trigger: triggerEl, indicators });
24
- }
25
-
26
- export function endRequest(reqId: number) {
27
- const req = activeRequests.get(reqId);
28
- if (!req) return;
29
-
30
- // Turn off all classes
31
- req.trigger.classList.remove('ax-request');
32
- req.indicators.forEach(el => el.classList.remove('ax-loading'));
33
-
34
- // Clean up
35
- activeRequests.delete(reqId);
36
- }