@almadar/ui 2.7.0 → 2.9.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/{chunk-VJP2HCLY.js → chunk-NES4SBB7.js} +6607 -3398
- package/dist/chunk-UVMBFEMO.js +375 -0
- package/dist/components/index.d.ts +3646 -3091
- package/dist/components/index.js +23 -1843
- package/dist/hooks/index.js +2 -2
- package/dist/lib/index.js +1 -1
- package/dist/providers/index.js +5 -375
- package/dist/runtime/index.css +1156 -0
- package/dist/runtime/index.d.ts +280 -0
- package/dist/runtime/index.js +471 -0
- package/package.json +6 -1
- package/dist/{chunk-RPYMP7ZC.js → chunk-A5J5CNCU.js} +26 -26
- package/dist/{chunk-2QM732NQ.js → chunk-GTIAVPI5.js} +1 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { SuspenseConfigProvider } from './chunk-NES4SBB7.js';
|
|
2
|
+
import { ThemeProvider } from './chunk-DKQN5FVU.js';
|
|
3
|
+
import { SelectionProvider, EntityDataProvider } from './chunk-WGJIL4YR.js';
|
|
4
|
+
import { useEventBus, EventBusProvider } from './chunk-YXZM3WCF.js';
|
|
5
|
+
import { recordTransition, registerCheck, bindEventBus, bindTraitStateGetter } from './chunk-A5J5CNCU.js';
|
|
6
|
+
import { useOfflineExecutor } from './chunk-K2D5D3WK.js';
|
|
7
|
+
import { createContext, useState, useCallback, useMemo, useContext, useRef, useEffect } from 'react';
|
|
8
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var FetchedDataContext = createContext(null);
|
|
11
|
+
function FetchedDataProvider({
|
|
12
|
+
initialData,
|
|
13
|
+
children
|
|
14
|
+
}) {
|
|
15
|
+
const [state, setState] = useState(() => ({
|
|
16
|
+
data: initialData || {},
|
|
17
|
+
fetchedAt: {},
|
|
18
|
+
loading: false,
|
|
19
|
+
error: null
|
|
20
|
+
}));
|
|
21
|
+
const getData = useCallback(
|
|
22
|
+
(entityName) => {
|
|
23
|
+
return state.data[entityName] || [];
|
|
24
|
+
},
|
|
25
|
+
[state.data]
|
|
26
|
+
);
|
|
27
|
+
const getById = useCallback(
|
|
28
|
+
(entityName, id) => {
|
|
29
|
+
const records = state.data[entityName];
|
|
30
|
+
return records?.find((r) => r.id === id);
|
|
31
|
+
},
|
|
32
|
+
[state.data]
|
|
33
|
+
);
|
|
34
|
+
const hasData = useCallback(
|
|
35
|
+
(entityName) => {
|
|
36
|
+
return entityName in state.data && state.data[entityName].length > 0;
|
|
37
|
+
},
|
|
38
|
+
[state.data]
|
|
39
|
+
);
|
|
40
|
+
const getFetchedAt = useCallback(
|
|
41
|
+
(entityName) => {
|
|
42
|
+
return state.fetchedAt[entityName];
|
|
43
|
+
},
|
|
44
|
+
[state.fetchedAt]
|
|
45
|
+
);
|
|
46
|
+
const setData = useCallback((data) => {
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
setState((prev) => ({
|
|
49
|
+
...prev,
|
|
50
|
+
data: {
|
|
51
|
+
...prev.data,
|
|
52
|
+
...data
|
|
53
|
+
},
|
|
54
|
+
fetchedAt: {
|
|
55
|
+
...prev.fetchedAt,
|
|
56
|
+
...Object.keys(data).reduce(
|
|
57
|
+
(acc, key) => ({ ...acc, [key]: now }),
|
|
58
|
+
{}
|
|
59
|
+
)
|
|
60
|
+
},
|
|
61
|
+
loading: false,
|
|
62
|
+
error: null
|
|
63
|
+
}));
|
|
64
|
+
}, []);
|
|
65
|
+
const clearData = useCallback(() => {
|
|
66
|
+
setState((prev) => ({
|
|
67
|
+
...prev,
|
|
68
|
+
data: {},
|
|
69
|
+
fetchedAt: {}
|
|
70
|
+
}));
|
|
71
|
+
}, []);
|
|
72
|
+
const clearEntity = useCallback((entityName) => {
|
|
73
|
+
setState((prev) => {
|
|
74
|
+
const newData = { ...prev.data };
|
|
75
|
+
const newFetchedAt = { ...prev.fetchedAt };
|
|
76
|
+
delete newData[entityName];
|
|
77
|
+
delete newFetchedAt[entityName];
|
|
78
|
+
return {
|
|
79
|
+
...prev,
|
|
80
|
+
data: newData,
|
|
81
|
+
fetchedAt: newFetchedAt
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}, []);
|
|
85
|
+
const setLoading = useCallback((loading) => {
|
|
86
|
+
setState((prev) => ({ ...prev, loading }));
|
|
87
|
+
}, []);
|
|
88
|
+
const setError = useCallback((error) => {
|
|
89
|
+
setState((prev) => ({ ...prev, error, loading: false }));
|
|
90
|
+
}, []);
|
|
91
|
+
const contextValue = useMemo(
|
|
92
|
+
() => ({
|
|
93
|
+
getData,
|
|
94
|
+
getById,
|
|
95
|
+
hasData,
|
|
96
|
+
getFetchedAt,
|
|
97
|
+
setData,
|
|
98
|
+
clearData,
|
|
99
|
+
clearEntity,
|
|
100
|
+
loading: state.loading,
|
|
101
|
+
setLoading,
|
|
102
|
+
error: state.error,
|
|
103
|
+
setError
|
|
104
|
+
}),
|
|
105
|
+
[
|
|
106
|
+
getData,
|
|
107
|
+
getById,
|
|
108
|
+
hasData,
|
|
109
|
+
getFetchedAt,
|
|
110
|
+
setData,
|
|
111
|
+
clearData,
|
|
112
|
+
clearEntity,
|
|
113
|
+
state.loading,
|
|
114
|
+
setLoading,
|
|
115
|
+
state.error,
|
|
116
|
+
setError
|
|
117
|
+
]
|
|
118
|
+
);
|
|
119
|
+
return /* @__PURE__ */ jsx(FetchedDataContext.Provider, { value: contextValue, children });
|
|
120
|
+
}
|
|
121
|
+
function useFetchedDataContext() {
|
|
122
|
+
return useContext(FetchedDataContext);
|
|
123
|
+
}
|
|
124
|
+
function useFetchedData() {
|
|
125
|
+
const context = useContext(FetchedDataContext);
|
|
126
|
+
if (!context) {
|
|
127
|
+
return {
|
|
128
|
+
getData: () => [],
|
|
129
|
+
getById: () => void 0,
|
|
130
|
+
hasData: () => false,
|
|
131
|
+
getFetchedAt: () => void 0,
|
|
132
|
+
setData: () => {
|
|
133
|
+
},
|
|
134
|
+
clearData: () => {
|
|
135
|
+
},
|
|
136
|
+
clearEntity: () => {
|
|
137
|
+
},
|
|
138
|
+
loading: false,
|
|
139
|
+
setLoading: () => {
|
|
140
|
+
},
|
|
141
|
+
error: null,
|
|
142
|
+
setError: () => {
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return context;
|
|
147
|
+
}
|
|
148
|
+
function useFetchedEntity(entityName) {
|
|
149
|
+
const context = useFetchedData();
|
|
150
|
+
return {
|
|
151
|
+
/** All fetched records for this entity */
|
|
152
|
+
records: context.getData(entityName),
|
|
153
|
+
/** Get a record by ID */
|
|
154
|
+
getById: (id) => context.getById(entityName, id),
|
|
155
|
+
/** Whether data has been fetched for this entity */
|
|
156
|
+
hasData: context.hasData(entityName),
|
|
157
|
+
/** When data was last fetched */
|
|
158
|
+
fetchedAt: context.getFetchedAt(entityName),
|
|
159
|
+
/** Whether data is loading */
|
|
160
|
+
loading: context.loading,
|
|
161
|
+
/** Current error */
|
|
162
|
+
error: context.error
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
var DISPATCH_SUFFIX = ":DISPATCH";
|
|
166
|
+
var SUCCESS_SUFFIX = ":SUCCESS";
|
|
167
|
+
var ERROR_SUFFIX = ":ERROR";
|
|
168
|
+
function parseLifecycleEvent(type) {
|
|
169
|
+
if (type.endsWith(DISPATCH_SUFFIX)) {
|
|
170
|
+
const traitName = type.slice(0, -DISPATCH_SUFFIX.length);
|
|
171
|
+
if (traitName) return { kind: "dispatch", traitName };
|
|
172
|
+
} else if (type.endsWith(SUCCESS_SUFFIX)) {
|
|
173
|
+
const rest = type.slice(0, -SUCCESS_SUFFIX.length);
|
|
174
|
+
const colonIdx = rest.indexOf(":");
|
|
175
|
+
if (colonIdx > 0) {
|
|
176
|
+
return {
|
|
177
|
+
kind: "success",
|
|
178
|
+
traitName: rest.slice(0, colonIdx),
|
|
179
|
+
event: rest.slice(colonIdx + 1)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
} else if (type.endsWith(ERROR_SUFFIX)) {
|
|
183
|
+
const rest = type.slice(0, -ERROR_SUFFIX.length);
|
|
184
|
+
const colonIdx = rest.indexOf(":");
|
|
185
|
+
if (colonIdx > 0) {
|
|
186
|
+
return {
|
|
187
|
+
kind: "error",
|
|
188
|
+
traitName: rest.slice(0, colonIdx),
|
|
189
|
+
event: rest.slice(colonIdx + 1)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
function VerificationProvider({
|
|
196
|
+
children,
|
|
197
|
+
enabled,
|
|
198
|
+
runtimeManager,
|
|
199
|
+
traitStateGetter
|
|
200
|
+
}) {
|
|
201
|
+
const isEnabled = enabled ?? (typeof process !== "undefined" && process.env?.NODE_ENV !== "production");
|
|
202
|
+
const eventBus = useEventBus();
|
|
203
|
+
const pendingRef = useRef(/* @__PURE__ */ new Map());
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (!isEnabled) return;
|
|
206
|
+
if (!eventBus.onAny) return;
|
|
207
|
+
const unsub = eventBus.onAny((evt) => {
|
|
208
|
+
const parsed = parseLifecycleEvent(evt.type);
|
|
209
|
+
if (!parsed) return;
|
|
210
|
+
const payload = evt.payload ?? {};
|
|
211
|
+
if (parsed.kind === "dispatch") {
|
|
212
|
+
const key = `${parsed.traitName}:${String(payload["event"] ?? "")}`;
|
|
213
|
+
pendingRef.current.set(key, {
|
|
214
|
+
traitName: parsed.traitName,
|
|
215
|
+
event: String(payload["event"] ?? ""),
|
|
216
|
+
from: payload["currentState"],
|
|
217
|
+
timestamp: evt.timestamp
|
|
218
|
+
});
|
|
219
|
+
} else if (parsed.kind === "success" && parsed.event) {
|
|
220
|
+
const key = `${parsed.traitName}:${parsed.event}`;
|
|
221
|
+
const pending = pendingRef.current.get(key);
|
|
222
|
+
pendingRef.current.delete(key);
|
|
223
|
+
const newState = payload["newState"] ?? payload["state"] ?? "unknown";
|
|
224
|
+
const effects = Array.isArray(payload["clientEffects"]) ? payload["clientEffects"].map((e) => ({
|
|
225
|
+
type: String(e["type"] ?? "unknown"),
|
|
226
|
+
args: Array.isArray(e["args"]) ? e["args"] : [],
|
|
227
|
+
status: "executed"
|
|
228
|
+
})) : [];
|
|
229
|
+
recordTransition({
|
|
230
|
+
traitName: parsed.traitName,
|
|
231
|
+
from: pending?.from ?? "unknown",
|
|
232
|
+
to: newState,
|
|
233
|
+
event: parsed.event,
|
|
234
|
+
effects,
|
|
235
|
+
timestamp: Date.now()
|
|
236
|
+
});
|
|
237
|
+
} else if (parsed.kind === "error" && parsed.event) {
|
|
238
|
+
const key = `${parsed.traitName}:${parsed.event}`;
|
|
239
|
+
const pending = pendingRef.current.get(key);
|
|
240
|
+
pendingRef.current.delete(key);
|
|
241
|
+
const errorMsg = payload["error"] ?? "Unknown error";
|
|
242
|
+
recordTransition({
|
|
243
|
+
traitName: parsed.traitName,
|
|
244
|
+
from: pending?.from ?? "unknown",
|
|
245
|
+
to: pending?.from ?? "unknown",
|
|
246
|
+
// state didn't change on error
|
|
247
|
+
event: parsed.event,
|
|
248
|
+
effects: [{
|
|
249
|
+
type: "server-call",
|
|
250
|
+
args: [],
|
|
251
|
+
status: "failed",
|
|
252
|
+
error: errorMsg
|
|
253
|
+
}],
|
|
254
|
+
timestamp: Date.now()
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
registerCheck(
|
|
259
|
+
"verification-provider",
|
|
260
|
+
"VerificationProvider active (compiled path)",
|
|
261
|
+
"pass"
|
|
262
|
+
);
|
|
263
|
+
return unsub;
|
|
264
|
+
}, [isEnabled, eventBus]);
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
if (!isEnabled) return;
|
|
267
|
+
if (!runtimeManager) return;
|
|
268
|
+
runtimeManager.setObserver({
|
|
269
|
+
onTransition(trace) {
|
|
270
|
+
recordTransition({
|
|
271
|
+
traitName: trace.traitName,
|
|
272
|
+
from: trace.from,
|
|
273
|
+
to: trace.to,
|
|
274
|
+
event: trace.event,
|
|
275
|
+
guardResult: trace.guardResult,
|
|
276
|
+
effects: trace.effects,
|
|
277
|
+
timestamp: Date.now()
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
registerCheck(
|
|
282
|
+
"verification-provider",
|
|
283
|
+
"VerificationProvider active (runtime path)",
|
|
284
|
+
"pass"
|
|
285
|
+
);
|
|
286
|
+
}, [isEnabled, runtimeManager]);
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
if (!isEnabled) return;
|
|
289
|
+
bindEventBus(eventBus);
|
|
290
|
+
}, [isEnabled, eventBus]);
|
|
291
|
+
useEffect(() => {
|
|
292
|
+
if (!isEnabled) return;
|
|
293
|
+
if (traitStateGetter) {
|
|
294
|
+
bindTraitStateGetter(traitStateGetter);
|
|
295
|
+
} else if (runtimeManager?.getState) {
|
|
296
|
+
const mgr = runtimeManager;
|
|
297
|
+
bindTraitStateGetter((traitName) => mgr.getState(traitName));
|
|
298
|
+
}
|
|
299
|
+
}, [isEnabled, traitStateGetter, runtimeManager]);
|
|
300
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
301
|
+
}
|
|
302
|
+
VerificationProvider.displayName = "VerificationProvider";
|
|
303
|
+
function FetchedDataBridge({ children }) {
|
|
304
|
+
const fetchedData = useFetchedData();
|
|
305
|
+
const adapter = useMemo(() => ({
|
|
306
|
+
getData: (entity) => fetchedData.getData(entity),
|
|
307
|
+
getById: (entity, id) => fetchedData.getById(entity, id),
|
|
308
|
+
isLoading: fetchedData.loading,
|
|
309
|
+
error: fetchedData.error
|
|
310
|
+
}), [fetchedData.getData, fetchedData.getById, fetchedData.loading, fetchedData.error]);
|
|
311
|
+
return /* @__PURE__ */ jsx(EntityDataProvider, { adapter, children });
|
|
312
|
+
}
|
|
313
|
+
function OrbitalProvider({
|
|
314
|
+
children,
|
|
315
|
+
themes,
|
|
316
|
+
defaultTheme = "wireframe",
|
|
317
|
+
defaultMode = "system",
|
|
318
|
+
targetRef,
|
|
319
|
+
skipTheme = false,
|
|
320
|
+
debug = false,
|
|
321
|
+
initialData,
|
|
322
|
+
suspense = false,
|
|
323
|
+
verification
|
|
324
|
+
}) {
|
|
325
|
+
const suspenseConfig = useMemo(
|
|
326
|
+
() => ({ enabled: suspense }),
|
|
327
|
+
[suspense]
|
|
328
|
+
);
|
|
329
|
+
const inner = /* @__PURE__ */ jsx(FetchedDataProvider, { initialData, children: /* @__PURE__ */ jsx(FetchedDataBridge, { children: /* @__PURE__ */ jsx(EventBusProvider, { debug, children: /* @__PURE__ */ jsx(VerificationProvider, { enabled: verification, children: /* @__PURE__ */ jsx(SelectionProvider, { debug, children: /* @__PURE__ */ jsx(SuspenseConfigProvider, { config: suspenseConfig, children }) }) }) }) }) });
|
|
330
|
+
if (skipTheme) {
|
|
331
|
+
return inner;
|
|
332
|
+
}
|
|
333
|
+
return /* @__PURE__ */ jsx(
|
|
334
|
+
ThemeProvider,
|
|
335
|
+
{
|
|
336
|
+
themes,
|
|
337
|
+
defaultTheme,
|
|
338
|
+
defaultMode,
|
|
339
|
+
targetRef,
|
|
340
|
+
children: inner
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
OrbitalProvider.displayName = "OrbitalProvider";
|
|
345
|
+
var OfflineModeContext = createContext(null);
|
|
346
|
+
function OfflineModeProvider({
|
|
347
|
+
children,
|
|
348
|
+
...executorOptions
|
|
349
|
+
}) {
|
|
350
|
+
const [forceOffline, setForceOffline] = useState(false);
|
|
351
|
+
const executor = useOfflineExecutor(executorOptions);
|
|
352
|
+
const effectivelyOffline = executor.isOffline || forceOffline;
|
|
353
|
+
const contextValue = useMemo(
|
|
354
|
+
() => ({
|
|
355
|
+
...executor,
|
|
356
|
+
forceOffline,
|
|
357
|
+
setForceOffline,
|
|
358
|
+
effectivelyOffline
|
|
359
|
+
}),
|
|
360
|
+
[executor, forceOffline, effectivelyOffline]
|
|
361
|
+
);
|
|
362
|
+
return /* @__PURE__ */ jsx(OfflineModeContext.Provider, { value: contextValue, children });
|
|
363
|
+
}
|
|
364
|
+
function useOfflineMode() {
|
|
365
|
+
const context = useContext(OfflineModeContext);
|
|
366
|
+
if (!context) {
|
|
367
|
+
throw new Error("useOfflineMode must be used within OfflineModeProvider");
|
|
368
|
+
}
|
|
369
|
+
return context;
|
|
370
|
+
}
|
|
371
|
+
function useOptionalOfflineMode() {
|
|
372
|
+
return useContext(OfflineModeContext);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export { FetchedDataContext, FetchedDataProvider, OfflineModeProvider, OrbitalProvider, VerificationProvider, useFetchedData, useFetchedDataContext, useFetchedEntity, useOfflineMode, useOptionalOfflineMode };
|