atmx-react 0.43.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/index.d.mts +135 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +628 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +602 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +13 -10
- package/src/components/AxGet.tsx +0 -19
- package/src/components/AxMutation.tsx +0 -48
- package/src/components/AxQuery.tsx +0 -41
- package/src/components/AxTrigger.tsx +0 -36
- package/src/components/AxWhen.tsx +0 -54
- package/src/context/AxiomDataContext.tsx +0 -27
- package/src/context/AxiomProvider.tsx +0 -97
- package/src/core/ActiveQuery.ts +0 -217
- package/src/core/QueryManager.ts +0 -40
- package/src/hooks/useAxiom.ts +0 -13
- package/src/hooks/useAxiomMutation.ts +0 -236
- package/src/hooks/useAxiomQuery.ts +0 -41
- package/src/index.ts +0 -39
- package/src/utils/core-bridge.ts +0 -62
- package/tsconfig.json +0 -27
- package/tsup.config.ts +0 -11
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/utils/core-bridge.ts
|
|
6
|
+
import {
|
|
7
|
+
initWasm,
|
|
8
|
+
wasmEngine,
|
|
9
|
+
allocBytes,
|
|
10
|
+
allocString,
|
|
11
|
+
setAuthToken,
|
|
12
|
+
clearAuthToken
|
|
13
|
+
} from "atmx-web";
|
|
14
|
+
import { resolveRoute, buildRequestPath } from "atmx-web";
|
|
15
|
+
import { pendingRequests } from "atmx-web";
|
|
16
|
+
var globalReqCounter = 0;
|
|
17
|
+
var getNextReqId = () => ++globalReqCounter;
|
|
18
|
+
|
|
19
|
+
// src/context/AxiomProvider.tsx
|
|
20
|
+
import {
|
|
21
|
+
createContext,
|
|
22
|
+
useEffect,
|
|
23
|
+
useState,
|
|
24
|
+
useRef
|
|
25
|
+
} from "react";
|
|
26
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
27
|
+
var AxiomContext = createContext(
|
|
28
|
+
void 0
|
|
29
|
+
);
|
|
30
|
+
var AxiomProvider = ({
|
|
31
|
+
configUrl,
|
|
32
|
+
config,
|
|
33
|
+
children,
|
|
34
|
+
fallback
|
|
35
|
+
}) => {
|
|
36
|
+
const [state, setState] = useState({
|
|
37
|
+
isReady: false,
|
|
38
|
+
error: null,
|
|
39
|
+
config: null
|
|
40
|
+
});
|
|
41
|
+
const initStarted = useRef(false);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (initStarted.current) return;
|
|
44
|
+
initStarted.current = true;
|
|
45
|
+
const bootSequence = async () => {
|
|
46
|
+
try {
|
|
47
|
+
let finalConfig;
|
|
48
|
+
if (configUrl) {
|
|
49
|
+
const res = await fetch(configUrl);
|
|
50
|
+
if (!res.ok)
|
|
51
|
+
throw new Error(`Failed to load config from ${configUrl}`);
|
|
52
|
+
finalConfig = await res.json();
|
|
53
|
+
} else if (config) {
|
|
54
|
+
finalConfig = config;
|
|
55
|
+
} else {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"AxiomProvider requires either 'configUrl' or 'config' prop."
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (!finalConfig.contracts || Object.keys(finalConfig.contracts).length === 0) {
|
|
61
|
+
throw new Error("No contracts defined in ATMX config.");
|
|
62
|
+
}
|
|
63
|
+
await initWasm(finalConfig);
|
|
64
|
+
console.log(`\u269B\uFE0F ATMX-React: Provider ready.`);
|
|
65
|
+
setState({ isReady: true, error: null, config: finalConfig });
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error("ATMX Provider Boot Error:", err);
|
|
68
|
+
setState({ isReady: false, error: err, config: null });
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
bootSequence();
|
|
72
|
+
}, [configUrl, config]);
|
|
73
|
+
if (state.error)
|
|
74
|
+
return /* @__PURE__ */ jsxs("div", { style: { color: "red", padding: "20px", fontFamily: "monospace" }, children: [
|
|
75
|
+
/* @__PURE__ */ jsx("strong", { children: "ATMX Initialization Failed:" }),
|
|
76
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
77
|
+
state.error.message
|
|
78
|
+
] });
|
|
79
|
+
if (!state.isReady) return /* @__PURE__ */ jsx(Fragment, { children: fallback || null });
|
|
80
|
+
return /* @__PURE__ */ jsx(AxiomContext.Provider, { value: state, children });
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/context/AxiomDataContext.tsx
|
|
84
|
+
import { createContext as createContext2, useContext } from "react";
|
|
85
|
+
var AxiomDataContext = createContext2(null);
|
|
86
|
+
function useAxiomContext() {
|
|
87
|
+
const context = useContext(AxiomDataContext);
|
|
88
|
+
if (!context) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"useAxiomContext must be used within an <AxQuery> or <AxMutate> scope."
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return context;
|
|
94
|
+
}
|
|
95
|
+
function useAxiomData() {
|
|
96
|
+
const context = useContext(AxiomDataContext);
|
|
97
|
+
return context?.data || {};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/hooks/useAxiomQuery.ts
|
|
101
|
+
import { useEffect as useEffect2, useSyncExternalStore, useCallback } from "react";
|
|
102
|
+
|
|
103
|
+
// src/hooks/useAxiom.ts
|
|
104
|
+
import { useContext as useContext2 } from "react";
|
|
105
|
+
var useAxiom = () => {
|
|
106
|
+
const context = useContext2(AxiomContext);
|
|
107
|
+
if (context === void 0) {
|
|
108
|
+
throw new Error("useAxiom must be used within an <AxiomProvider>. Did you forget to wrap your app?");
|
|
109
|
+
}
|
|
110
|
+
return context;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/core/ActiveQuery.ts
|
|
114
|
+
var ActiveQuery = class {
|
|
115
|
+
constructor(queryKey, def) {
|
|
116
|
+
__publicField(this, "queryKey");
|
|
117
|
+
__publicField(this, "def");
|
|
118
|
+
__publicField(this, "state");
|
|
119
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
120
|
+
__publicField(this, "currentReqId", null);
|
|
121
|
+
this.queryKey = queryKey;
|
|
122
|
+
this.def = def;
|
|
123
|
+
this.state = {
|
|
124
|
+
status: "idle",
|
|
125
|
+
data: null,
|
|
126
|
+
error: null,
|
|
127
|
+
isFetching: false,
|
|
128
|
+
isMutating: false,
|
|
129
|
+
source: null
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
getState() {
|
|
133
|
+
return this.state;
|
|
134
|
+
}
|
|
135
|
+
subscribe(listener) {
|
|
136
|
+
this.listeners.add(listener);
|
|
137
|
+
return () => this.listeners.delete(listener);
|
|
138
|
+
}
|
|
139
|
+
updateState(partial) {
|
|
140
|
+
this.state = { ...this.state, ...partial };
|
|
141
|
+
this.listeners.forEach((l) => l(this.state));
|
|
142
|
+
}
|
|
143
|
+
fetch(force = false, debug = false) {
|
|
144
|
+
if (this.state.isFetching && !force) return;
|
|
145
|
+
this.updateState({
|
|
146
|
+
isFetching: true,
|
|
147
|
+
status: this.state.data ? "success" : "loading"
|
|
148
|
+
});
|
|
149
|
+
const reqId = getNextReqId();
|
|
150
|
+
this.currentReqId = reqId;
|
|
151
|
+
const syntheticRoute = {
|
|
152
|
+
id: this.def.endpointId,
|
|
153
|
+
namespace: this.def.namespace,
|
|
154
|
+
name: this.def.name || "unknown",
|
|
155
|
+
method: this.def.method,
|
|
156
|
+
pathTemplate: this.def.path,
|
|
157
|
+
isStream: !!this.def.isStream
|
|
158
|
+
};
|
|
159
|
+
const { path } = buildRequestPath(syntheticRoute, this.def.args);
|
|
160
|
+
if (debug) {
|
|
161
|
+
console.groupCollapsed(
|
|
162
|
+
`%c\u2794 WASM QUERY [#${reqId}]`,
|
|
163
|
+
`color: #7c3aed; font-weight: bold;`
|
|
164
|
+
);
|
|
165
|
+
console.log("Namespace:", this.def.namespace);
|
|
166
|
+
console.log("Endpoint ID:", this.def.endpointId);
|
|
167
|
+
console.log("Path:", path);
|
|
168
|
+
console.groupEnd();
|
|
169
|
+
}
|
|
170
|
+
pendingRequests.set(reqId, {
|
|
171
|
+
isStream: !!this.def.isStream,
|
|
172
|
+
onResponse: (response) => {
|
|
173
|
+
if (this.currentReqId !== reqId) return;
|
|
174
|
+
if (debug) {
|
|
175
|
+
const evtName = response.eventType === 1 ? "NetworkSuccess" : response.eventType === 2 ? "CacheHit" : response.eventType === 3 ? "CacheHitAndFetching" : response.eventType === 4 ? "Error" : "Complete";
|
|
176
|
+
console.groupCollapsed(
|
|
177
|
+
`%c\u2190 WASM RESP [#${reqId}]`,
|
|
178
|
+
`color: #059669; font-weight: bold;`
|
|
179
|
+
);
|
|
180
|
+
console.log("Event Type:", evtName);
|
|
181
|
+
if (response.data) console.log("Data:", response.data);
|
|
182
|
+
if (response.error) console.log("Error:", response.error);
|
|
183
|
+
console.groupEnd();
|
|
184
|
+
}
|
|
185
|
+
if (response.eventType === 4) {
|
|
186
|
+
this.updateState({
|
|
187
|
+
status: "error",
|
|
188
|
+
error: response.error || null,
|
|
189
|
+
isFetching: false
|
|
190
|
+
});
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (response.data) {
|
|
194
|
+
try {
|
|
195
|
+
const decodedData = this.def.decoder(response.data);
|
|
196
|
+
let source = "network";
|
|
197
|
+
let isFetching = false;
|
|
198
|
+
if (response.eventType === 2) {
|
|
199
|
+
source = "cache";
|
|
200
|
+
isFetching = false;
|
|
201
|
+
} else if (response.eventType === 3) {
|
|
202
|
+
source = "cache";
|
|
203
|
+
isFetching = true;
|
|
204
|
+
} else if (response.eventType === 1) {
|
|
205
|
+
source = "network";
|
|
206
|
+
isFetching = false;
|
|
207
|
+
}
|
|
208
|
+
this.updateState({
|
|
209
|
+
status: "success",
|
|
210
|
+
data: decodedData,
|
|
211
|
+
error: null,
|
|
212
|
+
isFetching,
|
|
213
|
+
source
|
|
214
|
+
});
|
|
215
|
+
} catch (e) {
|
|
216
|
+
this.updateState({
|
|
217
|
+
status: "error",
|
|
218
|
+
error: { message: "Decoding failed", details: String(e) },
|
|
219
|
+
isFetching: false
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
onComplete: () => {
|
|
225
|
+
if (this.currentReqId !== reqId) return;
|
|
226
|
+
this.updateState({ isFetching: false });
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const isFormUrlEncoded = Object.entries(this.def.headers || {}).some(
|
|
230
|
+
([k, v]) => k.toLowerCase() === "content-type" && v.includes("application/x-www-form-urlencoded")
|
|
231
|
+
);
|
|
232
|
+
let payloadPtr = 0, payloadLen = 0;
|
|
233
|
+
if (this.def.payload !== void 0 && this.def.payload !== null) {
|
|
234
|
+
const safePayload = this.def.serializer ? this.def.serializer(this.def.payload) : this.def.payload;
|
|
235
|
+
let payloadBytes;
|
|
236
|
+
if (isFormUrlEncoded && typeof safePayload === "object") {
|
|
237
|
+
const params = new URLSearchParams();
|
|
238
|
+
for (const [k, v] of Object.entries(safePayload))
|
|
239
|
+
params.append(k, String(v));
|
|
240
|
+
payloadBytes = new TextEncoder().encode(params.toString());
|
|
241
|
+
} else {
|
|
242
|
+
payloadBytes = new TextEncoder().encode(JSON.stringify(safePayload));
|
|
243
|
+
}
|
|
244
|
+
payloadPtr = allocBytes(payloadBytes);
|
|
245
|
+
payloadLen = payloadBytes.length;
|
|
246
|
+
}
|
|
247
|
+
const nsStr = allocString(this.def.namespace);
|
|
248
|
+
const mStr = allocString(this.def.method);
|
|
249
|
+
const pStr = allocString(path);
|
|
250
|
+
const tpStr = allocString("");
|
|
251
|
+
const hStr = allocString(
|
|
252
|
+
this.def.headers ? JSON.stringify(this.def.headers) : ""
|
|
253
|
+
);
|
|
254
|
+
wasmEngine.axiom_wasm_call(
|
|
255
|
+
reqId,
|
|
256
|
+
nsStr.ptr,
|
|
257
|
+
nsStr.len,
|
|
258
|
+
this.def.endpointId,
|
|
259
|
+
mStr.ptr,
|
|
260
|
+
mStr.len,
|
|
261
|
+
pStr.ptr,
|
|
262
|
+
pStr.len,
|
|
263
|
+
tpStr.ptr,
|
|
264
|
+
tpStr.len,
|
|
265
|
+
hStr.ptr,
|
|
266
|
+
hStr.len,
|
|
267
|
+
payloadPtr,
|
|
268
|
+
payloadLen
|
|
269
|
+
);
|
|
270
|
+
wasmEngine.axiom_free_memory(nsStr.ptr, nsStr.len);
|
|
271
|
+
wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);
|
|
272
|
+
wasmEngine.axiom_free_memory(pStr.ptr, pStr.len);
|
|
273
|
+
wasmEngine.axiom_free_memory(tpStr.ptr, tpStr.len);
|
|
274
|
+
wasmEngine.axiom_free_memory(hStr.ptr, hStr.len);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/core/QueryManager.ts
|
|
279
|
+
var QueryManager = class {
|
|
280
|
+
constructor() {
|
|
281
|
+
__publicField(this, "queries", /* @__PURE__ */ new Map());
|
|
282
|
+
}
|
|
283
|
+
buildKey(namespace, endpointId, args) {
|
|
284
|
+
return `${namespace}:${endpointId}:${JSON.stringify(args)}`;
|
|
285
|
+
}
|
|
286
|
+
getQuery(def) {
|
|
287
|
+
const key = this.buildKey(def.namespace, def.endpointId, def.args);
|
|
288
|
+
if (this.queries.has(key)) {
|
|
289
|
+
return this.queries.get(key);
|
|
290
|
+
}
|
|
291
|
+
const newQuery = new ActiveQuery(key, def);
|
|
292
|
+
this.queries.set(key, newQuery);
|
|
293
|
+
return newQuery;
|
|
294
|
+
}
|
|
295
|
+
invalidate(namespace, endpointId, args) {
|
|
296
|
+
const key = this.buildKey(namespace, endpointId, args);
|
|
297
|
+
const query = this.queries.get(key);
|
|
298
|
+
if (query) query.fetch(true);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
var axiomQueryManager = new QueryManager();
|
|
302
|
+
|
|
303
|
+
// src/hooks/useAxiomQuery.ts
|
|
304
|
+
function useAxiomQuery(queryDef, options = {}) {
|
|
305
|
+
const { isReady, config } = useAxiom();
|
|
306
|
+
const { enabled = true } = options;
|
|
307
|
+
const activeQuery = axiomQueryManager.getQuery(queryDef);
|
|
308
|
+
const state = useSyncExternalStore(
|
|
309
|
+
useCallback(
|
|
310
|
+
(onStoreChange) => activeQuery.subscribe(onStoreChange),
|
|
311
|
+
[activeQuery]
|
|
312
|
+
),
|
|
313
|
+
() => activeQuery.getState(),
|
|
314
|
+
() => activeQuery.getState()
|
|
315
|
+
);
|
|
316
|
+
useEffect2(() => {
|
|
317
|
+
if (!isReady || !enabled) return;
|
|
318
|
+
if (state.status === "idle") {
|
|
319
|
+
activeQuery.fetch(false, config?.debug);
|
|
320
|
+
}
|
|
321
|
+
}, [isReady, enabled, activeQuery, state.status, config?.debug]);
|
|
322
|
+
return {
|
|
323
|
+
data: state.data,
|
|
324
|
+
isLoading: state.status === "loading",
|
|
325
|
+
isFetching: state.isFetching,
|
|
326
|
+
source: state.source,
|
|
327
|
+
error: state.error,
|
|
328
|
+
state,
|
|
329
|
+
// Export raw state for <AxWhen>
|
|
330
|
+
refetch: () => activeQuery.fetch(true, config?.debug)
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/components/AxQuery.tsx
|
|
335
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
336
|
+
function AxQuery({
|
|
337
|
+
call,
|
|
338
|
+
children,
|
|
339
|
+
enabled = true
|
|
340
|
+
}) {
|
|
341
|
+
const result = useAxiomQuery(call, { enabled });
|
|
342
|
+
const content = typeof children === "function" ? children({
|
|
343
|
+
data: result.data,
|
|
344
|
+
state: result.state,
|
|
345
|
+
refetch: result.refetch
|
|
346
|
+
}) : children;
|
|
347
|
+
return /* @__PURE__ */ jsx2(AxiomDataContext.Provider, { value: result.state, children: content });
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/components/AxWhen.tsx
|
|
351
|
+
import { useContext as useContext3 } from "react";
|
|
352
|
+
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
353
|
+
function AxWhen({ value, is, children }) {
|
|
354
|
+
const context = useContext3(AxiomDataContext);
|
|
355
|
+
const stateObj = value || context;
|
|
356
|
+
if (!stateObj) return null;
|
|
357
|
+
const expectedStates = is.split(",").map((s) => s.trim().toLowerCase());
|
|
358
|
+
let currentState = "idle";
|
|
359
|
+
if (stateObj.isMutating) {
|
|
360
|
+
currentState = "mutating";
|
|
361
|
+
} else if (stateObj.status === "loading") {
|
|
362
|
+
currentState = "loading";
|
|
363
|
+
} else if (stateObj.status === "error") {
|
|
364
|
+
currentState = "error";
|
|
365
|
+
} else if (stateObj.status === "success" || stateObj.data) {
|
|
366
|
+
currentState = "data";
|
|
367
|
+
}
|
|
368
|
+
if (expectedStates.includes("success") && stateObj.status === "success" && !stateObj.isMutating) {
|
|
369
|
+
currentState = "success";
|
|
370
|
+
}
|
|
371
|
+
if (expectedStates.includes(currentState)) {
|
|
372
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children });
|
|
373
|
+
}
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// src/components/AxTrigger.tsx
|
|
378
|
+
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
379
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
380
|
+
var AxTrigger = ({ onTrigger, once = true, children }) => {
|
|
381
|
+
const elementRef = useRef2(null);
|
|
382
|
+
const hasTriggered = useRef2(false);
|
|
383
|
+
useEffect3(() => {
|
|
384
|
+
const observer = new IntersectionObserver((entries) => {
|
|
385
|
+
entries.forEach((entry) => {
|
|
386
|
+
if (entry.isIntersecting) {
|
|
387
|
+
if (once && hasTriggered.current) return;
|
|
388
|
+
onTrigger();
|
|
389
|
+
hasTriggered.current = true;
|
|
390
|
+
if (once) observer.unobserve(entry.target);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}, { threshold: 0.1 });
|
|
394
|
+
if (elementRef.current) {
|
|
395
|
+
observer.observe(elementRef.current);
|
|
396
|
+
}
|
|
397
|
+
return () => observer.disconnect();
|
|
398
|
+
}, [onTrigger, once]);
|
|
399
|
+
return /* @__PURE__ */ jsx4("div", { ref: elementRef, children });
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
// src/hooks/useAxiomMutation.ts
|
|
403
|
+
import { useState as useState2, useCallback as useCallback2, useRef as useRef3, useEffect as useEffect4 } from "react";
|
|
404
|
+
function extractFieldError(error, fieldName) {
|
|
405
|
+
if (error?.code !== "ValidationError" || !error?.details) return null;
|
|
406
|
+
const lines = error.details.split("\n");
|
|
407
|
+
for (const line of lines) {
|
|
408
|
+
if (line.startsWith(fieldName + ":"))
|
|
409
|
+
return line.substring(fieldName.length + 1).trim();
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
function useAxiomMutation(mutationFn) {
|
|
414
|
+
const { isReady, config } = useAxiom();
|
|
415
|
+
const [state, setState] = useState2({
|
|
416
|
+
status: "idle",
|
|
417
|
+
data: null,
|
|
418
|
+
error: null,
|
|
419
|
+
isFetching: false,
|
|
420
|
+
isMutating: false,
|
|
421
|
+
source: null
|
|
422
|
+
});
|
|
423
|
+
const isMounted = useRef3(true);
|
|
424
|
+
useEffect4(() => {
|
|
425
|
+
isMounted.current = true;
|
|
426
|
+
return () => {
|
|
427
|
+
isMounted.current = false;
|
|
428
|
+
};
|
|
429
|
+
}, []);
|
|
430
|
+
const execute = useCallback2(
|
|
431
|
+
async (args, options) => {
|
|
432
|
+
if (!isReady || !config) return;
|
|
433
|
+
const rawDef = mutationFn(args);
|
|
434
|
+
rawDef.headers = options?.headers;
|
|
435
|
+
const reqId = getNextReqId();
|
|
436
|
+
if (isMounted.current)
|
|
437
|
+
setState({
|
|
438
|
+
status: "loading",
|
|
439
|
+
data: null,
|
|
440
|
+
error: null,
|
|
441
|
+
isFetching: false,
|
|
442
|
+
isMutating: true,
|
|
443
|
+
source: null
|
|
444
|
+
});
|
|
445
|
+
const syntheticRoute = {
|
|
446
|
+
id: rawDef.endpointId,
|
|
447
|
+
namespace: rawDef.namespace,
|
|
448
|
+
name: rawDef.name || "unknown",
|
|
449
|
+
method: rawDef.method,
|
|
450
|
+
pathTemplate: rawDef.path,
|
|
451
|
+
isStream: !!rawDef.isStream
|
|
452
|
+
};
|
|
453
|
+
const { path } = buildRequestPath(syntheticRoute, rawDef.args);
|
|
454
|
+
const isFormUrlEncoded = Object.entries(rawDef.headers || {}).some(
|
|
455
|
+
([k, v]) => k.toLowerCase() === "content-type" && v.includes("application/x-www-form-urlencoded")
|
|
456
|
+
);
|
|
457
|
+
let payloadPtr = 0, payloadLen = 0, payloadObj = null;
|
|
458
|
+
if (rawDef.payload !== void 0 && rawDef.payload !== null) {
|
|
459
|
+
payloadObj = rawDef.serializer ? rawDef.serializer(rawDef.payload) : rawDef.payload;
|
|
460
|
+
let payloadBytes;
|
|
461
|
+
if (isFormUrlEncoded && typeof payloadObj === "object") {
|
|
462
|
+
const params = new URLSearchParams();
|
|
463
|
+
for (const [k, v] of Object.entries(payloadObj))
|
|
464
|
+
params.append(k, String(v));
|
|
465
|
+
payloadBytes = new TextEncoder().encode(params.toString());
|
|
466
|
+
} else {
|
|
467
|
+
payloadBytes = new TextEncoder().encode(JSON.stringify(payloadObj));
|
|
468
|
+
}
|
|
469
|
+
payloadPtr = allocBytes(payloadBytes);
|
|
470
|
+
payloadLen = payloadBytes.length;
|
|
471
|
+
}
|
|
472
|
+
if (config.debug) {
|
|
473
|
+
console.groupCollapsed(
|
|
474
|
+
`%c\u2794 WASM MUTATE [#${reqId}]`,
|
|
475
|
+
`color: #7c3aed; font-weight: bold;`
|
|
476
|
+
);
|
|
477
|
+
console.log("Namespace:", rawDef.namespace);
|
|
478
|
+
console.log("Endpoint ID:", rawDef.endpointId);
|
|
479
|
+
console.log("Path:", path);
|
|
480
|
+
console.log("Payload:", payloadObj);
|
|
481
|
+
console.groupEnd();
|
|
482
|
+
}
|
|
483
|
+
pendingRequests.set(reqId, {
|
|
484
|
+
isStream: !!rawDef.isStream,
|
|
485
|
+
onResponse: (response) => {
|
|
486
|
+
if (!isMounted.current) return;
|
|
487
|
+
if (config.debug) {
|
|
488
|
+
const evtName = response.eventType === 1 ? "NetworkSuccess" : response.eventType === 2 ? "CacheHit" : response.eventType === 3 ? "CacheHitAndFetching" : response.eventType === 4 ? "Error" : "Complete";
|
|
489
|
+
console.groupCollapsed(
|
|
490
|
+
`%c\u2190 WASM RESP [#${reqId}]`,
|
|
491
|
+
`color: #059669; font-weight: bold;`
|
|
492
|
+
);
|
|
493
|
+
console.log("Event Type:", evtName);
|
|
494
|
+
if (response.data) console.log("Data:", response.data);
|
|
495
|
+
if (response.error) console.log("Error:", response.error);
|
|
496
|
+
console.groupEnd();
|
|
497
|
+
}
|
|
498
|
+
if (response.eventType === 4) {
|
|
499
|
+
setState({
|
|
500
|
+
status: "error",
|
|
501
|
+
error: response.error || null,
|
|
502
|
+
isFetching: false,
|
|
503
|
+
isMutating: false,
|
|
504
|
+
data: null,
|
|
505
|
+
source: null
|
|
506
|
+
});
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
if (response.data) {
|
|
510
|
+
try {
|
|
511
|
+
let source = "network";
|
|
512
|
+
if (response.eventType === 2 || response.eventType === 3)
|
|
513
|
+
source = "cache";
|
|
514
|
+
setState({
|
|
515
|
+
status: "success",
|
|
516
|
+
data: rawDef.decoder(response.data),
|
|
517
|
+
error: null,
|
|
518
|
+
isFetching: false,
|
|
519
|
+
isMutating: false,
|
|
520
|
+
source
|
|
521
|
+
});
|
|
522
|
+
} catch (e) {
|
|
523
|
+
setState({
|
|
524
|
+
status: "error",
|
|
525
|
+
error: {
|
|
526
|
+
message: "Decoding failed",
|
|
527
|
+
details: String(e)
|
|
528
|
+
},
|
|
529
|
+
isFetching: false,
|
|
530
|
+
isMutating: false,
|
|
531
|
+
data: null,
|
|
532
|
+
source: null
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
onComplete: () => {
|
|
538
|
+
if (isMounted.current)
|
|
539
|
+
setState((prev) => ({
|
|
540
|
+
...prev,
|
|
541
|
+
isMutating: false,
|
|
542
|
+
isFetching: false
|
|
543
|
+
}));
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
const nsStr = allocString(rawDef.namespace);
|
|
547
|
+
const mStr = allocString(rawDef.method);
|
|
548
|
+
const pStr = allocString(path);
|
|
549
|
+
const tpStr = allocString("");
|
|
550
|
+
const hStr = allocString(
|
|
551
|
+
rawDef.headers ? JSON.stringify(rawDef.headers) : ""
|
|
552
|
+
);
|
|
553
|
+
wasmEngine.axiom_wasm_call(
|
|
554
|
+
reqId,
|
|
555
|
+
nsStr.ptr,
|
|
556
|
+
nsStr.len,
|
|
557
|
+
rawDef.endpointId,
|
|
558
|
+
mStr.ptr,
|
|
559
|
+
mStr.len,
|
|
560
|
+
pStr.ptr,
|
|
561
|
+
pStr.len,
|
|
562
|
+
tpStr.ptr,
|
|
563
|
+
tpStr.len,
|
|
564
|
+
hStr.ptr,
|
|
565
|
+
hStr.len,
|
|
566
|
+
payloadPtr,
|
|
567
|
+
payloadLen
|
|
568
|
+
);
|
|
569
|
+
wasmEngine.axiom_free_memory(nsStr.ptr, nsStr.len);
|
|
570
|
+
wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);
|
|
571
|
+
wasmEngine.axiom_free_memory(pStr.ptr, pStr.len);
|
|
572
|
+
wasmEngine.axiom_free_memory(tpStr.ptr, tpStr.len);
|
|
573
|
+
wasmEngine.axiom_free_memory(hStr.ptr, hStr.len);
|
|
574
|
+
},
|
|
575
|
+
[isReady, config, mutationFn]
|
|
576
|
+
);
|
|
577
|
+
return {
|
|
578
|
+
execute,
|
|
579
|
+
state,
|
|
580
|
+
data: state.data,
|
|
581
|
+
isMutating: state.isMutating,
|
|
582
|
+
error: state.error,
|
|
583
|
+
getFieldError: (fieldName) => extractFieldError(state.error, fieldName)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
export {
|
|
587
|
+
AxQuery,
|
|
588
|
+
AxTrigger,
|
|
589
|
+
AxWhen,
|
|
590
|
+
AxiomContext,
|
|
591
|
+
AxiomDataContext,
|
|
592
|
+
AxiomProvider,
|
|
593
|
+
axiomQueryManager,
|
|
594
|
+
clearAuthToken,
|
|
595
|
+
setAuthToken,
|
|
596
|
+
useAxiom,
|
|
597
|
+
useAxiomContext,
|
|
598
|
+
useAxiomData,
|
|
599
|
+
useAxiomMutation,
|
|
600
|
+
useAxiomQuery
|
|
601
|
+
};
|
|
602
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/core-bridge.ts","../src/context/AxiomProvider.tsx","../src/context/AxiomDataContext.tsx","../src/hooks/useAxiomQuery.ts","../src/hooks/useAxiom.ts","../src/core/ActiveQuery.ts","../src/core/QueryManager.ts","../src/components/AxQuery.tsx","../src/components/AxWhen.tsx","../src/components/AxTrigger.tsx","../src/hooks/useAxiomMutation.ts"],"sourcesContent":["import {\n initWasm,\n wasmEngine,\n allocBytes,\n allocString,\n setAuthToken,\n clearAuthToken,\n} from \"atmx-web\";\nimport { resolveRoute, Route, buildRequestPath } from \"atmx-web\";\nimport { pendingRequests } from \"atmx-web\";\nimport { AtmxConfig, AxiomResponse, AxiomError, EventType } from \"atmx-web\";\n\nlet globalReqCounter = 0;\nexport const getNextReqId = () => ++globalReqCounter;\n\nexport interface AxiomQueryDef<T> {\n namespace: string;\n name: string;\n endpointId: number;\n method: string;\n path: string;\n payload?: any;\n decoder: (json: any) => T;\n serializer?: (payload: any) => any;\n args: Record<string, any>;\n isStream?: boolean;\n headers?: Record<string, string>; // ✨ NEW\n}\n\nexport type AxiomStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nexport interface AxiomState<T> {\n status: AxiomStatus;\n data: T | null;\n error: AxiomError | null;\n isFetching: boolean;\n isMutating: boolean;\n source: \"cache\" | \"network\" | null;\n}\n\nexport {\n initWasm,\n wasmEngine,\n allocBytes,\n allocString,\n resolveRoute,\n buildRequestPath,\n pendingRequests,\n setAuthToken,\n clearAuthToken,\n};\n\nexport type { AtmxConfig, AxiomResponse, AxiomError, EventType, Route };\n","// FILE: src/context/AxiomProvider.tsx\nimport React, {\n createContext,\n useEffect,\n useState,\n useRef,\n ReactNode,\n} from \"react\";\nimport { initWasm, AtmxConfig } from \"../utils/core-bridge\";\n\nexport interface AxiomContextState {\n isReady: boolean;\n error: Error | null;\n config: AtmxConfig | null;\n}\n\nexport const AxiomContext = createContext<AxiomContextState | undefined>(\n undefined,\n);\n\nexport interface AxiomProviderProps {\n configUrl?: string;\n config?: AtmxConfig;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\nexport const AxiomProvider: React.FC<AxiomProviderProps> = ({\n configUrl,\n config,\n children,\n fallback,\n}) => {\n const [state, setState] = useState<AxiomContextState>({\n isReady: false,\n error: null,\n config: null,\n });\n\n const initStarted = useRef(false);\n\n useEffect(() => {\n if (initStarted.current) return;\n initStarted.current = true;\n\n const bootSequence = async () => {\n try {\n let finalConfig: AtmxConfig;\n if (configUrl) {\n const res = await fetch(configUrl);\n if (!res.ok)\n throw new Error(`Failed to load config from ${configUrl}`);\n finalConfig = await res.json();\n } else if (config) {\n finalConfig = config;\n } else {\n throw new Error(\n \"AxiomProvider requires either 'configUrl' or 'config' prop.\",\n );\n }\n\n if (\n !finalConfig.contracts ||\n Object.keys(finalConfig.contracts).length === 0\n ) {\n throw new Error(\"No contracts defined in ATMX config.\");\n }\n\n // 1. Initialize Wasm Engine (Handles ALL contracts natively!)\n await initWasm(finalConfig);\n\n console.log(`⚛️ ATMX-React: Provider ready.`);\n setState({ isReady: true, error: null, config: finalConfig });\n } catch (err: any) {\n console.error(\"ATMX Provider Boot Error:\", err);\n setState({ isReady: false, error: err, config: null });\n }\n };\n\n bootSequence();\n }, [configUrl, config]);\n\n if (state.error)\n return (\n <div style={{ color: \"red\", padding: \"20px\", fontFamily: \"monospace\" }}>\n <strong>ATMX Initialization Failed:</strong>\n <br />\n {state.error.message}\n </div>\n );\n\n if (!state.isReady) return <>{fallback || null}</>;\n\n return (\n <AxiomContext.Provider value={state}>{children}</AxiomContext.Provider>\n );\n};\n","// FILE: src/context/AxiomDataContext.tsx\nimport { createContext, useContext } from \"react\";\nimport { AxiomState } from \"../utils/core-bridge\";\n\nexport const AxiomDataContext = createContext<AxiomState<any> | null>(null);\n\n/**\n * Throwing version: Use this when you absolutely expect to be inside a scope.\n */\nexport function useAxiomContext<T>(): AxiomState<T> {\n const context = useContext(AxiomDataContext);\n if (!context) {\n throw new Error(\n \"useAxiomContext must be used within an <AxQuery> or <AxMutate> scope.\",\n );\n }\n return context as AxiomState<T>;\n}\n\n/**\n * Safe version: Returns T or an empty object.\n * Used for Context Inheritance ($data access).\n */\nexport function useAxiomData<T>(): T {\n const context = useContext(AxiomDataContext);\n return (context?.data || {}) as T;\n}\n","// FILE: src/hooks/useAxiomQuery.ts\nimport { useEffect, useSyncExternalStore, useCallback } from \"react\";\nimport { useAxiom } from \"./useAxiom\";\nimport { AxiomQueryDef } from \"../utils/core-bridge\";\nimport { axiomQueryManager } from \"../core/QueryManager\";\n\nexport function useAxiomQuery<T>(\n queryDef: AxiomQueryDef<T>,\n options: { enabled?: boolean } = {},\n) {\n const { isReady, config } = useAxiom();\n const { enabled = true } = options;\n\n const activeQuery = axiomQueryManager.getQuery(queryDef);\n\n const state = useSyncExternalStore(\n useCallback(\n (onStoreChange) => activeQuery.subscribe(onStoreChange),\n [activeQuery],\n ),\n () => activeQuery.getState(),\n () => activeQuery.getState(),\n );\n\n useEffect(() => {\n if (!isReady || !enabled) return;\n if (state.status === \"idle\") {\n activeQuery.fetch(false, config?.debug);\n }\n }, [isReady, enabled, activeQuery, state.status, config?.debug]);\n\n return {\n data: state.data,\n isLoading: state.status === \"loading\",\n isFetching: state.isFetching,\n source: state.source,\n error: state.error,\n state: state, // Export raw state for <AxWhen>\n refetch: () => activeQuery.fetch(true, config?.debug),\n };\n}\n","// src/hooks/useAxiom.ts\nimport { useContext } from 'react';\nimport { AxiomContext } from '../context/AxiomProvider';\n\nexport const useAxiom = () => {\n const context = useContext(AxiomContext);\n\n if (context === undefined) {\n throw new Error(\"useAxiom must be used within an <AxiomProvider>. Did you forget to wrap your app?\");\n }\n\n return context;\n};","// FILE: src/core/ActiveQuery.ts\nimport {\n AxiomState,\n AxiomQueryDef,\n wasmEngine,\n allocString,\n allocBytes,\n pendingRequests,\n getNextReqId,\n buildRequestPath,\n Route,\n} from \"../utils/core-bridge\";\n\ntype Listener<T> = (state: AxiomState<T>) => void;\n\nexport class ActiveQuery<T> {\n public queryKey: string;\n public def: AxiomQueryDef<T>;\n private state: AxiomState<T>;\n private listeners: Set<Listener<T>> = new Set();\n private currentReqId: number | null = null;\n\n constructor(queryKey: string, def: AxiomQueryDef<T>) {\n this.queryKey = queryKey;\n this.def = def;\n this.state = {\n status: \"idle\",\n data: null,\n error: null,\n isFetching: false,\n isMutating: false,\n source: null,\n };\n }\n\n public getState(): AxiomState<T> {\n return this.state;\n }\n\n public subscribe(listener: Listener<T>): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private updateState(partial: Partial<AxiomState<T>>) {\n this.state = { ...this.state, ...partial };\n this.listeners.forEach((l) => l(this.state));\n }\n\n public fetch(force: boolean = false, debug: boolean = false) {\n if (this.state.isFetching && !force) return;\n\n this.updateState({\n isFetching: true,\n status: this.state.data ? \"success\" : \"loading\",\n });\n\n const reqId = getNextReqId();\n this.currentReqId = reqId;\n\n // FIX: Bypass the dictionary lookup. We already have the metadata from the generated SDK!\n const syntheticRoute: Route = {\n id: this.def.endpointId,\n namespace: this.def.namespace,\n name: this.def.name || \"unknown\",\n method: this.def.method,\n pathTemplate: this.def.path,\n isStream: !!this.def.isStream,\n };\n\n // Auto-interpolate {path_params} and ?query_params\n const { path } = buildRequestPath(syntheticRoute, this.def.args);\n\n if (debug) {\n console.groupCollapsed(\n `%c➔ WASM QUERY [#${reqId}]`,\n `color: #7c3aed; font-weight: bold;`,\n );\n console.log(\"Namespace:\", this.def.namespace);\n console.log(\"Endpoint ID:\", this.def.endpointId);\n console.log(\"Path:\", path);\n console.groupEnd();\n }\n\n pendingRequests.set(reqId, {\n isStream: !!this.def.isStream,\n onResponse: (response) => {\n if (this.currentReqId !== reqId) return;\n\n if (debug) {\n const evtName =\n response.eventType === 1\n ? \"NetworkSuccess\"\n : response.eventType === 2\n ? \"CacheHit\"\n : response.eventType === 3\n ? \"CacheHitAndFetching\"\n : response.eventType === 4\n ? \"Error\"\n : \"Complete\";\n console.groupCollapsed(\n `%c← WASM RESP [#${reqId}]`,\n `color: #059669; font-weight: bold;`,\n );\n console.log(\"Event Type:\", evtName);\n if (response.data) console.log(\"Data:\", response.data);\n if (response.error) console.log(\"Error:\", response.error);\n console.groupEnd();\n }\n\n if (response.eventType === 4) {\n this.updateState({\n status: \"error\",\n error: response.error || null,\n isFetching: false,\n });\n return;\n }\n\n if (response.data) {\n try {\n const decodedData = this.def.decoder(response.data);\n let source: \"cache\" | \"network\" = \"network\";\n let isFetching = false;\n\n if (response.eventType === 2) {\n source = \"cache\";\n isFetching = false;\n } else if (response.eventType === 3) {\n source = \"cache\";\n isFetching = true;\n } else if (response.eventType === 1) {\n source = \"network\";\n isFetching = false;\n }\n\n this.updateState({\n status: \"success\",\n data: decodedData,\n error: null,\n isFetching,\n source,\n });\n } catch (e) {\n this.updateState({\n status: \"error\",\n error: { message: \"Decoding failed\", details: String(e) } as any,\n isFetching: false,\n });\n }\n }\n },\n onComplete: () => {\n if (this.currentReqId !== reqId) return;\n this.updateState({ isFetching: false });\n },\n });\n\n const isFormUrlEncoded = Object.entries(this.def.headers || {}).some(\n ([k, v]) =>\n k.toLowerCase() === \"content-type\" &&\n v.includes(\"application/x-www-form-urlencoded\"),\n );\n\n let payloadPtr = 0,\n payloadLen = 0;\n if (this.def.payload !== undefined && this.def.payload !== null) {\n const safePayload = this.def.serializer\n ? this.def.serializer(this.def.payload)\n : this.def.payload;\n let payloadBytes: Uint8Array;\n\n if (isFormUrlEncoded && typeof safePayload === \"object\") {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(safePayload))\n params.append(k, String(v));\n payloadBytes = new TextEncoder().encode(params.toString());\n } else {\n payloadBytes = new TextEncoder().encode(JSON.stringify(safePayload));\n }\n\n payloadPtr = allocBytes(payloadBytes);\n payloadLen = payloadBytes.length;\n }\n\n const nsStr = allocString(this.def.namespace);\n const mStr = allocString(this.def.method);\n const pStr = allocString(path);\n const tpStr = allocString(\"\");\n const hStr = allocString(\n this.def.headers ? JSON.stringify(this.def.headers) : \"\",\n );\n\n wasmEngine.axiom_wasm_call(\n reqId,\n nsStr.ptr,\n nsStr.len,\n this.def.endpointId,\n mStr.ptr,\n mStr.len,\n pStr.ptr,\n pStr.len,\n tpStr.ptr,\n tpStr.len,\n hStr.ptr,\n hStr.len,\n payloadPtr,\n payloadLen,\n );\n\n wasmEngine.axiom_free_memory(nsStr.ptr, nsStr.len);\n wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);\n wasmEngine.axiom_free_memory(pStr.ptr, pStr.len);\n wasmEngine.axiom_free_memory(tpStr.ptr, tpStr.len);\n wasmEngine.axiom_free_memory(hStr.ptr, hStr.len);\n }\n}\n","// FILE: src/core/QueryManager.ts\nimport { ActiveQuery } from \"./ActiveQuery\";\nimport { AxiomQueryDef } from \"../utils/core-bridge\";\n\nclass QueryManager {\n private queries = new Map<string, ActiveQuery<any>>();\n\n private buildKey(\n namespace: string,\n endpointId: number,\n args: Record<string, any>,\n ): string {\n // EXACT ATMX Core Cache Key Match!\n return `${namespace}:${endpointId}:${JSON.stringify(args)}`;\n }\n\n public getQuery<T>(def: AxiomQueryDef<T>): ActiveQuery<T> {\n const key = this.buildKey(def.namespace, def.endpointId, def.args);\n\n if (this.queries.has(key)) {\n return this.queries.get(key) as ActiveQuery<T>;\n }\n\n const newQuery = new ActiveQuery<T>(key, def);\n this.queries.set(key, newQuery);\n return newQuery;\n }\n\n public invalidate(\n namespace: string,\n endpointId: number,\n args: Record<string, any>,\n ) {\n const key = this.buildKey(namespace, endpointId, args);\n const query = this.queries.get(key);\n if (query) query.fetch(true);\n }\n}\n\nexport const axiomQueryManager = new QueryManager();\n","// FILE: src/components/AxQuery.tsx\nimport { ReactNode } from \"react\";\nimport { AxiomQueryDef, AxiomState } from \"../utils/core-bridge\";\nimport { useAxiomQuery } from \"../hooks/useAxiomQuery\";\nimport { AxiomDataContext } from \"../context/AxiomDataContext\";\n\nexport interface AxQueryProps<T> {\n call: AxiomQueryDef<T>;\n children:\n | ReactNode\n | ((props: {\n data: T | null;\n state: AxiomState<T>;\n refetch: () => void;\n }) => ReactNode);\n enabled?: boolean;\n}\n\nexport function AxQuery<T>({\n call,\n children,\n enabled = true,\n}: AxQueryProps<T>) {\n const result = useAxiomQuery<T>(call, { enabled });\n\n const content =\n typeof children === \"function\"\n ? children({\n data: result.data,\n state: result.state,\n refetch: result.refetch,\n })\n : children;\n\n // Provide the state downwards so nested components (or AxWhen) can inherit it!\n return (\n <AxiomDataContext.Provider value={result.state}>\n {content}\n </AxiomDataContext.Provider>\n );\n}\n","// FILE: src/components/AxWhen.tsx\nimport { ReactNode, useContext } from \"react\";\nimport { AxiomDataContext } from \"../context/AxiomDataContext\";\n\ninterface AxWhenProps {\n /** Explicit state object from a hook (e.g. sdk.users.useGetUser) */\n value?: {\n status: string;\n data?: any;\n isFetching?: boolean;\n isMutating?: boolean;\n };\n /** Comma-separated states: \"idle, loading, mutating, data, success, error\" */\n is: string;\n children: ReactNode;\n}\n\nexport function AxWhen({ value, is, children }: AxWhenProps) {\n // Use useContext directly instead of the throwing hook useAxiomContext\n const context = useContext(AxiomDataContext);\n const stateObj = value || context;\n\n // If no value is provided and we aren't inside a scope, render nothing\n if (!stateObj) return null;\n\n const expectedStates = is.split(\",\").map((s) => s.trim().toLowerCase());\n\n let currentState = \"idle\";\n\n if (stateObj.isMutating) {\n currentState = \"mutating\";\n } else if (stateObj.status === \"loading\") {\n currentState = \"loading\";\n } else if (stateObj.status === \"error\") {\n currentState = \"error\";\n } else if (stateObj.status === \"success\" || stateObj.data) {\n currentState = \"data\";\n }\n\n // Handle 'success' as a distinct semantic state for Mutations\n if (\n expectedStates.includes(\"success\") &&\n stateObj.status === \"success\" &&\n !stateObj.isMutating\n ) {\n currentState = \"success\";\n }\n\n if (expectedStates.includes(currentState)) {\n return <>{children}</>;\n }\n\n return null;\n}\n","// src/components/AxTrigger.tsx\nimport { useEffect, useRef, ReactNode } from 'react';\n\ninterface AxTriggerProps {\n onTrigger: () => void;\n once?: boolean;\n children?: ReactNode;\n}\n\nexport const AxTrigger: React.FC<AxTriggerProps> = ({ onTrigger, once = true, children }) => {\n const elementRef = useRef<HTMLDivElement>(null);\n const hasTriggered = useRef(false);\n\n useEffect(() => {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n if (once && hasTriggered.current) return;\n\n onTrigger();\n hasTriggered.current = true;\n\n if (once) observer.unobserve(entry.target);\n }\n });\n }, { threshold: 0.1 });\n\n if (elementRef.current) {\n observer.observe(elementRef.current);\n }\n\n return () => observer.disconnect();\n }, [onTrigger, once]);\n\n return <div ref={elementRef}>{children}</div>;\n};","// FILE: src/hooks/useAxiomMutation.ts\nimport { useState, useCallback, useRef, useEffect } from \"react\";\nimport { useAxiom } from \"./useAxiom\";\nimport {\n AxiomQueryDef,\n AxiomState,\n getNextReqId,\n wasmEngine,\n allocString,\n allocBytes,\n pendingRequests,\n buildRequestPath,\n Route,\n} from \"../utils/core-bridge\";\n\nfunction extractFieldError(error: any, fieldName: string): string | null {\n if (error?.code !== \"ValidationError\" || !error?.details) return null;\n const lines = error.details.split(\"\\n\");\n for (const line of lines) {\n if (line.startsWith(fieldName + \":\"))\n return line.substring(fieldName.length + 1).trim();\n }\n return null;\n}\n\nexport function useAxiomMutation<T, A>(\n mutationFn: (args: A) => AxiomQueryDef<T>,\n) {\n const { isReady, config } = useAxiom();\n const [state, setState] = useState<AxiomState<T>>({\n status: \"idle\",\n data: null,\n error: null,\n isFetching: false,\n isMutating: false,\n source: null,\n });\n const isMounted = useRef(true);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (args: A, options?: { headers?: Record<string, string> }) => {\n if (!isReady || !config) return;\n\n const rawDef = mutationFn(args);\n rawDef.headers = options?.headers; // ✨ Inject dynamic headers!\n\n const reqId = getNextReqId();\n if (isMounted.current)\n setState({\n status: \"loading\",\n data: null,\n error: null,\n isFetching: false,\n isMutating: true,\n source: null,\n });\n\n // FIX: Bypass router lookup!\n const syntheticRoute: Route = {\n id: rawDef.endpointId,\n namespace: rawDef.namespace,\n name: rawDef.name || \"unknown\",\n method: rawDef.method,\n pathTemplate: rawDef.path,\n isStream: !!rawDef.isStream,\n };\n\n const { path } = buildRequestPath(syntheticRoute, rawDef.args);\n\n const isFormUrlEncoded = Object.entries(rawDef.headers || {}).some(\n ([k, v]) =>\n k.toLowerCase() === \"content-type\" &&\n v.includes(\"application/x-www-form-urlencoded\"),\n );\n\n let payloadPtr = 0,\n payloadLen = 0,\n payloadObj = null;\n if (rawDef.payload !== undefined && rawDef.payload !== null) {\n payloadObj = rawDef.serializer\n ? rawDef.serializer(rawDef.payload)\n : rawDef.payload;\n let payloadBytes: Uint8Array;\n\n if (isFormUrlEncoded && typeof payloadObj === \"object\") {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(payloadObj))\n params.append(k, String(v));\n payloadBytes = new TextEncoder().encode(params.toString());\n } else {\n payloadBytes = new TextEncoder().encode(JSON.stringify(payloadObj));\n }\n\n payloadPtr = allocBytes(payloadBytes);\n payloadLen = payloadBytes.length;\n }\n\n if (config.debug) {\n console.groupCollapsed(\n `%c➔ WASM MUTATE [#${reqId}]`,\n `color: #7c3aed; font-weight: bold;`,\n );\n console.log(\"Namespace:\", rawDef.namespace);\n console.log(\"Endpoint ID:\", rawDef.endpointId);\n console.log(\"Path:\", path);\n console.log(\"Payload:\", payloadObj);\n console.groupEnd();\n }\n\n pendingRequests.set(reqId, {\n isStream: !!rawDef.isStream,\n onResponse: (response) => {\n if (!isMounted.current) return;\n\n if (config.debug) {\n const evtName =\n response.eventType === 1\n ? \"NetworkSuccess\"\n : response.eventType === 2\n ? \"CacheHit\"\n : response.eventType === 3\n ? \"CacheHitAndFetching\"\n : response.eventType === 4\n ? \"Error\"\n : \"Complete\";\n console.groupCollapsed(\n `%c← WASM RESP [#${reqId}]`,\n `color: #059669; font-weight: bold;`,\n );\n console.log(\"Event Type:\", evtName);\n if (response.data) console.log(\"Data:\", response.data);\n if (response.error) console.log(\"Error:\", response.error);\n console.groupEnd();\n }\n\n if (response.eventType === 4) {\n setState({\n status: \"error\",\n error: response.error || null,\n isFetching: false,\n isMutating: false,\n data: null,\n source: null,\n });\n return;\n }\n if (response.data) {\n try {\n let source: \"cache\" | \"network\" = \"network\";\n if (response.eventType === 2 || response.eventType === 3)\n source = \"cache\";\n\n setState({\n status: \"success\",\n data: rawDef.decoder(response.data),\n error: null,\n isFetching: false,\n isMutating: false,\n source,\n });\n } catch (e) {\n setState({\n status: \"error\",\n error: {\n message: \"Decoding failed\",\n details: String(e),\n } as any,\n isFetching: false,\n isMutating: false,\n data: null,\n source: null,\n });\n }\n }\n },\n onComplete: () => {\n if (isMounted.current)\n setState((prev) => ({\n ...prev,\n isMutating: false,\n isFetching: false,\n }));\n },\n });\n\n const nsStr = allocString(rawDef.namespace);\n const mStr = allocString(rawDef.method);\n const pStr = allocString(path);\n const tpStr = allocString(\"\");\n const hStr = allocString(\n rawDef.headers ? JSON.stringify(rawDef.headers) : \"\",\n );\n\n wasmEngine.axiom_wasm_call(\n reqId,\n nsStr.ptr,\n nsStr.len,\n rawDef.endpointId,\n mStr.ptr,\n mStr.len,\n pStr.ptr,\n pStr.len,\n tpStr.ptr,\n tpStr.len,\n hStr.ptr,\n hStr.len,\n payloadPtr,\n payloadLen,\n );\n\n wasmEngine.axiom_free_memory(nsStr.ptr, nsStr.len);\n wasmEngine.axiom_free_memory(mStr.ptr, mStr.len);\n wasmEngine.axiom_free_memory(pStr.ptr, pStr.len);\n wasmEngine.axiom_free_memory(tpStr.ptr, tpStr.len);\n wasmEngine.axiom_free_memory(hStr.ptr, hStr.len);\n },\n [isReady, config, mutationFn],\n );\n\n return {\n execute,\n state,\n data: state.data,\n isMutating: state.isMutating,\n error: state.error,\n getFieldError: (fieldName: string) =>\n extractFieldError(state.error, fieldName),\n };\n}\n"],"mappings":"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","names":["createContext","useEffect","useContext","useContext","useEffect","jsx","useContext","Fragment","jsx","useContext","useEffect","useRef","jsx","useState","useCallback","useRef","useEffect","useState","useRef","useEffect","useCallback"]}
|