@mdxui/do 2.1.1

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.
Files changed (42) hide show
  1. package/README.md +412 -0
  2. package/dist/__test-utils__/index.d.ts +399 -0
  3. package/dist/__test-utils__/index.js +34641 -0
  4. package/dist/__test-utils__/index.js.map +1 -0
  5. package/dist/agents-xcIn2dUB.d.ts +832 -0
  6. package/dist/chunk-EEDMN7UF.js +1351 -0
  7. package/dist/chunk-EEDMN7UF.js.map +1 -0
  8. package/dist/chunk-G3PMV62Z.js +33 -0
  9. package/dist/chunk-G3PMV62Z.js.map +1 -0
  10. package/dist/chunk-GGO5GW72.js +695 -0
  11. package/dist/chunk-GGO5GW72.js.map +1 -0
  12. package/dist/chunk-GKSP5RIA.js +3 -0
  13. package/dist/chunk-GKSP5RIA.js.map +1 -0
  14. package/dist/chunk-NXPXL5NA.js +3789 -0
  15. package/dist/chunk-NXPXL5NA.js.map +1 -0
  16. package/dist/chunk-PC5FJY6M.js +20 -0
  17. package/dist/chunk-PC5FJY6M.js.map +1 -0
  18. package/dist/chunk-XF6LKY2M.js +445 -0
  19. package/dist/chunk-XF6LKY2M.js.map +1 -0
  20. package/dist/components/index.d.ts +813 -0
  21. package/dist/components/index.js +8 -0
  22. package/dist/components/index.js.map +1 -0
  23. package/dist/do-CaQVueZw.d.ts +195 -0
  24. package/dist/hooks/index.d.ts +801 -0
  25. package/dist/hooks/index.js +7 -0
  26. package/dist/hooks/index.js.map +1 -0
  27. package/dist/index.d.ts +1012 -0
  28. package/dist/index.js +843 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/magic-string.es-J7BYFTTJ.js +1307 -0
  31. package/dist/magic-string.es-J7BYFTTJ.js.map +1 -0
  32. package/dist/providers/index.d.ts +90 -0
  33. package/dist/providers/index.js +5 -0
  34. package/dist/providers/index.js.map +1 -0
  35. package/dist/schemas/index.d.ts +206 -0
  36. package/dist/schemas/index.js +262 -0
  37. package/dist/schemas/index.js.map +1 -0
  38. package/dist/thing-DtI25yZh.d.ts +902 -0
  39. package/dist/types/index.d.ts +7681 -0
  40. package/dist/types/index.js +5 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/package.json +94 -0
package/dist/index.js ADDED
@@ -0,0 +1,843 @@
1
+ export { AgentExecutePanel, AgentFeedbackPanel, AgentHistoryTable, AgentsGrid, ConfirmDialog, DOErrorBoundary, DOHeader, DOShell, DOSidebar, DOSidebarHeader, StatsCards, SyncStatusIndicator, ThingForm, ThingFormDialog, ThingsList, ThingsPage, ToastContainer, ToastProvider, TriggerWorkflowDialog, WorkflowExecutionView, WorkflowsList, defaultNavItems, defaultStats, useErrorBoundary, useShell, useToast } from './chunk-NXPXL5NA.js';
2
+ export { APIError, AdminError, AdminProvider, DO, AdminProvider2 as DotdoAdminProvider, DotdoDataProvider, NetworkError, SyncError, ValidationError, agentsKeys, createCacheKey, createRPCClient, createResourceFromSchema, formatAdminError, inferFieldsFromSchema, invalidateCache, isAPIError, isAdminError, isNetworkError, isSyncError, isValidationError, relationshipsKeys, thingsKeys, use$, useAdminContext, useAgent, useAgentExecution, useAgentExecutions, useAgentMetrics, useAgents, useCancelExecution, useCreateAgent, useCreateRelationship, useCreateThing, useCreateWorkflow, useDOAdmin, useDOContext, useDOResource, useDeleteAgent, useDeleteRelationship, useDeleteThing, useDeleteWorkflow, useEntityRelationships, useExecuteAgent, useGraphStats, useGraphTraversal, useIsDOEnabled, useOptimisticUpdate, useRPCClient, useRelationships, useSubmitAgentFeedback, useThing, useThingVersions, useThings, useTriggerWorkflow, useTypeStats, useUpdateAgent, useUpdateThing, useUpdateWorkflow, useWorkflow, useWorkflowExecution, useWorkflowExecutions, useWorkflows, workflowsKeys } from './chunk-EEDMN7UF.js';
3
+ import './chunk-GKSP5RIA.js';
4
+ export { isAppError, isNotFoundError, isPermissionError, isRateLimitError, isValidationErrorData } from './chunk-PC5FJY6M.js';
5
+ export { AgentArtifactResponseSchema, AgentClassificationResponseSchema, AgentExecuteInputSchema, AgentExecutionFilterSchema, AgentExecutionResponseSchema, AgentFeedbackInputSchema, AgentFeedbackResponseSchema, AgentFilterSchema, AgentGuardrailResponseSchema, AgentHandoffResponseSchema, AgentInputResponseSchema, AgentMetricsResponseSchema, AgentOutputResponseSchema, AgentResponseSchema, AgentTraceResponseSchema, AgentTypeResponseSchema, CharacterBibleResponseSchema, CompensationConfigResponseSchema, DateResponseSchema, EntityReferenceResponseSchema, EntityReferenceSchema, EntityRelationshipsResultResponseSchema, ErrorHandlingConfigResponseSchema, ExecutionContextResponseSchema, ExecutionErrorResponseSchema, ExecutionFilterSchema, GraphPathResponseSchema, GraphPatternSchema, GraphStatsResponseSchema, GraphTraversalResultResponseSchema, GuardrailViolationResponseSchema, HandoffRuleResponseSchema, OptionalDateResponseSchema, PaginatedResultResponseSchema, PartialEntityReferenceSchema, RelationshipCreateInputSchema, RelationshipFilterSchema, RelationshipMetadataResponseSchema, RelationshipMetadataSchema, RelationshipResponseSchema, RetryConfigResponseSchema, StepConfigResponseSchema, StepExecutionResponseSchema, ThingCreateInputSchema, ThingDataSchema, ThingDeleteOptionsSchema, ThingFilterSchema, ThingPaginationSchema, ThingQueryResultResponseSchema, ThingResponseSchema, ThingSortSchema, ThingUpdateInputSchema, ThingVersionResponseSchema, TokenUsageResponseSchema, TriggerDataResponseSchema, TypeStatsResponseSchema, WorkflowConfigResponseSchema, WorkflowExecutionResponseSchema, WorkflowFilterSchema, WorkflowResponseSchema, WorkflowStepResponseSchema, WorkflowTriggerInputSchema, WorkflowTriggerResponseSchema } from './chunk-GGO5GW72.js';
6
+ import { useDO, DOProvider, fetchWithTimeout, DEFAULT_REQUEST_TIMEOUT } from './chunk-XF6LKY2M.js';
7
+ export { DOProvider, camelToTitle, capitalize, cn, debounce, fetchWithTimeout, formatBytes, formatDate, formatDateTime, formatDuration, formatNumber, formatRelativeTime, formatSemanticId, generateId, groupBy, parseSemanticId, truncate, useDO, useDOUrls, useDataProviderSafe, useSyncStatus } from './chunk-XF6LKY2M.js';
8
+ import './chunk-G3PMV62Z.js';
9
+ import * as React3 from 'react';
10
+ import { DataProviderProvider, AuthProvider, useAuth, AppShell, AppBreadcrumbs, NavUser, NavMain } from '@mdxui/app';
11
+ import { AdminWithoutRouter, Admin, Resource } from '@mdxui/admin';
12
+ import { jsx, jsxs } from 'react/jsx-runtime';
13
+ import { Database, Settings, Zap, Bot, Workflow, GitBranch, Box, Users, FileText, Home } from 'lucide-react';
14
+
15
+ function createDoDataProvider(apiEndpoint, authToken, namespace = "default", rpcUrl) {
16
+ const headers = {
17
+ "Content-Type": "application/json",
18
+ ...authToken ? { Authorization: `Bearer ${authToken}` } : {}
19
+ };
20
+ async function rpcCall(method, args = []) {
21
+ if (!rpcUrl) {
22
+ throw new Error("RPC URL not configured");
23
+ }
24
+ const response = await fetchWithTimeout(rpcUrl, {
25
+ method: "POST",
26
+ headers,
27
+ body: JSON.stringify({
28
+ id: crypto.randomUUID(),
29
+ type: "call",
30
+ calls: [
31
+ {
32
+ promiseId: "p-1",
33
+ target: { type: "root" },
34
+ method,
35
+ args: args.map((arg) => ({ type: "value", value: arg }))
36
+ }
37
+ ]
38
+ }),
39
+ timeout: DEFAULT_REQUEST_TIMEOUT
40
+ });
41
+ if (!response.ok) {
42
+ throw new Error(`RPC error: ${response.status}`);
43
+ }
44
+ const json = await response.json();
45
+ if (json.type === "error") {
46
+ throw new Error(json.error?.message ?? "RPC error");
47
+ }
48
+ if (json.results?.[0]?.type === "error") {
49
+ throw new Error(json.results[0].error?.message ?? "RPC error");
50
+ }
51
+ return json.results?.[0]?.value;
52
+ }
53
+ function resourceToType(resource) {
54
+ return resource.charAt(0).toUpperCase() + resource.slice(1);
55
+ }
56
+ function normalizeRecord(item, fallbackId) {
57
+ return {
58
+ ...item,
59
+ id: item.id ?? item.$id ?? fallbackId
60
+ };
61
+ }
62
+ const dataProvider = {
63
+ // =========================================================================
64
+ // GetList
65
+ // =========================================================================
66
+ getList: async (resource, params) => {
67
+ const type = resourceToType(resource);
68
+ const { pagination, sort, filter } = params ?? {};
69
+ if (rpcUrl) {
70
+ const result = await rpcCall("Thing.list", [{
71
+ filter: { type, ns: namespace, ...filter },
72
+ sort: sort ? { field: sort.field, order: sort.order.toLowerCase() } : void 0,
73
+ pagination: pagination ? { page: pagination.page, perPage: pagination.perPage } : void 0
74
+ }]);
75
+ return {
76
+ data: result.items.map((item) => normalizeRecord(item)),
77
+ total: result.total
78
+ };
79
+ } else {
80
+ const urlParams = new URLSearchParams();
81
+ urlParams.set("type", type);
82
+ urlParams.set("ns", namespace);
83
+ if (pagination) {
84
+ urlParams.set("page", pagination.page.toString());
85
+ urlParams.set("perPage", pagination.perPage.toString());
86
+ }
87
+ if (sort) {
88
+ urlParams.set("sortField", sort.field);
89
+ urlParams.set("sortOrder", sort.order);
90
+ }
91
+ if (filter) {
92
+ Object.entries(filter).forEach(([key, value]) => {
93
+ if (value !== void 0 && value !== null) {
94
+ urlParams.set(`filter[${key}]`, String(value));
95
+ }
96
+ });
97
+ }
98
+ const response = await fetchWithTimeout(`${apiEndpoint}/things?${urlParams}`, {
99
+ headers,
100
+ timeout: DEFAULT_REQUEST_TIMEOUT
101
+ });
102
+ if (!response.ok) {
103
+ throw new Error(`Failed to fetch ${resource}: ${response.status}`);
104
+ }
105
+ const result = await response.json();
106
+ const items = result.items ?? result.data ?? [];
107
+ return {
108
+ data: items.map((item) => normalizeRecord(item)),
109
+ total: result.total ?? items.length
110
+ };
111
+ }
112
+ },
113
+ // =========================================================================
114
+ // GetOne
115
+ // =========================================================================
116
+ getOne: async (resource, params) => {
117
+ const type = resourceToType(resource);
118
+ const { id } = params;
119
+ if (rpcUrl) {
120
+ const result = await rpcCall("Thing.get", [{
121
+ ns: namespace,
122
+ type,
123
+ id: String(id)
124
+ }]);
125
+ return {
126
+ data: normalizeRecord(result, id)
127
+ };
128
+ } else {
129
+ const response = await fetchWithTimeout(
130
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/${encodeURIComponent(String(id))}`,
131
+ { headers, timeout: DEFAULT_REQUEST_TIMEOUT }
132
+ );
133
+ if (!response.ok) {
134
+ throw new Error(`Failed to fetch ${resource}/${id}: ${response.status}`);
135
+ }
136
+ const result = await response.json();
137
+ return { data: normalizeRecord(result, id) };
138
+ }
139
+ },
140
+ // =========================================================================
141
+ // GetMany
142
+ // =========================================================================
143
+ getMany: async (resource, params) => {
144
+ const type = resourceToType(resource);
145
+ const { ids } = params;
146
+ const results = await Promise.all(
147
+ ids.map(async (id) => {
148
+ try {
149
+ if (rpcUrl) {
150
+ const result = await rpcCall("Thing.get", [{
151
+ ns: namespace,
152
+ type,
153
+ id: String(id)
154
+ }]);
155
+ return normalizeRecord(result, id);
156
+ } else {
157
+ const response = await fetchWithTimeout(
158
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/${encodeURIComponent(String(id))}`,
159
+ { headers, timeout: DEFAULT_REQUEST_TIMEOUT }
160
+ );
161
+ if (!response.ok) return null;
162
+ const result = await response.json();
163
+ return normalizeRecord(result, id);
164
+ }
165
+ } catch {
166
+ return null;
167
+ }
168
+ })
169
+ );
170
+ return {
171
+ data: results.filter((item) => item !== null)
172
+ };
173
+ },
174
+ // =========================================================================
175
+ // Create
176
+ // =========================================================================
177
+ create: async (resource, params) => {
178
+ const type = resourceToType(resource);
179
+ const { data } = params;
180
+ if (rpcUrl) {
181
+ const result = await rpcCall("Thing.create", [{
182
+ ns: namespace,
183
+ type,
184
+ name: data.name ?? `${type}-${Date.now()}`,
185
+ data
186
+ }]);
187
+ return {
188
+ data: normalizeRecord(result)
189
+ };
190
+ } else {
191
+ const response = await fetchWithTimeout(`${apiEndpoint}/things`, {
192
+ method: "POST",
193
+ headers,
194
+ body: JSON.stringify({
195
+ ns: namespace,
196
+ type,
197
+ name: data.name ?? `${type}-${Date.now()}`,
198
+ data
199
+ }),
200
+ timeout: DEFAULT_REQUEST_TIMEOUT
201
+ });
202
+ if (!response.ok) {
203
+ throw new Error(`Failed to create ${resource}: ${response.status}`);
204
+ }
205
+ const result = await response.json();
206
+ return { data: normalizeRecord(result) };
207
+ }
208
+ },
209
+ // =========================================================================
210
+ // Update
211
+ // =========================================================================
212
+ update: async (resource, params) => {
213
+ const type = resourceToType(resource);
214
+ const { id, data } = params;
215
+ if (rpcUrl) {
216
+ const result = await rpcCall("Thing.update", [{
217
+ ns: namespace,
218
+ type,
219
+ id: String(id),
220
+ data
221
+ }]);
222
+ return {
223
+ data: normalizeRecord(result, id)
224
+ };
225
+ } else {
226
+ const response = await fetchWithTimeout(
227
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/${encodeURIComponent(String(id))}`,
228
+ {
229
+ method: "PATCH",
230
+ headers,
231
+ body: JSON.stringify({ data }),
232
+ timeout: DEFAULT_REQUEST_TIMEOUT
233
+ }
234
+ );
235
+ if (!response.ok) {
236
+ throw new Error(`Failed to update ${resource}/${id}: ${response.status}`);
237
+ }
238
+ const result = await response.json();
239
+ return { data: normalizeRecord(result, id) };
240
+ }
241
+ },
242
+ // =========================================================================
243
+ // Delete
244
+ // =========================================================================
245
+ delete: async (resource, params) => {
246
+ const type = resourceToType(resource);
247
+ const { id } = params;
248
+ if (rpcUrl) {
249
+ await rpcCall("Thing.delete", [{
250
+ ns: namespace,
251
+ type,
252
+ id: String(id),
253
+ hard: false
254
+ }]);
255
+ return { data: { id } };
256
+ } else {
257
+ const response = await fetchWithTimeout(
258
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/${encodeURIComponent(String(id))}`,
259
+ {
260
+ method: "DELETE",
261
+ headers,
262
+ timeout: DEFAULT_REQUEST_TIMEOUT
263
+ }
264
+ );
265
+ if (!response.ok) {
266
+ throw new Error(`Failed to delete ${resource}/${id}: ${response.status}`);
267
+ }
268
+ return { data: { id } };
269
+ }
270
+ },
271
+ // =========================================================================
272
+ // DO-Specific Methods
273
+ // =========================================================================
274
+ /**
275
+ * Get type statistics
276
+ */
277
+ getTypeStats: async (resource) => {
278
+ const type = resourceToType(resource);
279
+ if (rpcUrl) {
280
+ const result = await rpcCall("Thing.stats", [{ ns: namespace, type }]);
281
+ return result;
282
+ } else {
283
+ const response = await fetchWithTimeout(
284
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/stats`,
285
+ { headers, timeout: DEFAULT_REQUEST_TIMEOUT }
286
+ );
287
+ if (!response.ok) {
288
+ throw new Error(`Failed to get stats for ${resource}: ${response.status}`);
289
+ }
290
+ return response.json();
291
+ }
292
+ },
293
+ /**
294
+ * Get version history
295
+ */
296
+ getVersions: async (resource, id) => {
297
+ const type = resourceToType(resource);
298
+ if (rpcUrl) {
299
+ const result = await rpcCall("Thing.versions", [{
300
+ ns: namespace,
301
+ type,
302
+ id
303
+ }]);
304
+ return result;
305
+ } else {
306
+ const response = await fetchWithTimeout(
307
+ `${apiEndpoint}/things/${encodeURIComponent(namespace)}/${encodeURIComponent(type)}/${encodeURIComponent(id)}/versions`,
308
+ { headers, timeout: DEFAULT_REQUEST_TIMEOUT }
309
+ );
310
+ if (!response.ok) {
311
+ throw new Error(`Failed to get versions for ${resource}/${id}: ${response.status}`);
312
+ }
313
+ return response.json();
314
+ }
315
+ }
316
+ };
317
+ return dataProvider;
318
+ }
319
+ function DoDataProviderProvider({
320
+ children,
321
+ dataProvider: providedDataProvider
322
+ }) {
323
+ const { config, namespace, rpcUrl } = useDO();
324
+ const dataProvider = React3.useMemo(() => {
325
+ if (providedDataProvider) return providedDataProvider;
326
+ return createDoDataProvider(
327
+ config.apiEndpoint,
328
+ config.authToken,
329
+ namespace,
330
+ rpcUrl
331
+ );
332
+ }, [providedDataProvider, config.apiEndpoint, config.authToken, namespace, rpcUrl]);
333
+ return /* @__PURE__ */ jsx(DataProviderProvider, { dataProvider, children });
334
+ }
335
+ function createDoAuthProvider(apiEndpoint, authMethod, authToken, namespace = "default") {
336
+ let currentToken = authToken;
337
+ const getHeaders = () => ({
338
+ "Content-Type": "application/json",
339
+ ...currentToken ? { Authorization: `Bearer ${currentToken}` } : {}
340
+ });
341
+ const authProvider = {
342
+ /**
343
+ * Login with credentials
344
+ */
345
+ login: async (params) => {
346
+ const { username, password, apiKey, oauthToken, provider } = params;
347
+ let endpoint = `${apiEndpoint}/auth/login`;
348
+ let body = {};
349
+ switch (authMethod) {
350
+ case "jwt":
351
+ body = { username, password };
352
+ break;
353
+ case "api-key":
354
+ endpoint = `${apiEndpoint}/auth/api-key`;
355
+ body = { apiKey };
356
+ break;
357
+ case "oauth":
358
+ endpoint = `${apiEndpoint}/auth/oauth/${provider ?? "google"}`;
359
+ body = { token: oauthToken };
360
+ break;
361
+ }
362
+ const response = await fetchWithTimeout(endpoint, {
363
+ method: "POST",
364
+ headers: { "Content-Type": "application/json" },
365
+ body: JSON.stringify(body),
366
+ timeout: DEFAULT_REQUEST_TIMEOUT
367
+ });
368
+ if (!response.ok) {
369
+ const error = await response.json().catch(() => ({ message: "Login failed" }));
370
+ throw new Error(error.message ?? "Login failed");
371
+ }
372
+ const result = await response.json();
373
+ currentToken = result.token ?? result.accessToken;
374
+ if (typeof window !== "undefined" && currentToken) {
375
+ localStorage.setItem("do_auth_token", currentToken);
376
+ }
377
+ },
378
+ /**
379
+ * Logout current session
380
+ */
381
+ logout: async () => {
382
+ try {
383
+ await fetchWithTimeout(`${apiEndpoint}/auth/logout`, {
384
+ method: "POST",
385
+ headers: getHeaders(),
386
+ timeout: DEFAULT_REQUEST_TIMEOUT
387
+ });
388
+ } catch {
389
+ }
390
+ currentToken = void 0;
391
+ if (typeof window !== "undefined") {
392
+ localStorage.removeItem("do_auth_token");
393
+ }
394
+ },
395
+ /**
396
+ * Check if user is authenticated
397
+ */
398
+ checkAuth: async () => {
399
+ if (!currentToken && typeof window !== "undefined") {
400
+ currentToken = localStorage.getItem("do_auth_token") ?? void 0;
401
+ }
402
+ if (!currentToken) {
403
+ throw new Error("Not authenticated");
404
+ }
405
+ const response = await fetchWithTimeout(`${apiEndpoint}/auth/me`, {
406
+ method: "GET",
407
+ headers: getHeaders(),
408
+ timeout: DEFAULT_REQUEST_TIMEOUT
409
+ });
410
+ if (!response.ok) {
411
+ currentToken = void 0;
412
+ if (typeof window !== "undefined") {
413
+ localStorage.removeItem("do_auth_token");
414
+ }
415
+ throw new Error("Session expired");
416
+ }
417
+ },
418
+ /**
419
+ * Check if an error is an auth error
420
+ */
421
+ checkError: async (error) => {
422
+ const status = error.status;
423
+ if (status === 401 || status === 403) {
424
+ currentToken = void 0;
425
+ if (typeof window !== "undefined") {
426
+ localStorage.removeItem("do_auth_token");
427
+ }
428
+ throw error;
429
+ }
430
+ },
431
+ /**
432
+ * Get current user identity
433
+ */
434
+ getIdentity: async () => {
435
+ const response = await fetchWithTimeout(`${apiEndpoint}/auth/me`, {
436
+ method: "GET",
437
+ headers: getHeaders(),
438
+ timeout: DEFAULT_REQUEST_TIMEOUT
439
+ });
440
+ if (!response.ok) {
441
+ throw new Error("Failed to get user identity");
442
+ }
443
+ const user = await response.json();
444
+ return {
445
+ id: user.id ?? user.$id ?? user.sub,
446
+ fullName: user.fullName ?? user.name ?? user.displayName,
447
+ email: user.email,
448
+ avatar: user.avatar ?? user.picture ?? user.avatarUrl,
449
+ namespace: user.namespace ?? namespace,
450
+ role: user.role,
451
+ claims: user.claims ?? user.metadata
452
+ };
453
+ },
454
+ /**
455
+ * Get user permissions
456
+ */
457
+ getPermissions: async () => {
458
+ const response = await fetchWithTimeout(`${apiEndpoint}/auth/permissions`, {
459
+ method: "GET",
460
+ headers: getHeaders(),
461
+ timeout: DEFAULT_REQUEST_TIMEOUT
462
+ });
463
+ if (!response.ok) {
464
+ return [];
465
+ }
466
+ const result = await response.json();
467
+ return result.permissions ?? result ?? [];
468
+ }
469
+ };
470
+ return authProvider;
471
+ }
472
+ function DoAuthProviderProvider({
473
+ children,
474
+ authProvider: providedAuthProvider
475
+ }) {
476
+ const { config, namespace } = useDO();
477
+ const authProvider = React3.useMemo(() => {
478
+ if (providedAuthProvider) return providedAuthProvider;
479
+ return createDoAuthProvider(
480
+ config.apiEndpoint,
481
+ config.authMethod,
482
+ config.authToken,
483
+ namespace
484
+ );
485
+ }, [providedAuthProvider, config.apiEndpoint, config.authMethod, config.authToken, namespace]);
486
+ const appAuthProvider = React3.useMemo(() => ({
487
+ login: authProvider.login,
488
+ logout: authProvider.logout,
489
+ checkAuth: authProvider.checkAuth,
490
+ checkError: authProvider.checkError,
491
+ getIdentity: async () => {
492
+ const identity = await authProvider.getIdentity();
493
+ return {
494
+ id: identity.id,
495
+ fullName: identity.fullName,
496
+ email: identity.email,
497
+ avatar: identity.avatar
498
+ };
499
+ },
500
+ getPermissions: authProvider.getPermissions
501
+ }), [authProvider]);
502
+ return /* @__PURE__ */ jsx(AuthProvider, { authProvider: appAuthProvider, children });
503
+ }
504
+
505
+ // src/admin/discover-resources.ts
506
+ var DEFAULT_RESOURCE_TYPES = ["Thing", "Agent", "Workflow"];
507
+ var CLASS_NAME_MAPPINGS = {
508
+ ThingsRelationshipsDO: "Thing",
509
+ StateMachine: "Workflow",
510
+ ClaudeCodeSession: "Session",
511
+ BrowserSession: "BrowserSession",
512
+ ConversationSession: "Conversation",
513
+ ChangeProposal: "Proposal"
514
+ };
515
+ function bindingToResource(binding) {
516
+ const resourceName = CLASS_NAME_MAPPINGS[binding.className] ?? binding.name;
517
+ const label = resourceName.replace(/([A-Z])/g, " $1").trim().replace(/^./, (s) => s.toUpperCase());
518
+ return {
519
+ name: resourceName,
520
+ label: label.endsWith("s") ? label : `${label}s`,
521
+ // Pluralize for list views
522
+ showInSidebar: true
523
+ };
524
+ }
525
+ function createDefaultResource(resourceType) {
526
+ const label = resourceType.replace(/([A-Z])/g, " $1").trim().replace(/^./, (s) => s.toUpperCase());
527
+ return {
528
+ name: resourceType,
529
+ label: label.endsWith("s") ? label : `${label}s`,
530
+ // Pluralize
531
+ showInSidebar: true
532
+ };
533
+ }
534
+ function discoverResources(config) {
535
+ if (config.resources && config.resources.length > 0) {
536
+ return config.resources;
537
+ }
538
+ if (config.autoDiscoverResources && config.doConfig.bindings.length > 0) {
539
+ const seen = /* @__PURE__ */ new Set();
540
+ const resources = [];
541
+ for (const binding of config.doConfig.bindings) {
542
+ const resource = bindingToResource(binding);
543
+ if (!seen.has(resource.name)) {
544
+ seen.add(resource.name);
545
+ resources.push(resource);
546
+ }
547
+ }
548
+ return resources;
549
+ }
550
+ return DEFAULT_RESOURCE_TYPES.map(createDefaultResource);
551
+ }
552
+ function mergeResourceOverrides(discovered, overrides) {
553
+ const overrideMap = new Map(
554
+ overrides.filter((o) => o.name).map((o) => [o.name, o])
555
+ );
556
+ return discovered.map((resource) => {
557
+ const override = overrideMap.get(resource.name);
558
+ if (override) {
559
+ return { ...resource, ...override };
560
+ }
561
+ return resource;
562
+ });
563
+ }
564
+ var DoAdminContext = React3.createContext(null);
565
+ function useDoAdminConfig() {
566
+ return React3.useContext(DoAdminContext);
567
+ }
568
+ var DEFAULT_ICONS = {
569
+ dashboard: Home,
570
+ task: FileText,
571
+ user: Users,
572
+ thing: Box,
573
+ relationship: GitBranch,
574
+ workflow: Workflow,
575
+ agent: Bot,
576
+ event: Zap,
577
+ settings: Settings,
578
+ database: Database
579
+ };
580
+ function getIconForResource(name) {
581
+ const lowercaseName = name.toLowerCase();
582
+ return DEFAULT_ICONS[lowercaseName] ?? Box;
583
+ }
584
+ function buildNavigation(resources, basePath = "") {
585
+ const mainItems = resources.filter((r) => r.showInSidebar !== false).map((resource) => {
586
+ const Icon = resource.icon ?? getIconForResource(resource.name);
587
+ return {
588
+ title: resource.label ?? resource.name,
589
+ url: `${basePath}/${resource.name.toLowerCase()}`,
590
+ icon: Icon
591
+ };
592
+ });
593
+ return [
594
+ {
595
+ label: "Resources",
596
+ items: mainItems
597
+ }
598
+ ];
599
+ }
600
+ function DoAdminInner({ config }) {
601
+ const {
602
+ title = "Admin",
603
+ logo,
604
+ theme = "system",
605
+ basePath = "",
606
+ dashboard,
607
+ loginPage,
608
+ notFoundPage,
609
+ layout: CustomLayout,
610
+ sidebarFooter,
611
+ disableRouter = false
612
+ } = config;
613
+ const { isAuthenticated, identity, isLoading: isAuthLoading, logout } = useAuth();
614
+ const { isConnected, connectionError, namespace } = useDO();
615
+ const resources = React3.useMemo(() => discoverResources(config), [config]);
616
+ const navigation = React3.useMemo(
617
+ () => buildNavigation(resources, basePath),
618
+ [resources, basePath]
619
+ );
620
+ const adminContextValue = React3.useMemo(
621
+ () => ({ config, resources }),
622
+ [config, resources]
623
+ );
624
+ const user = React3.useMemo(
625
+ () => identity ? {
626
+ id: identity.id,
627
+ fullName: identity.fullName,
628
+ email: identity.email,
629
+ avatar: identity.avatar
630
+ } : void 0,
631
+ [identity]
632
+ );
633
+ if (isAuthLoading) {
634
+ return /* @__PURE__ */ jsx("div", { className: "flex h-screen w-full items-center justify-center bg-background", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
635
+ /* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }),
636
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Loading..." })
637
+ ] }) });
638
+ }
639
+ if (connectionError) {
640
+ return /* @__PURE__ */ jsx("div", { className: "flex h-screen w-full items-center justify-center bg-background", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
641
+ /* @__PURE__ */ jsx("div", { className: "rounded-full bg-destructive/10 p-4", children: /* @__PURE__ */ jsx(Database, { className: "h-8 w-8 text-destructive" }) }),
642
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Connection Error" }),
643
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-md", children: "Unable to connect to the backend. Please check your configuration and try again." }),
644
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: connectionError.message })
645
+ ] }) });
646
+ }
647
+ const AdminComponent = disableRouter ? AdminWithoutRouter : Admin;
648
+ const adminContent = /* @__PURE__ */ jsx(
649
+ AdminComponent,
650
+ {
651
+ title,
652
+ logo,
653
+ theme,
654
+ basename: basePath,
655
+ dashboard,
656
+ loginPage,
657
+ catchAll: notFoundPage,
658
+ disableRouter,
659
+ children: resources.map((resource) => /* @__PURE__ */ jsx(
660
+ Resource,
661
+ {
662
+ name: resource.name,
663
+ list: resource.list,
664
+ create: resource.create,
665
+ edit: resource.edit,
666
+ show: resource.show,
667
+ icon: resource.icon
668
+ },
669
+ resource.name
670
+ ))
671
+ }
672
+ );
673
+ if (CustomLayout) {
674
+ return /* @__PURE__ */ jsx(DoAdminContext.Provider, { value: adminContextValue, children: /* @__PURE__ */ jsx(CustomLayout, { children: adminContent }) });
675
+ }
676
+ return /* @__PURE__ */ jsx(DoAdminContext.Provider, { value: adminContextValue, children: /* @__PURE__ */ jsx(
677
+ AppShell,
678
+ {
679
+ config: {
680
+ name: title,
681
+ basePath,
682
+ logo
683
+ },
684
+ navigation,
685
+ user,
686
+ isLoading: isAuthLoading,
687
+ header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
688
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: title }),
689
+ namespace !== "default" && /* @__PURE__ */ jsx("span", { className: "rounded-md bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: namespace })
690
+ ] }),
691
+ nav: /* @__PURE__ */ jsx(NavMain, { items: navigation[0]?.items ?? [] }),
692
+ footer: sidebarFooter ?? (user && /* @__PURE__ */ jsx(NavUser, { user })),
693
+ pageHeader: /* @__PURE__ */ jsx(AppBreadcrumbs, {}),
694
+ children: adminContent
695
+ }
696
+ ) });
697
+ }
698
+ function DoAdmin({ config, children }) {
699
+ const { doConfig } = config;
700
+ return /* @__PURE__ */ jsx(DOProvider, { config: doConfig, children: /* @__PURE__ */ jsx(DoAuthProviderProvider, { children: /* @__PURE__ */ jsxs(DoDataProviderProvider, { children: [
701
+ /* @__PURE__ */ jsx(DoAdminInner, { config }),
702
+ children
703
+ ] }) }) });
704
+ }
705
+ DoAdmin.displayName = "DoAdmin";
706
+ function useDoAdmin() {
707
+ const auth = useAuth();
708
+ const do_ = useDO();
709
+ const adminConfig = useDoAdminConfig();
710
+ const resources = React3.useMemo(() => {
711
+ if (adminConfig?.resources) {
712
+ return adminConfig.resources;
713
+ }
714
+ return discoverResources({
715
+ doConfig: do_.config
716
+ });
717
+ }, [adminConfig?.resources, do_.config]);
718
+ return React3.useMemo(
719
+ () => ({
720
+ user: auth.identity ? {
721
+ id: auth.identity.id,
722
+ fullName: auth.identity.fullName,
723
+ email: auth.identity.email,
724
+ avatar: auth.identity.avatar
725
+ } : null,
726
+ isAuthenticated: auth.isAuthenticated,
727
+ isAuthLoading: auth.isLoading,
728
+ isConnected: do_.isConnected,
729
+ connectionError: do_.connectionError ?? null,
730
+ resources,
731
+ namespace: do_.namespace,
732
+ setNamespace: do_.setNamespace,
733
+ login: auth.login,
734
+ logout: auth.logout
735
+ }),
736
+ [auth, do_, resources]
737
+ );
738
+ }
739
+
740
+ // src/lib/sync/batch-sync.ts
741
+ function createBatchedOperations(executor, options = {}) {
742
+ const { maxBatchSize = 100, maxWaitMs = 50 } = options;
743
+ let batch = [];
744
+ let timer = null;
745
+ let flushPromise = null;
746
+ const flush = async () => {
747
+ if (batch.length === 0) return;
748
+ if (flushPromise) {
749
+ await flushPromise;
750
+ return;
751
+ }
752
+ const items = batch;
753
+ batch = [];
754
+ if (timer) {
755
+ clearTimeout(timer);
756
+ timer = null;
757
+ }
758
+ flushPromise = executor(items).finally(() => {
759
+ flushPromise = null;
760
+ });
761
+ await flushPromise;
762
+ };
763
+ return {
764
+ add: (item) => {
765
+ batch.push(item);
766
+ if (batch.length >= maxBatchSize) {
767
+ if (timer) {
768
+ clearTimeout(timer);
769
+ timer = null;
770
+ }
771
+ void flush();
772
+ } else if (!timer) {
773
+ timer = setTimeout(() => {
774
+ timer = null;
775
+ void flush();
776
+ }, maxWaitMs);
777
+ }
778
+ },
779
+ flush,
780
+ get pending() {
781
+ return batch.length;
782
+ }
783
+ };
784
+ }
785
+
786
+ // src/lib/sync/offline-queue.ts
787
+ function createOfflineQueue(options = {}) {
788
+ const { maxQueueSize = 1e3, persistKey } = options;
789
+ let queue = [];
790
+ if (persistKey && typeof localStorage !== "undefined") {
791
+ try {
792
+ const stored = localStorage.getItem(persistKey);
793
+ if (stored) {
794
+ const parsed = JSON.parse(stored);
795
+ if (Array.isArray(parsed)) {
796
+ queue = parsed;
797
+ }
798
+ }
799
+ } catch {
800
+ }
801
+ }
802
+ const persist = () => {
803
+ if (persistKey && typeof localStorage !== "undefined") {
804
+ try {
805
+ localStorage.setItem(persistKey, JSON.stringify(queue));
806
+ } catch {
807
+ }
808
+ }
809
+ };
810
+ return {
811
+ enqueue: (item) => {
812
+ if (queue.length >= maxQueueSize) {
813
+ return false;
814
+ }
815
+ queue.push(item);
816
+ persist();
817
+ return true;
818
+ },
819
+ dequeueAll: () => {
820
+ const items = queue;
821
+ queue = [];
822
+ persist();
823
+ return items;
824
+ },
825
+ peek: () => {
826
+ return queue;
827
+ },
828
+ clear: () => {
829
+ queue = [];
830
+ persist();
831
+ },
832
+ get length() {
833
+ return queue.length;
834
+ },
835
+ get isFull() {
836
+ return queue.length >= maxQueueSize;
837
+ }
838
+ };
839
+ }
840
+
841
+ export { DEFAULT_RESOURCE_TYPES, DoAdmin, DoAuthProviderProvider, DoDataProviderProvider, createBatchedOperations, createDoAuthProvider, createDoDataProvider, createOfflineQueue, discoverResources, mergeResourceOverrides, useDoAdmin };
842
+ //# sourceMappingURL=index.js.map
843
+ //# sourceMappingURL=index.js.map