@mdxui/do 2.1.1 → 4.0.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/README.md +115 -323
- package/dist/{agents-xcIn2dUB.d.ts → agents-2_r9e9i7.d.ts} +213 -2
- package/dist/app/index.d.ts +347 -0
- package/dist/app/index.js +14 -0
- package/dist/app/index.js.map +1 -0
- package/dist/breadcrumbs-C9Qn3S7d.d.ts +81 -0
- package/dist/capnweb-client-Bq78FtEA.d.ts +229 -0
- package/dist/chunk-3XKYQRXY.js +192 -0
- package/dist/chunk-3XKYQRXY.js.map +1 -0
- package/dist/chunk-4KXVN3EQ.js +56 -0
- package/dist/chunk-4KXVN3EQ.js.map +1 -0
- package/dist/chunk-5SHZZC7L.js +234 -0
- package/dist/chunk-5SHZZC7L.js.map +1 -0
- package/dist/chunk-7UFINK3Q.js +1994 -0
- package/dist/chunk-7UFINK3Q.js.map +1 -0
- package/dist/chunk-JJLAES6W.js +76 -0
- package/dist/chunk-JJLAES6W.js.map +1 -0
- package/dist/chunk-KT52UU3U.js +985 -0
- package/dist/chunk-KT52UU3U.js.map +1 -0
- package/dist/chunk-LJIWB7KE.js +95 -0
- package/dist/chunk-LJIWB7KE.js.map +1 -0
- package/dist/chunk-NA652ART.js +596 -0
- package/dist/chunk-NA652ART.js.map +1 -0
- package/dist/chunk-OVLO7UOH.js +1071 -0
- package/dist/chunk-OVLO7UOH.js.map +1 -0
- package/dist/chunk-VRLUXCLD.js +31 -0
- package/dist/chunk-VRLUXCLD.js.map +1 -0
- package/dist/chunk-WMNT4OIE.js +249 -0
- package/dist/chunk-WMNT4OIE.js.map +1 -0
- package/dist/chunk-Y52IEYVM.js +131 -0
- package/dist/chunk-Y52IEYVM.js.map +1 -0
- package/dist/components/index.d.ts +14 -732
- package/dist/components/index.js +3 -6
- package/dist/config-CxvpD8Y6.d.ts +111 -0
- package/dist/{do-CaQVueZw.d.ts → do-D27i5bU0.d.ts} +32 -33
- package/dist/errors-DratdVIz.d.ts +346 -0
- package/dist/hooks/index.d.ts +450 -691
- package/dist/hooks/index.js +6 -4
- package/dist/hooks/things/index.d.ts +298 -0
- package/dist/hooks/things/index.js +8 -0
- package/dist/hooks/things/index.js.map +1 -0
- package/dist/index.d.ts +62 -989
- package/dist/index.js +12 -839
- package/dist/index.js.map +1 -1
- package/dist/lib/index.d.ts +798 -0
- package/dist/lib/index.js +6 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/providers/index.d.ts +130 -34
- package/dist/providers/index.js +3 -2
- package/dist/query-keys-CZNFikIi.d.ts +153 -0
- package/dist/schemas/index.d.ts +5 -5
- package/dist/schemas/index.js +2 -2
- package/dist/schemas/index.js.map +1 -1
- package/dist/{thing-DtI25yZh.d.ts → thing-BF25aUtJ.d.ts} +72 -72
- package/dist/types/index.d.ts +693 -658
- package/dist/types/index.js +1 -2
- package/dist/views/index.d.ts +131 -0
- package/dist/views/index.js +11 -0
- package/dist/views/index.js.map +1 -0
- package/package.json +39 -17
- package/dist/__test-utils__/index.d.ts +0 -399
- package/dist/__test-utils__/index.js +0 -34641
- package/dist/__test-utils__/index.js.map +0 -1
- package/dist/chunk-EEDMN7UF.js +0 -1351
- package/dist/chunk-EEDMN7UF.js.map +0 -1
- package/dist/chunk-G3PMV62Z.js +0 -33
- package/dist/chunk-G3PMV62Z.js.map +0 -1
- package/dist/chunk-NXPXL5NA.js +0 -3789
- package/dist/chunk-NXPXL5NA.js.map +0 -1
- package/dist/chunk-PC5FJY6M.js +0 -20
- package/dist/chunk-PC5FJY6M.js.map +0 -1
- package/dist/chunk-XF6LKY2M.js +0 -445
- package/dist/chunk-XF6LKY2M.js.map +0 -1
- package/dist/magic-string.es-J7BYFTTJ.js +0 -1307
- package/dist/magic-string.es-J7BYFTTJ.js.map +0 -1
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import { thingsKeys } from './chunk-4KXVN3EQ.js';
|
|
2
|
+
import { useDO } from './chunk-WMNT4OIE.js';
|
|
3
|
+
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
5
|
+
import { useRouterState } from '@tanstack/react-router';
|
|
6
|
+
|
|
7
|
+
var schemaKeys = {
|
|
8
|
+
all: ["schema"],
|
|
9
|
+
discovery: (ns) => [...schemaKeys.all, "discovery", ns ?? "all"],
|
|
10
|
+
definition: (ns, type) => [...schemaKeys.all, "definition", ns, type]
|
|
11
|
+
};
|
|
12
|
+
function useSchema(options = {}) {
|
|
13
|
+
const { ns, type, includeSystem = false, enabled = true } = options;
|
|
14
|
+
const { client } = useDO();
|
|
15
|
+
const query = useQuery({
|
|
16
|
+
queryKey: schemaKeys.discovery(ns),
|
|
17
|
+
queryFn: async () => {
|
|
18
|
+
try {
|
|
19
|
+
const result = await client.Schema.discover({
|
|
20
|
+
ns,
|
|
21
|
+
type,
|
|
22
|
+
includeSystem
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
schemas: result.schemas ?? [],
|
|
26
|
+
namespaces: result.namespaces ?? [],
|
|
27
|
+
typesByNamespace: result.typesByNamespace ?? {},
|
|
28
|
+
serverInfo: result.serverInfo
|
|
29
|
+
};
|
|
30
|
+
} catch (error) {
|
|
31
|
+
try {
|
|
32
|
+
const typesResult = await client.Thing.types({ ns });
|
|
33
|
+
const namespaces = typesResult.namespaces ?? [ns ?? "default"];
|
|
34
|
+
const types = typesResult.types ?? [];
|
|
35
|
+
return {
|
|
36
|
+
schemas: types.map((t) => ({
|
|
37
|
+
name: t,
|
|
38
|
+
ns: ns ?? "default",
|
|
39
|
+
properties: []
|
|
40
|
+
})),
|
|
41
|
+
namespaces,
|
|
42
|
+
typesByNamespace: {
|
|
43
|
+
[ns ?? "default"]: types
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
} catch {
|
|
47
|
+
return {
|
|
48
|
+
schemas: [],
|
|
49
|
+
namespaces: [],
|
|
50
|
+
typesByNamespace: {}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
enabled
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
data: query.data ?? null,
|
|
59
|
+
isLoading: query.isLoading,
|
|
60
|
+
error: query.error,
|
|
61
|
+
refetch: query.refetch,
|
|
62
|
+
isRefetching: query.isRefetching
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function useSchemaDefinition(ns, type, options = {}) {
|
|
66
|
+
const { enabled = true } = options;
|
|
67
|
+
const { client } = useDO();
|
|
68
|
+
const query = useQuery({
|
|
69
|
+
queryKey: schemaKeys.definition(ns, type),
|
|
70
|
+
queryFn: async () => {
|
|
71
|
+
try {
|
|
72
|
+
const result = await client.Schema.get({ ns, type });
|
|
73
|
+
return result;
|
|
74
|
+
} catch {
|
|
75
|
+
return {
|
|
76
|
+
name: type,
|
|
77
|
+
ns,
|
|
78
|
+
properties: []
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
enabled: enabled && Boolean(ns && type)
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
data: query.data ?? null,
|
|
86
|
+
isLoading: query.isLoading,
|
|
87
|
+
error: query.error,
|
|
88
|
+
refetch: query.refetch
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
var namespacesKeys = {
|
|
92
|
+
all: ["namespaces"],
|
|
93
|
+
list: (includeSystem) => [...namespacesKeys.all, "list", includeSystem ?? false]
|
|
94
|
+
};
|
|
95
|
+
function useNamespaces(options = {}) {
|
|
96
|
+
const { includeSystem = false, enabled = true } = options;
|
|
97
|
+
const { client } = useDO();
|
|
98
|
+
const query = useQuery({
|
|
99
|
+
queryKey: namespacesKeys.list(includeSystem),
|
|
100
|
+
queryFn: async () => {
|
|
101
|
+
let primaryError = null;
|
|
102
|
+
try {
|
|
103
|
+
const result = await client.Namespace.list({ includeSystem });
|
|
104
|
+
if (Array.isArray(result)) {
|
|
105
|
+
return result.map(normalizeNamespace);
|
|
106
|
+
}
|
|
107
|
+
if (result.namespaces && Array.isArray(result.namespaces)) {
|
|
108
|
+
return result.namespaces.map(normalizeNamespace);
|
|
109
|
+
}
|
|
110
|
+
if (result.data && Array.isArray(result.data)) {
|
|
111
|
+
return result.data.map(normalizeNamespace);
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
114
|
+
} catch (err) {
|
|
115
|
+
primaryError = err instanceof Error ? err : new Error(String(err));
|
|
116
|
+
try {
|
|
117
|
+
const schemaResult = await client.Schema.discover({});
|
|
118
|
+
const namespaceNames = schemaResult.namespaces ?? ["default"];
|
|
119
|
+
return namespaceNames.map((name) => ({
|
|
120
|
+
id: name,
|
|
121
|
+
name,
|
|
122
|
+
types: [],
|
|
123
|
+
thingCount: 0,
|
|
124
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
125
|
+
}));
|
|
126
|
+
} catch (fallbackErr) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Failed to fetch namespaces: ${primaryError.message}. Fallback also failed: ${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
enabled
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
data: query.data ?? null,
|
|
137
|
+
isLoading: query.isLoading,
|
|
138
|
+
error: query.error,
|
|
139
|
+
refetch: query.refetch,
|
|
140
|
+
isRefetching: query.isRefetching,
|
|
141
|
+
status: query.status
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function normalizeNamespace(ns) {
|
|
145
|
+
if (typeof ns === "string") {
|
|
146
|
+
return {
|
|
147
|
+
id: ns,
|
|
148
|
+
name: ns,
|
|
149
|
+
types: [],
|
|
150
|
+
thingCount: 0,
|
|
151
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const nsObj = ns;
|
|
155
|
+
return {
|
|
156
|
+
id: nsObj.id ?? nsObj.name ?? "unknown",
|
|
157
|
+
name: nsObj.name ?? nsObj.id ?? "unknown",
|
|
158
|
+
description: nsObj.description,
|
|
159
|
+
baseUrl: nsObj.baseUrl,
|
|
160
|
+
types: nsObj.types ?? [],
|
|
161
|
+
thingCount: nsObj.thingCount ?? 0,
|
|
162
|
+
createdAt: nsObj.createdAt ? new Date(nsObj.createdAt) : /* @__PURE__ */ new Date()
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
var typesKeys = {
|
|
166
|
+
all: ["types"],
|
|
167
|
+
list: (ns, includeSystem) => [...typesKeys.all, "list", ns, includeSystem ?? false]
|
|
168
|
+
};
|
|
169
|
+
function useTypes(options = {}) {
|
|
170
|
+
const { includeSystem = false, enabled = true } = options;
|
|
171
|
+
const { namespace, client } = useDO();
|
|
172
|
+
const ns = options.ns ?? namespace;
|
|
173
|
+
const query = useQuery({
|
|
174
|
+
queryKey: typesKeys.list(ns, includeSystem),
|
|
175
|
+
queryFn: async () => {
|
|
176
|
+
let primaryError = null;
|
|
177
|
+
try {
|
|
178
|
+
const result = await client.Thing.types({ ns, includeSystem });
|
|
179
|
+
if (Array.isArray(result)) {
|
|
180
|
+
return result.map((t) => normalizeType(t, ns));
|
|
181
|
+
}
|
|
182
|
+
if (result.types && Array.isArray(result.types)) {
|
|
183
|
+
return result.types.map((t) => normalizeType(t, ns));
|
|
184
|
+
}
|
|
185
|
+
if (result.data && Array.isArray(result.data)) {
|
|
186
|
+
return result.data.map((t) => normalizeType(t, ns));
|
|
187
|
+
}
|
|
188
|
+
return [];
|
|
189
|
+
} catch (err) {
|
|
190
|
+
primaryError = err instanceof Error ? err : new Error(String(err));
|
|
191
|
+
try {
|
|
192
|
+
const schemaResult = await client.Schema.discover({ ns });
|
|
193
|
+
const typeNames = schemaResult.typesByNamespace?.[ns] ?? [];
|
|
194
|
+
return typeNames.map((name) => normalizeType(name, ns));
|
|
195
|
+
} catch (fallbackErr) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`Failed to fetch types: ${primaryError.message}. Fallback also failed: ${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
enabled: enabled && Boolean(ns)
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
data: query.data ?? null,
|
|
206
|
+
isLoading: query.isLoading,
|
|
207
|
+
error: query.error,
|
|
208
|
+
refetch: query.refetch,
|
|
209
|
+
isRefetching: query.isRefetching,
|
|
210
|
+
status: query.status
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function normalizeType(type, defaultNs) {
|
|
214
|
+
if (typeof type === "string") {
|
|
215
|
+
return {
|
|
216
|
+
namespace: defaultNs,
|
|
217
|
+
name: type,
|
|
218
|
+
id: `${defaultNs}/${type}`,
|
|
219
|
+
label: type,
|
|
220
|
+
parentTypes: [],
|
|
221
|
+
properties: [],
|
|
222
|
+
subtypes: []
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const typeObj = type;
|
|
226
|
+
const name = typeObj.name ?? typeObj.type ?? "unknown";
|
|
227
|
+
const namespace = typeObj.namespace ?? typeObj.ns ?? defaultNs;
|
|
228
|
+
return {
|
|
229
|
+
namespace,
|
|
230
|
+
name,
|
|
231
|
+
id: typeObj.id ?? `${namespace}/${name}`,
|
|
232
|
+
label: typeObj.label ?? typeObj.displayName ?? name,
|
|
233
|
+
description: typeObj.description,
|
|
234
|
+
parentTypes: typeObj.parentTypes ?? [],
|
|
235
|
+
properties: typeObj.properties ?? [],
|
|
236
|
+
subtypes: typeObj.subtypes ?? [],
|
|
237
|
+
examples: typeObj.examples
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function useThingSubscription(options = {}) {
|
|
241
|
+
const {
|
|
242
|
+
type,
|
|
243
|
+
id,
|
|
244
|
+
filter,
|
|
245
|
+
onCreated,
|
|
246
|
+
onUpdated,
|
|
247
|
+
onDeleted,
|
|
248
|
+
onEvent,
|
|
249
|
+
onStateChange,
|
|
250
|
+
enabled = true,
|
|
251
|
+
invalidateOnUpdate = true
|
|
252
|
+
} = options;
|
|
253
|
+
const { client, namespace } = useDO();
|
|
254
|
+
const ns = options.ns ?? namespace;
|
|
255
|
+
const queryClient = useQueryClient();
|
|
256
|
+
const [state, setState] = useState("disconnected");
|
|
257
|
+
const [events, setEvents] = useState([]);
|
|
258
|
+
const [error, setError] = useState(null);
|
|
259
|
+
const subscriptionRef = useRef(null);
|
|
260
|
+
const reconnectTimeoutRef = useRef(null);
|
|
261
|
+
const MAX_EVENTS = 100;
|
|
262
|
+
const addEvent = useCallback((event) => {
|
|
263
|
+
setEvents((prev) => {
|
|
264
|
+
const newEvents = [event, ...prev];
|
|
265
|
+
return newEvents.slice(0, MAX_EVENTS);
|
|
266
|
+
});
|
|
267
|
+
onEvent?.(event);
|
|
268
|
+
}, [onEvent]);
|
|
269
|
+
const handleCreated = useCallback((thing) => {
|
|
270
|
+
addEvent({ type: "created", thing, timestamp: /* @__PURE__ */ new Date() });
|
|
271
|
+
onCreated?.(thing);
|
|
272
|
+
if (invalidateOnUpdate) {
|
|
273
|
+
queryClient.invalidateQueries({ queryKey: thingsKeys.lists() });
|
|
274
|
+
}
|
|
275
|
+
}, [addEvent, onCreated, invalidateOnUpdate, queryClient]);
|
|
276
|
+
const handleUpdated = useCallback((thing) => {
|
|
277
|
+
addEvent({ type: "updated", thing, timestamp: /* @__PURE__ */ new Date() });
|
|
278
|
+
onUpdated?.(thing);
|
|
279
|
+
if (invalidateOnUpdate) {
|
|
280
|
+
queryClient.setQueryData(
|
|
281
|
+
thingsKeys.detail(thing.ns, thing.type, thing.id),
|
|
282
|
+
thing
|
|
283
|
+
);
|
|
284
|
+
queryClient.invalidateQueries({ queryKey: thingsKeys.lists() });
|
|
285
|
+
}
|
|
286
|
+
}, [addEvent, onUpdated, invalidateOnUpdate, queryClient]);
|
|
287
|
+
const handleDeleted = useCallback((thingId) => {
|
|
288
|
+
addEvent({ type: "deleted", thingId, timestamp: /* @__PURE__ */ new Date() });
|
|
289
|
+
onDeleted?.(thingId);
|
|
290
|
+
if (invalidateOnUpdate) {
|
|
291
|
+
queryClient.invalidateQueries({ queryKey: thingsKeys.lists() });
|
|
292
|
+
}
|
|
293
|
+
}, [addEvent, onDeleted, invalidateOnUpdate, queryClient]);
|
|
294
|
+
const updateState = useCallback((newState) => {
|
|
295
|
+
setState(newState);
|
|
296
|
+
onStateChange?.(newState);
|
|
297
|
+
if (newState === "connected") {
|
|
298
|
+
addEvent({ type: "connected", timestamp: /* @__PURE__ */ new Date() });
|
|
299
|
+
} else if (newState === "disconnected") {
|
|
300
|
+
addEvent({ type: "disconnected", timestamp: /* @__PURE__ */ new Date() });
|
|
301
|
+
}
|
|
302
|
+
}, [onStateChange, addEvent]);
|
|
303
|
+
const connect = useCallback(async () => {
|
|
304
|
+
if (!enabled) return;
|
|
305
|
+
try {
|
|
306
|
+
updateState("connecting");
|
|
307
|
+
setError(null);
|
|
308
|
+
const subscriptionParams = {
|
|
309
|
+
ns,
|
|
310
|
+
type,
|
|
311
|
+
id,
|
|
312
|
+
filter
|
|
313
|
+
};
|
|
314
|
+
const subscription = await client.Thing.subscribe?.(subscriptionParams, {
|
|
315
|
+
onCreated: handleCreated,
|
|
316
|
+
onUpdated: handleUpdated,
|
|
317
|
+
onDeleted: handleDeleted,
|
|
318
|
+
onError: (err) => {
|
|
319
|
+
setError(err);
|
|
320
|
+
addEvent({ type: "error", error: err.message, timestamp: /* @__PURE__ */ new Date() });
|
|
321
|
+
updateState("error");
|
|
322
|
+
},
|
|
323
|
+
onConnected: () => updateState("connected"),
|
|
324
|
+
onDisconnected: () => updateState("disconnected")
|
|
325
|
+
});
|
|
326
|
+
if (subscription) {
|
|
327
|
+
subscriptionRef.current = subscription;
|
|
328
|
+
updateState("connected");
|
|
329
|
+
} else {
|
|
330
|
+
updateState("disconnected");
|
|
331
|
+
}
|
|
332
|
+
} catch (err) {
|
|
333
|
+
const error2 = err instanceof Error ? err : new Error("Subscription failed");
|
|
334
|
+
setError(error2);
|
|
335
|
+
addEvent({ type: "error", error: error2.message, timestamp: /* @__PURE__ */ new Date() });
|
|
336
|
+
updateState("error");
|
|
337
|
+
}
|
|
338
|
+
}, [
|
|
339
|
+
enabled,
|
|
340
|
+
ns,
|
|
341
|
+
type,
|
|
342
|
+
id,
|
|
343
|
+
filter,
|
|
344
|
+
client,
|
|
345
|
+
handleCreated,
|
|
346
|
+
handleUpdated,
|
|
347
|
+
handleDeleted,
|
|
348
|
+
updateState,
|
|
349
|
+
addEvent
|
|
350
|
+
]);
|
|
351
|
+
const disconnect = useCallback(() => {
|
|
352
|
+
if (subscriptionRef.current?.unsubscribe) {
|
|
353
|
+
subscriptionRef.current.unsubscribe();
|
|
354
|
+
}
|
|
355
|
+
subscriptionRef.current = null;
|
|
356
|
+
updateState("disconnected");
|
|
357
|
+
}, [updateState]);
|
|
358
|
+
const reconnect = useCallback(() => {
|
|
359
|
+
disconnect();
|
|
360
|
+
reconnectTimeoutRef.current = setTimeout(connect, 100);
|
|
361
|
+
}, [disconnect, connect]);
|
|
362
|
+
useEffect(() => {
|
|
363
|
+
if (enabled) {
|
|
364
|
+
connect();
|
|
365
|
+
}
|
|
366
|
+
return () => {
|
|
367
|
+
disconnect();
|
|
368
|
+
if (reconnectTimeoutRef.current) {
|
|
369
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}, [enabled, connect, disconnect]);
|
|
373
|
+
return {
|
|
374
|
+
state,
|
|
375
|
+
events,
|
|
376
|
+
isConnected: state === "connected",
|
|
377
|
+
error,
|
|
378
|
+
reconnect,
|
|
379
|
+
disconnect
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function useSingleThingSubscription(options) {
|
|
383
|
+
const [lastUpdate, setLastUpdate] = useState(null);
|
|
384
|
+
const { isConnected, error } = useThingSubscription({
|
|
385
|
+
ns: options.ns,
|
|
386
|
+
type: options.type,
|
|
387
|
+
id: options.id,
|
|
388
|
+
enabled: options.enabled,
|
|
389
|
+
onUpdated: (thing) => {
|
|
390
|
+
setLastUpdate(/* @__PURE__ */ new Date());
|
|
391
|
+
options.onUpdated?.(thing);
|
|
392
|
+
},
|
|
393
|
+
onDeleted: () => {
|
|
394
|
+
options.onDeleted?.();
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
return {
|
|
398
|
+
isConnected,
|
|
399
|
+
lastUpdate,
|
|
400
|
+
error
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function useEditHistory(options = {}) {
|
|
404
|
+
const { maxHistory = 50, onUndo, onRedo } = options;
|
|
405
|
+
const [undoStack, setUndoStack] = useState([]);
|
|
406
|
+
const [redoStack, setRedoStack] = useState([]);
|
|
407
|
+
const isUndoingRef = useRef(false);
|
|
408
|
+
const pushOperation = useCallback(
|
|
409
|
+
(operation) => {
|
|
410
|
+
if (isUndoingRef.current) return;
|
|
411
|
+
const fullOperation = {
|
|
412
|
+
...operation,
|
|
413
|
+
timestamp: Date.now()
|
|
414
|
+
};
|
|
415
|
+
setUndoStack((prev) => {
|
|
416
|
+
const newStack = [...prev, fullOperation];
|
|
417
|
+
if (newStack.length > maxHistory) {
|
|
418
|
+
return newStack.slice(-maxHistory);
|
|
419
|
+
}
|
|
420
|
+
return newStack;
|
|
421
|
+
});
|
|
422
|
+
setRedoStack([]);
|
|
423
|
+
},
|
|
424
|
+
[maxHistory]
|
|
425
|
+
);
|
|
426
|
+
const undo = useCallback(() => {
|
|
427
|
+
if (undoStack.length === 0) return null;
|
|
428
|
+
const operation = undoStack[undoStack.length - 1];
|
|
429
|
+
isUndoingRef.current = true;
|
|
430
|
+
try {
|
|
431
|
+
setUndoStack((prev) => prev.slice(0, -1));
|
|
432
|
+
setRedoStack((prev) => [...prev, operation]);
|
|
433
|
+
onUndo?.(operation);
|
|
434
|
+
} finally {
|
|
435
|
+
isUndoingRef.current = false;
|
|
436
|
+
}
|
|
437
|
+
return operation;
|
|
438
|
+
}, [undoStack, onUndo]);
|
|
439
|
+
const redo = useCallback(() => {
|
|
440
|
+
if (redoStack.length === 0) return null;
|
|
441
|
+
const operation = redoStack[redoStack.length - 1];
|
|
442
|
+
isUndoingRef.current = true;
|
|
443
|
+
try {
|
|
444
|
+
setRedoStack((prev) => prev.slice(0, -1));
|
|
445
|
+
setUndoStack((prev) => [...prev, operation]);
|
|
446
|
+
onRedo?.(operation);
|
|
447
|
+
} finally {
|
|
448
|
+
isUndoingRef.current = false;
|
|
449
|
+
}
|
|
450
|
+
return operation;
|
|
451
|
+
}, [redoStack, onRedo]);
|
|
452
|
+
const clearHistory = useCallback(() => {
|
|
453
|
+
setUndoStack([]);
|
|
454
|
+
setRedoStack([]);
|
|
455
|
+
}, []);
|
|
456
|
+
return {
|
|
457
|
+
pushOperation,
|
|
458
|
+
undo,
|
|
459
|
+
redo,
|
|
460
|
+
canUndo: undoStack.length > 0,
|
|
461
|
+
canRedo: redoStack.length > 0,
|
|
462
|
+
undoCount: undoStack.length,
|
|
463
|
+
redoCount: redoStack.length,
|
|
464
|
+
clearHistory
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function isEditableTarget(target) {
|
|
468
|
+
if (!target || !(target instanceof HTMLElement)) return false;
|
|
469
|
+
const tagName = target.tagName;
|
|
470
|
+
if (tagName === "INPUT" || tagName === "TEXTAREA") {
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
if (target.isContentEditable || target.getAttribute("contenteditable") === "true") {
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
function matchesShortcut(event, config) {
|
|
479
|
+
if (event.key.toLowerCase() !== config.key.toLowerCase()) {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
const isModifierPressed = config.ctrl || config.meta;
|
|
483
|
+
if (isModifierPressed) {
|
|
484
|
+
if (!event.ctrlKey && !event.metaKey) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (config.shift && !event.shiftKey) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
if (!config.shift && event.shiftKey) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
function useKeyboardShortcuts(shortcuts, options = {}) {
|
|
497
|
+
const { enabled = true, preventDefault = true, stopPropagation = false } = options;
|
|
498
|
+
const shortcutsRef = useRef(shortcuts);
|
|
499
|
+
shortcutsRef.current = shortcuts;
|
|
500
|
+
const optionsRef = useRef({ preventDefault, stopPropagation });
|
|
501
|
+
optionsRef.current = { preventDefault, stopPropagation };
|
|
502
|
+
const handleKeyDown = useCallback((event) => {
|
|
503
|
+
if (isEditableTarget(event.target)) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const currentShortcuts = shortcutsRef.current;
|
|
507
|
+
const currentOptions = optionsRef.current;
|
|
508
|
+
for (const config of currentShortcuts) {
|
|
509
|
+
if (config.disabled) {
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (matchesShortcut(event, config)) {
|
|
513
|
+
if (currentOptions.preventDefault) {
|
|
514
|
+
event.preventDefault();
|
|
515
|
+
}
|
|
516
|
+
if (currentOptions.stopPropagation) {
|
|
517
|
+
event.stopPropagation();
|
|
518
|
+
}
|
|
519
|
+
config.handler();
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}, []);
|
|
524
|
+
useEffect(() => {
|
|
525
|
+
if (!enabled) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
529
|
+
return () => {
|
|
530
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
531
|
+
};
|
|
532
|
+
}, [enabled, handleKeyDown]);
|
|
533
|
+
}
|
|
534
|
+
var ROUTE_LABELS = {
|
|
535
|
+
// Main
|
|
536
|
+
"/": "Overview",
|
|
537
|
+
// Development
|
|
538
|
+
"/agents": "Agents",
|
|
539
|
+
"/functions": "Functions",
|
|
540
|
+
"/workflows": "Workflows",
|
|
541
|
+
"/databases": "Databases",
|
|
542
|
+
// Data Model
|
|
543
|
+
"/things": "Things",
|
|
544
|
+
"/nouns": "Nouns",
|
|
545
|
+
"/verbs": "Verbs",
|
|
546
|
+
"/actions": "Actions",
|
|
547
|
+
"/relationships": "Relationships",
|
|
548
|
+
"/events": "Events",
|
|
549
|
+
// SaaS
|
|
550
|
+
"/customers": "Customers",
|
|
551
|
+
"/subscriptions": "Subscriptions",
|
|
552
|
+
"/integrations": "Integrations",
|
|
553
|
+
// Admin
|
|
554
|
+
"/orgs": "Organizations",
|
|
555
|
+
"/roles": "Roles",
|
|
556
|
+
"/users": "Users",
|
|
557
|
+
"/api-keys": "API Keys",
|
|
558
|
+
"/settings": "Settings"
|
|
559
|
+
};
|
|
560
|
+
function segmentToLabel(segment) {
|
|
561
|
+
const knownLabel = ROUTE_LABELS[`/${segment}`];
|
|
562
|
+
if (knownLabel) return knownLabel;
|
|
563
|
+
return segment.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
564
|
+
}
|
|
565
|
+
function useBreadcrumbs(options) {
|
|
566
|
+
const { rootLabel = "Admin", includeRoot = true } = options ?? {};
|
|
567
|
+
const routerState = useRouterState();
|
|
568
|
+
const pathname = routerState.location.pathname;
|
|
569
|
+
const breadcrumbs = [];
|
|
570
|
+
if (pathname === "/" || pathname === "") {
|
|
571
|
+
if (includeRoot) {
|
|
572
|
+
breadcrumbs.push({ label: rootLabel });
|
|
573
|
+
}
|
|
574
|
+
return breadcrumbs;
|
|
575
|
+
}
|
|
576
|
+
if (includeRoot) {
|
|
577
|
+
breadcrumbs.push({ label: rootLabel, href: "/" });
|
|
578
|
+
}
|
|
579
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
580
|
+
let currentPath = "";
|
|
581
|
+
segments.forEach((segment, index) => {
|
|
582
|
+
currentPath += `/${segment}`;
|
|
583
|
+
const isLast = index === segments.length - 1;
|
|
584
|
+
const label = ROUTE_LABELS[currentPath] || segmentToLabel(segment);
|
|
585
|
+
breadcrumbs.push({
|
|
586
|
+
label,
|
|
587
|
+
// Last item doesn't get a href (it's the current page)
|
|
588
|
+
href: isLast ? void 0 : currentPath
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
return breadcrumbs;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
export { namespacesKeys, schemaKeys, typesKeys, useBreadcrumbs, useEditHistory, useKeyboardShortcuts, useNamespaces, useSchema, useSchemaDefinition, useSingleThingSubscription, useThingSubscription, useTypes };
|
|
595
|
+
//# sourceMappingURL=chunk-NA652ART.js.map
|
|
596
|
+
//# sourceMappingURL=chunk-NA652ART.js.map
|