@noya-app/noya-multiplayer-react 0.1.63 → 0.1.64
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +10 -0
- package/dist/index.bundle.js +18 -18
- package/dist/index.d.mts +33 -10
- package/dist/index.d.ts +33 -10
- package/dist/index.js +1410 -329
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1357 -283
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/NoyaStateContext.tsx +225 -19
- package/src/inspector/StateInspector.tsx +141 -20
- package/src/inspector/StateInspectorTitleLabel.tsx +13 -0
- package/src/inspector/sections/ActivityEventsSection.tsx +136 -0
- package/src/inspector/utils.ts +2 -2
- package/src/noyaApp.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noya-app/noya-multiplayer-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.64",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
"dev": "npm run build -- --watch"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@noya-app/state-manager": "0.1.
|
|
15
|
+
"@noya-app/state-manager": "0.1.50",
|
|
16
16
|
"@noya-app/emitter": "0.1.0",
|
|
17
|
-
"@noya-app/observable": "0.1.
|
|
17
|
+
"@noya-app/observable": "0.1.12",
|
|
18
18
|
"@noya-app/task-runner": "0.1.6",
|
|
19
|
-
"@noya-app/react-utils": "0.1.
|
|
19
|
+
"@noya-app/react-utils": "0.1.25",
|
|
20
20
|
"react-inspector": "6.0.2"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
package/src/NoyaStateContext.tsx
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { MenuItem } from "@noya-app/noya-designsystem";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
diffResourceMaps,
|
|
6
|
+
Input,
|
|
7
|
+
MediaItem,
|
|
8
|
+
OutputTransform,
|
|
9
|
+
Resource,
|
|
10
|
+
ResourceCreateMap,
|
|
11
|
+
ResourceMap,
|
|
12
|
+
} from "@noya-app/noya-schemas";
|
|
5
13
|
import {
|
|
6
14
|
GetAtPath,
|
|
7
15
|
Observable,
|
|
8
16
|
ObservableOptions,
|
|
9
17
|
PathKey,
|
|
10
18
|
} from "@noya-app/observable";
|
|
11
|
-
import { useStableCallback } from "@noya-app/react-utils";
|
|
19
|
+
import { useJsonMemo, useStableCallback } from "@noya-app/react-utils";
|
|
12
20
|
import {
|
|
21
|
+
ActivityEventsManager,
|
|
13
22
|
ConnectedUsersManager,
|
|
14
23
|
CreateParams,
|
|
15
24
|
EphemeralUserDataManager,
|
|
@@ -17,18 +26,22 @@ import {
|
|
|
17
26
|
MultiplayerStateManager,
|
|
18
27
|
NoyaManager,
|
|
19
28
|
PublishCallback,
|
|
29
|
+
ResourceManager,
|
|
20
30
|
SafeEval,
|
|
21
31
|
StateManagerOptions,
|
|
22
32
|
Static,
|
|
33
|
+
StreamFilter,
|
|
23
34
|
TSchema,
|
|
24
35
|
} from "@noya-app/state-manager";
|
|
25
36
|
import React, {
|
|
26
37
|
createContext,
|
|
38
|
+
Dispatch,
|
|
27
39
|
SetStateAction,
|
|
28
40
|
useCallback,
|
|
29
41
|
useContext,
|
|
30
42
|
useEffect,
|
|
31
43
|
useMemo,
|
|
44
|
+
useState,
|
|
32
45
|
} from "react";
|
|
33
46
|
import {
|
|
34
47
|
AppTheme,
|
|
@@ -207,6 +220,27 @@ export function useConnectedUsersManager() {
|
|
|
207
220
|
return useContext(ConnectedUsersContext);
|
|
208
221
|
}
|
|
209
222
|
|
|
223
|
+
export function useConnectedUsers() {
|
|
224
|
+
const connectedUsersManager = useConnectedUsersManager();
|
|
225
|
+
return useObservable(connectedUsersManager?.connectedUsers$);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function useConnectedUser(userId?: string | null) {
|
|
229
|
+
const connectedUsersManager = useConnectedUsersManager();
|
|
230
|
+
return useObservable(
|
|
231
|
+
connectedUsersManager?.connectedUsers$,
|
|
232
|
+
useCallback(
|
|
233
|
+
(users) => {
|
|
234
|
+
return users.find((user) => {
|
|
235
|
+
const prefix = user.id.slice(0, 8);
|
|
236
|
+
return userId?.includes(prefix);
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
[userId]
|
|
240
|
+
)
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
210
244
|
export const AnyEphemeralUserDataManagerContext = createContext<
|
|
211
245
|
EphemeralUserDataManager<object> | undefined
|
|
212
246
|
>(undefined);
|
|
@@ -220,6 +254,163 @@ export function useCurrentUserId() {
|
|
|
220
254
|
return useObservable(connectedUsersManager?.currentUserId$);
|
|
221
255
|
}
|
|
222
256
|
|
|
257
|
+
export function useIsProcessing() {
|
|
258
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
259
|
+
return useObservable(noyaManager.isProcessing$);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function useResourceManager(): ResourceManager {
|
|
263
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
264
|
+
return noyaManager.resourceManager;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// export function useResources(): Resource[] {
|
|
268
|
+
// const { noyaManager } = useAnyNoyaStateContext();
|
|
269
|
+
// const resources = useObservable(noyaManager.resourceManager.resources$);
|
|
270
|
+
// return resources;
|
|
271
|
+
// }
|
|
272
|
+
|
|
273
|
+
export function resourceToMediaItem(resource: Resource): MediaItem {
|
|
274
|
+
switch (resource.type) {
|
|
275
|
+
case "asset":
|
|
276
|
+
return { kind: "asset", id: resource.id, assetId: resource.assetId };
|
|
277
|
+
case "file":
|
|
278
|
+
return { kind: "noyaFile", id: resource.id, fileId: resource.fileId };
|
|
279
|
+
default:
|
|
280
|
+
return { kind: "folder", id: resource.id };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function useResources({
|
|
285
|
+
shouldDeleteAssets = true,
|
|
286
|
+
}: {
|
|
287
|
+
shouldDeleteAssets?: boolean;
|
|
288
|
+
} = {}): [ResourceMap, Dispatch<SetStateAction<ResourceCreateMap>>] {
|
|
289
|
+
const resourceManager = useResourceManager();
|
|
290
|
+
const assetManager = useAssetManager();
|
|
291
|
+
|
|
292
|
+
const resourceMap = useObservable(
|
|
293
|
+
resourceManager.optimisticResources$,
|
|
294
|
+
useCallback((resources) => {
|
|
295
|
+
return Object.fromEntries(
|
|
296
|
+
resources.map((resource) => [resource.path, resource])
|
|
297
|
+
);
|
|
298
|
+
}, [])
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
const setResourceMap = useCallback(
|
|
302
|
+
async (action: SetStateAction<ResourceCreateMap>) => {
|
|
303
|
+
const newResourceMap =
|
|
304
|
+
action instanceof Function ? action(resourceMap) : action;
|
|
305
|
+
|
|
306
|
+
const { addedResources, removedResources, modifiedResources } =
|
|
307
|
+
diffResourceMaps(resourceMap, newResourceMap, "id");
|
|
308
|
+
|
|
309
|
+
if (addedResources.length > 0) {
|
|
310
|
+
const payload = addedResources.map((resource) => {
|
|
311
|
+
switch (resource.type) {
|
|
312
|
+
case "directory":
|
|
313
|
+
return {
|
|
314
|
+
path: resource.path,
|
|
315
|
+
type: "directory" as const,
|
|
316
|
+
};
|
|
317
|
+
case "asset":
|
|
318
|
+
return {
|
|
319
|
+
path: resource.path,
|
|
320
|
+
type: "asset" as const,
|
|
321
|
+
assetId: resource.assetId,
|
|
322
|
+
asset: resource.asset,
|
|
323
|
+
};
|
|
324
|
+
case "file":
|
|
325
|
+
return {
|
|
326
|
+
path: resource.path,
|
|
327
|
+
type: "file" as const,
|
|
328
|
+
fileId: resource.fileId,
|
|
329
|
+
};
|
|
330
|
+
case "resource":
|
|
331
|
+
return {
|
|
332
|
+
path: resource.path,
|
|
333
|
+
type: "resource" as const,
|
|
334
|
+
fileId: resource.fileId,
|
|
335
|
+
resourceId: resource.resourceId,
|
|
336
|
+
};
|
|
337
|
+
default:
|
|
338
|
+
throw new Error(
|
|
339
|
+
`Unknown resource type: ${(resource as any).type}`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
await resourceManager.createResource(payload);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
for (const resource of removedResources) {
|
|
348
|
+
await resourceManager.deleteResource({ id: resource.id });
|
|
349
|
+
|
|
350
|
+
if (shouldDeleteAssets && resource.type === "asset") {
|
|
351
|
+
try {
|
|
352
|
+
await assetManager.delete(resource.assetId);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error("Failed to delete asset:", error);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
await Promise.all(
|
|
360
|
+
modifiedResources.map(({ id, path, assetId, asset }) =>
|
|
361
|
+
resourceManager.updateResource({
|
|
362
|
+
id,
|
|
363
|
+
path,
|
|
364
|
+
assetId,
|
|
365
|
+
asset,
|
|
366
|
+
})
|
|
367
|
+
)
|
|
368
|
+
);
|
|
369
|
+
},
|
|
370
|
+
[resourceMap, resourceManager, shouldDeleteAssets, assetManager]
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
return [resourceMap, setResourceMap];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const emptyArray: unknown[] = [];
|
|
377
|
+
|
|
378
|
+
export function useActivityEvents(streamFilter: StreamFilter) {
|
|
379
|
+
const { noyaManager } = useAnyNoyaStateContext();
|
|
380
|
+
return useActivityEventsForManager(
|
|
381
|
+
streamFilter,
|
|
382
|
+
noyaManager.activityEventsManager
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export function useActivityEventsForManager(
|
|
387
|
+
streamFilter: StreamFilter | undefined,
|
|
388
|
+
activityEventsManager: ActivityEventsManager
|
|
389
|
+
) {
|
|
390
|
+
const [streamId, setStreamId] = useState<string | undefined>(undefined);
|
|
391
|
+
const stableStreamFilter = useJsonMemo(streamFilter);
|
|
392
|
+
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
if (!stableStreamFilter) return;
|
|
395
|
+
|
|
396
|
+
const streamId = activityEventsManager.subscribe(stableStreamFilter);
|
|
397
|
+
|
|
398
|
+
setStreamId(streamId);
|
|
399
|
+
|
|
400
|
+
return () => {
|
|
401
|
+
setStreamId(undefined);
|
|
402
|
+
|
|
403
|
+
activityEventsManager.unsubscribe(streamId);
|
|
404
|
+
};
|
|
405
|
+
}, [activityEventsManager, stableStreamFilter]);
|
|
406
|
+
|
|
407
|
+
const observable = streamId
|
|
408
|
+
? activityEventsManager.getStream(streamId)
|
|
409
|
+
: undefined;
|
|
410
|
+
|
|
411
|
+
return useObservable(observable) ?? emptyArray;
|
|
412
|
+
}
|
|
413
|
+
|
|
223
414
|
export const FallbackUntilInitialized = ({
|
|
224
415
|
children,
|
|
225
416
|
fallback,
|
|
@@ -267,6 +458,28 @@ export function createNoyaContext<
|
|
|
267
458
|
EphemeralUserDataManager<E> | undefined
|
|
268
459
|
>;
|
|
269
460
|
|
|
461
|
+
function NoyaContextProvider({
|
|
462
|
+
children,
|
|
463
|
+
contextValue,
|
|
464
|
+
}: {
|
|
465
|
+
children: React.ReactNode;
|
|
466
|
+
contextValue: AnyNoyaStateContextValue;
|
|
467
|
+
}) {
|
|
468
|
+
return (
|
|
469
|
+
<AnyNoyaStateContext.Provider value={contextValue}>
|
|
470
|
+
<ConnectedUsersContext.Provider
|
|
471
|
+
value={contextValue.noyaManager.connectedUsersManager}
|
|
472
|
+
>
|
|
473
|
+
<EphemeralUserDataManagerContext.Provider
|
|
474
|
+
value={contextValue.noyaManager.ephemeralUserDataManager}
|
|
475
|
+
>
|
|
476
|
+
{children}
|
|
477
|
+
</EphemeralUserDataManagerContext.Provider>
|
|
478
|
+
</ConnectedUsersContext.Provider>
|
|
479
|
+
</AnyNoyaStateContext.Provider>
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
270
483
|
function NoyaStateProvider({
|
|
271
484
|
children,
|
|
272
485
|
initialState,
|
|
@@ -294,23 +507,15 @@ export function createNoyaContext<
|
|
|
294
507
|
);
|
|
295
508
|
|
|
296
509
|
return (
|
|
297
|
-
<
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
{children}
|
|
307
|
-
</FallbackUntilInitialized>
|
|
308
|
-
) : (
|
|
309
|
-
children
|
|
310
|
-
)}
|
|
311
|
-
</EphemeralUserDataManagerContext.Provider>
|
|
312
|
-
</ConnectedUsersContext.Provider>
|
|
313
|
-
</AnyNoyaStateContext.Provider>
|
|
510
|
+
<NoyaContextProvider contextValue={contextValue}>
|
|
511
|
+
{options.fallback !== undefined ? (
|
|
512
|
+
<FallbackUntilInitialized fallback={options.fallback}>
|
|
513
|
+
{children}
|
|
514
|
+
</FallbackUntilInitialized>
|
|
515
|
+
) : (
|
|
516
|
+
children
|
|
517
|
+
)}
|
|
518
|
+
</NoyaContextProvider>
|
|
314
519
|
);
|
|
315
520
|
}
|
|
316
521
|
|
|
@@ -513,6 +718,7 @@ export function createNoyaContext<
|
|
|
513
718
|
return {
|
|
514
719
|
Context: NoyaStateContext,
|
|
515
720
|
Provider: NoyaStateProvider,
|
|
721
|
+
NoyaContextProvider,
|
|
516
722
|
useValue,
|
|
517
723
|
useSetValue,
|
|
518
724
|
useValueState,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-globals */
|
|
1
2
|
"use client";
|
|
2
3
|
|
|
3
4
|
import { Input, OutputTransform } from "@noya-app/noya-schemas";
|
|
5
|
+
import { Base64, uuid } from "@noya-app/noya-utils";
|
|
4
6
|
import { downloadBlob, memoGeneric } from "@noya-app/react-utils";
|
|
5
7
|
import { NoyaManager } from "@noya-app/state-manager";
|
|
6
8
|
import React, {
|
|
@@ -18,6 +20,7 @@ import {
|
|
|
18
20
|
getStateInspectorBorderColor,
|
|
19
21
|
getStateInspectorTheme,
|
|
20
22
|
} from "./inspectorTheme";
|
|
23
|
+
import { ActivityEventsSection } from "./sections/ActivityEventsSection";
|
|
21
24
|
import { EventsSection } from "./sections/EventsSection";
|
|
22
25
|
import { HistorySection } from "./sections/HistorySection";
|
|
23
26
|
import { exportAll, importAll } from "./serialization";
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
StateInspectorDisclosureSection,
|
|
28
31
|
} from "./StateInspectorDisclosureSection";
|
|
29
32
|
import { StateInspectorRow } from "./StateInspectorRow";
|
|
33
|
+
import { StateInspectorTitleLabel } from "./StateInspectorTitleLabel";
|
|
30
34
|
import { StateInspectorToggleButton } from "./StateInspectorToggleButton";
|
|
31
35
|
import { useLocalStorageState } from "./useLocalStorageState";
|
|
32
36
|
import { ellipsis, uploadFile } from "./utils";
|
|
@@ -67,6 +71,8 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
67
71
|
connectionEventManager,
|
|
68
72
|
taskManager,
|
|
69
73
|
ioManager,
|
|
74
|
+
resourceManager,
|
|
75
|
+
activityEventsManager,
|
|
70
76
|
} = noyaManager;
|
|
71
77
|
|
|
72
78
|
const [didMount, setDidMount] = React.useState(false);
|
|
@@ -79,6 +85,7 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
79
85
|
}, []);
|
|
80
86
|
|
|
81
87
|
const eventsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
88
|
+
const activityEventsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
82
89
|
|
|
83
90
|
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
84
91
|
"noya-multiplayer-react-show-inspector",
|
|
@@ -112,6 +119,10 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
112
119
|
"noya-multiplayer-react-show-assets",
|
|
113
120
|
false
|
|
114
121
|
);
|
|
122
|
+
const [showResources, setShowResources] = useLocalStorageState(
|
|
123
|
+
"noya-multiplayer-react-show-resources",
|
|
124
|
+
false
|
|
125
|
+
);
|
|
115
126
|
const [showSecrets, setShowSecrets] = useLocalStorageState(
|
|
116
127
|
"noya-multiplayer-react-show-secrets",
|
|
117
128
|
false
|
|
@@ -124,9 +135,12 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
124
135
|
"noya-multiplayer-react-show-output-transforms",
|
|
125
136
|
false
|
|
126
137
|
);
|
|
138
|
+
const [showActivityEvents, setShowActivityEvents] = useLocalStorageState(
|
|
139
|
+
"noya-multiplayer-react-show-activity-events",
|
|
140
|
+
false
|
|
141
|
+
);
|
|
127
142
|
|
|
128
143
|
const connectionEvents = useObservable(connectionEventManager.events$);
|
|
129
|
-
|
|
130
144
|
useEffect(() => {
|
|
131
145
|
if (eventsContainerRef.current) {
|
|
132
146
|
eventsContainerRef.current.scrollTop =
|
|
@@ -140,6 +154,8 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
140
154
|
const ephemeral = useObservable(ephemeralUserDataManager.data$);
|
|
141
155
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
142
156
|
const assets = useObservable(assetManager.assets$);
|
|
157
|
+
const resources = useObservable(resourceManager.resources$);
|
|
158
|
+
const resourcesInitialized = useObservable(resourceManager.isInitialized$);
|
|
143
159
|
const assetsInitialized = useObservable(assetManager.isInitialized$);
|
|
144
160
|
const secrets = useObservable(secretManager.secrets$);
|
|
145
161
|
const secretsInitialized = useObservable(secretManager.isInitialized$);
|
|
@@ -150,7 +166,6 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
150
166
|
const outputTransformsInitialized = useObservable(
|
|
151
167
|
ioManager.outputTransformsInitialized$
|
|
152
168
|
);
|
|
153
|
-
|
|
154
169
|
const theme = getStateInspectorTheme(colorScheme);
|
|
155
170
|
const solidBorderColor = getStateInspectorBorderColor(colorScheme);
|
|
156
171
|
|
|
@@ -290,12 +305,12 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
290
305
|
</StateInspectorDisclosureSection>
|
|
291
306
|
<StateInspectorDisclosureSection
|
|
292
307
|
title={
|
|
293
|
-
<
|
|
308
|
+
<StateInspectorTitleLabel>
|
|
294
309
|
Data
|
|
295
310
|
<ColoredDot
|
|
296
311
|
type={multipeerStateInitialized ? "success" : "error"}
|
|
297
312
|
/>
|
|
298
|
-
</
|
|
313
|
+
</StateInspectorTitleLabel>
|
|
299
314
|
}
|
|
300
315
|
colorScheme={colorScheme}
|
|
301
316
|
setOpen={setShowData}
|
|
@@ -355,14 +370,28 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
355
370
|
open={showAssets}
|
|
356
371
|
setOpen={setShowAssets}
|
|
357
372
|
title={
|
|
358
|
-
<
|
|
373
|
+
<StateInspectorTitleLabel>
|
|
359
374
|
Assets ({assets.length})
|
|
360
375
|
<ColoredDot type={assetsInitialized ? "success" : "error"} />
|
|
361
|
-
</
|
|
376
|
+
</StateInspectorTitleLabel>
|
|
362
377
|
}
|
|
363
378
|
colorScheme={colorScheme}
|
|
364
379
|
right={
|
|
365
380
|
<span style={{ display: "flex", gap: "10px" }}>
|
|
381
|
+
<StateInspectorButton
|
|
382
|
+
theme={theme}
|
|
383
|
+
onClick={async () => {
|
|
384
|
+
const ok = confirm(
|
|
385
|
+
"Are you sure you want to delete all assets?"
|
|
386
|
+
);
|
|
387
|
+
if (!ok) return;
|
|
388
|
+
await Promise.all(
|
|
389
|
+
assets.map((asset) => assetManager.delete(asset.id))
|
|
390
|
+
);
|
|
391
|
+
}}
|
|
392
|
+
>
|
|
393
|
+
Delete all
|
|
394
|
+
</StateInspectorButton>
|
|
366
395
|
<StateInspectorButton
|
|
367
396
|
theme={theme}
|
|
368
397
|
onClick={() => {
|
|
@@ -416,10 +445,103 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
416
445
|
</StateInspectorDisclosureSection>
|
|
417
446
|
<StateInspectorDisclosureSection
|
|
418
447
|
title={
|
|
419
|
-
<
|
|
448
|
+
<StateInspectorTitleLabel>
|
|
449
|
+
Resources ({resources.length})
|
|
450
|
+
<ColoredDot type={resourcesInitialized ? "success" : "error"} />
|
|
451
|
+
</StateInspectorTitleLabel>
|
|
452
|
+
}
|
|
453
|
+
colorScheme={colorScheme}
|
|
454
|
+
open={showResources}
|
|
455
|
+
setOpen={setShowResources}
|
|
456
|
+
right={
|
|
457
|
+
<span style={{ display: "flex", gap: "10px" }}>
|
|
458
|
+
<StateInspectorButton
|
|
459
|
+
theme={theme}
|
|
460
|
+
onClick={async () => {
|
|
461
|
+
const ok = confirm(
|
|
462
|
+
"Are you sure you want to delete all resources?"
|
|
463
|
+
);
|
|
464
|
+
if (!ok) return;
|
|
465
|
+
await Promise.all(
|
|
466
|
+
resources.map((resource) =>
|
|
467
|
+
resourceManager.deleteResource({ id: resource.id })
|
|
468
|
+
)
|
|
469
|
+
);
|
|
470
|
+
}}
|
|
471
|
+
>
|
|
472
|
+
Delete all
|
|
473
|
+
</StateInspectorButton>
|
|
474
|
+
<StateInspectorButton
|
|
475
|
+
theme={theme}
|
|
476
|
+
onClick={async () => {
|
|
477
|
+
const path = prompt("Enter directory path") || uuid();
|
|
478
|
+
await resourceManager.createResource({
|
|
479
|
+
type: "directory",
|
|
480
|
+
path,
|
|
481
|
+
});
|
|
482
|
+
}}
|
|
483
|
+
>
|
|
484
|
+
Create Directory
|
|
485
|
+
</StateInspectorButton>
|
|
486
|
+
<StateInspectorButton
|
|
487
|
+
theme={theme}
|
|
488
|
+
onClick={async () => {
|
|
489
|
+
const file = await uploadFile();
|
|
490
|
+
|
|
491
|
+
resourceManager.createResource({
|
|
492
|
+
type: "asset",
|
|
493
|
+
path: file.name || uuid(),
|
|
494
|
+
asset: {
|
|
495
|
+
content: Base64.encode(await file.arrayBuffer()),
|
|
496
|
+
contentType: file.type,
|
|
497
|
+
encoding: "base64",
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
}}
|
|
501
|
+
>
|
|
502
|
+
Create Asset
|
|
503
|
+
</StateInspectorButton>
|
|
504
|
+
</span>
|
|
505
|
+
}
|
|
506
|
+
>
|
|
507
|
+
<StateInspectorDisclosureRowInner>
|
|
508
|
+
{resources?.map((resource) => (
|
|
509
|
+
<StateInspectorRow key={resource.id} colorScheme={colorScheme}>
|
|
510
|
+
<ObjectInspector
|
|
511
|
+
name={resource.path}
|
|
512
|
+
data={resource}
|
|
513
|
+
theme={theme}
|
|
514
|
+
/>
|
|
515
|
+
<div style={{ display: "flex", gap: "4px" }}>
|
|
516
|
+
<StateInspectorButton
|
|
517
|
+
theme={theme}
|
|
518
|
+
onClick={() =>
|
|
519
|
+
resourceManager.deleteResource({ id: resource.id })
|
|
520
|
+
}
|
|
521
|
+
>
|
|
522
|
+
Delete
|
|
523
|
+
</StateInspectorButton>
|
|
524
|
+
<StateInspectorButton
|
|
525
|
+
theme={theme}
|
|
526
|
+
onClick={() => {
|
|
527
|
+
const path = prompt("Enter new path", resource.path);
|
|
528
|
+
if (!path) return;
|
|
529
|
+
resourceManager.updateResource({ id: resource.id, path });
|
|
530
|
+
}}
|
|
531
|
+
>
|
|
532
|
+
Rename
|
|
533
|
+
</StateInspectorButton>
|
|
534
|
+
</div>
|
|
535
|
+
</StateInspectorRow>
|
|
536
|
+
))}
|
|
537
|
+
</StateInspectorDisclosureRowInner>
|
|
538
|
+
</StateInspectorDisclosureSection>
|
|
539
|
+
<StateInspectorDisclosureSection
|
|
540
|
+
title={
|
|
541
|
+
<StateInspectorTitleLabel>
|
|
420
542
|
Secrets
|
|
421
543
|
<ColoredDot type={secretsInitialized ? "success" : "error"} />
|
|
422
|
-
</
|
|
544
|
+
</StateInspectorTitleLabel>
|
|
423
545
|
}
|
|
424
546
|
colorScheme={colorScheme}
|
|
425
547
|
open={showSecrets}
|
|
@@ -457,10 +579,10 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
457
579
|
open={showInputs}
|
|
458
580
|
setOpen={setShowInputs}
|
|
459
581
|
title={
|
|
460
|
-
<
|
|
582
|
+
<StateInspectorTitleLabel>
|
|
461
583
|
Inputs
|
|
462
584
|
<ColoredDot type={inputsInitialized ? "success" : "error"} />
|
|
463
|
-
</
|
|
585
|
+
</StateInspectorTitleLabel>
|
|
464
586
|
}
|
|
465
587
|
colorScheme={colorScheme}
|
|
466
588
|
>
|
|
@@ -489,12 +611,12 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
489
611
|
open={showOutputTransforms}
|
|
490
612
|
setOpen={setShowOutputTransforms}
|
|
491
613
|
title={
|
|
492
|
-
<
|
|
614
|
+
<StateInspectorTitleLabel>
|
|
493
615
|
Output Transforms
|
|
494
616
|
<ColoredDot
|
|
495
617
|
type={outputTransformsInitialized ? "success" : "error"}
|
|
496
618
|
/>
|
|
497
|
-
</
|
|
619
|
+
</StateInspectorTitleLabel>
|
|
498
620
|
}
|
|
499
621
|
colorScheme={colorScheme}
|
|
500
622
|
>
|
|
@@ -567,6 +689,13 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
567
689
|
))}
|
|
568
690
|
</StateInspectorDisclosureRowInner>
|
|
569
691
|
</StateInspectorDisclosureSection>
|
|
692
|
+
<ActivityEventsSection
|
|
693
|
+
colorScheme={colorScheme}
|
|
694
|
+
activityEventsContainerRef={activityEventsContainerRef}
|
|
695
|
+
showEvents={showActivityEvents}
|
|
696
|
+
setShowEvents={setShowActivityEvents}
|
|
697
|
+
activityEventsManager={activityEventsManager}
|
|
698
|
+
/>
|
|
570
699
|
<EventsSection<S>
|
|
571
700
|
connectionEvents={connectionEvents}
|
|
572
701
|
colorScheme={colorScheme}
|
|
@@ -577,11 +706,3 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
577
706
|
</div>
|
|
578
707
|
);
|
|
579
708
|
});
|
|
580
|
-
|
|
581
|
-
function TitleLabel({ children }: { children: React.ReactNode }) {
|
|
582
|
-
return (
|
|
583
|
-
<span style={{ display: "flex", alignItems: "center", gap: "4px" }}>
|
|
584
|
-
{children}
|
|
585
|
-
</span>
|
|
586
|
-
);
|
|
587
|
-
}
|