@noya-app/noya-multiplayer-react 0.1.12 → 0.1.14
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 +9 -9
- package/CHANGELOG.md +16 -0
- package/dist/index.d.mts +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.js +228 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +228 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/globals.ts +2 -1
- package/src/hooks.ts +60 -16
- package/src/inspector/StateInspector.tsx +185 -18
- package/src/inspector/useLocalStorageState.tsx +2 -0
- package/src/inspector/useStateInspector.tsx +18 -5
package/.turbo/turbo-build.log
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
[34mCLI[39m Target: esnext
|
|
6
6
|
[34mCJS[39m Build start
|
|
7
7
|
[34mESM[39m Build start
|
|
8
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
9
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[
|
|
10
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
12
|
-
[32mCJS[39m [1mdist/index.js.map [22m[
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
8
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m29.45 KB[39m
|
|
9
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m53.24 KB[39m
|
|
10
|
+
[32mESM[39m ⚡️ Build success in 71ms
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m33.48 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m53.03 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 76ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
15
|
"ComponentPropsWithoutRef" is imported from external module "react" but never used in "src/inspector/StateInspector.tsx" and "src/hooks.ts".
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m2.
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 2151ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.69 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m2.69 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @noya-app/state-manager
|
|
2
2
|
|
|
3
|
+
## 0.1.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 380da63: Add more inspector tools
|
|
8
|
+
- Updated dependencies [380da63]
|
|
9
|
+
- @noya-app/state-manager@0.1.14
|
|
10
|
+
|
|
11
|
+
## 0.1.13
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 149f2f9: Improve multiplayer
|
|
16
|
+
- Updated dependencies [149f2f9]
|
|
17
|
+
- @noya-app/state-manager@0.1.13
|
|
18
|
+
|
|
3
19
|
## 0.1.12
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import * as _noya_app_state_manager from '@noya-app/state-manager';
|
|
2
|
-
import { ConnectionEvent, MultiplayerUser, StateManager, Get, StateManagerOptions,
|
|
2
|
+
import { ConnectionEvent, MultiplayerUser, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions } from '@noya-app/state-manager';
|
|
3
3
|
export * from '@noya-app/state-manager';
|
|
4
4
|
import React, { SetStateAction, ComponentProps } from 'react';
|
|
5
5
|
|
|
6
|
-
type Anchor = "left" | "right";
|
|
7
|
-
declare const StateInspector: React.MemoExoticComponent<(<S extends object, M>({ state, connectionEvents, connectedUsers, userId, unstyled, colorScheme,
|
|
6
|
+
type Anchor = "left" | "right" | "bottom left" | "bottom right";
|
|
7
|
+
declare const StateInspector: React.MemoExoticComponent<(<S extends object, M>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, anchor, forceInit, ...props }: {
|
|
8
8
|
state: S;
|
|
9
9
|
connectionEvents?: ConnectionEvent<S>[] | undefined;
|
|
10
10
|
connectedUsers?: MultiplayerUser[] | undefined;
|
|
11
|
+
tasks?: Task[] | undefined;
|
|
11
12
|
userId?: string | undefined;
|
|
12
13
|
unstyled?: boolean | undefined;
|
|
13
14
|
colorScheme?: "light" | "dark" | undefined;
|
|
14
|
-
|
|
15
|
+
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
15
16
|
anchor?: Anchor | undefined;
|
|
17
|
+
forceInit: () => void;
|
|
16
18
|
} & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
|
|
17
19
|
|
|
18
20
|
declare function useSyncStateManager<S extends object, M>(stateManager: StateManager<S, M>): S;
|
|
@@ -20,13 +22,15 @@ declare function useSyncStateManager<S extends object, M, P extends string>(stat
|
|
|
20
22
|
declare function useManagedState<S extends object, M = void>(createInitialState: () => S, options?: StateManagerOptions<S, M>): readonly [S, (...args: M extends {} ? [metadata: M, action: SetStateAction<S>] : [action: SetStateAction<S>]) => void, StateManager<S, M>];
|
|
21
23
|
declare function useManagedHistory<S extends object, M = void>(stateManager: StateManager<S, M>): _noya_app_state_manager.HistorySnapshot<S, M>;
|
|
22
24
|
declare function useSyncMultiplayerStateManager<S extends object, M = void>(multiplayerStateManager: MultiplayerStateManager<S, M>): S;
|
|
23
|
-
declare function useMultiplayerState<S extends object, M = void>(initialState: S | (() => S), options
|
|
25
|
+
declare function useMultiplayerState<S extends object, M = void>(initialState: S | (() => S), options?: MultiplayerStateManagerOptions<S, M> & {
|
|
24
26
|
sync?: (options: {
|
|
25
27
|
ms: MultiplayerStateManager<S, M>;
|
|
26
28
|
}) => void;
|
|
27
29
|
trackConnectionEvents?: boolean;
|
|
30
|
+
trackTasks?: boolean;
|
|
28
31
|
inspector?: boolean | Pick<ComponentProps<typeof StateInspector>, "colorScheme" | "anchor">;
|
|
29
32
|
}): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, MultiplayerStateManager<S, M>, {
|
|
33
|
+
tasks: Task[];
|
|
30
34
|
connectionEvents: ConnectionEvent<S>[] | undefined;
|
|
31
35
|
connectedUsers: MultiplayerUser[];
|
|
32
36
|
}];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import * as _noya_app_state_manager from '@noya-app/state-manager';
|
|
2
|
-
import { ConnectionEvent, MultiplayerUser, StateManager, Get, StateManagerOptions,
|
|
2
|
+
import { ConnectionEvent, MultiplayerUser, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions } from '@noya-app/state-manager';
|
|
3
3
|
export * from '@noya-app/state-manager';
|
|
4
4
|
import React, { SetStateAction, ComponentProps } from 'react';
|
|
5
5
|
|
|
6
|
-
type Anchor = "left" | "right";
|
|
7
|
-
declare const StateInspector: React.MemoExoticComponent<(<S extends object, M>({ state, connectionEvents, connectedUsers, userId, unstyled, colorScheme,
|
|
6
|
+
type Anchor = "left" | "right" | "bottom left" | "bottom right";
|
|
7
|
+
declare const StateInspector: React.MemoExoticComponent<(<S extends object, M>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, anchor, forceInit, ...props }: {
|
|
8
8
|
state: S;
|
|
9
9
|
connectionEvents?: ConnectionEvent<S>[] | undefined;
|
|
10
10
|
connectedUsers?: MultiplayerUser[] | undefined;
|
|
11
|
+
tasks?: Task[] | undefined;
|
|
11
12
|
userId?: string | undefined;
|
|
12
13
|
unstyled?: boolean | undefined;
|
|
13
14
|
colorScheme?: "light" | "dark" | undefined;
|
|
14
|
-
|
|
15
|
+
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
15
16
|
anchor?: Anchor | undefined;
|
|
17
|
+
forceInit: () => void;
|
|
16
18
|
} & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
|
|
17
19
|
|
|
18
20
|
declare function useSyncStateManager<S extends object, M>(stateManager: StateManager<S, M>): S;
|
|
@@ -20,13 +22,15 @@ declare function useSyncStateManager<S extends object, M, P extends string>(stat
|
|
|
20
22
|
declare function useManagedState<S extends object, M = void>(createInitialState: () => S, options?: StateManagerOptions<S, M>): readonly [S, (...args: M extends {} ? [metadata: M, action: SetStateAction<S>] : [action: SetStateAction<S>]) => void, StateManager<S, M>];
|
|
21
23
|
declare function useManagedHistory<S extends object, M = void>(stateManager: StateManager<S, M>): _noya_app_state_manager.HistorySnapshot<S, M>;
|
|
22
24
|
declare function useSyncMultiplayerStateManager<S extends object, M = void>(multiplayerStateManager: MultiplayerStateManager<S, M>): S;
|
|
23
|
-
declare function useMultiplayerState<S extends object, M = void>(initialState: S | (() => S), options
|
|
25
|
+
declare function useMultiplayerState<S extends object, M = void>(initialState: S | (() => S), options?: MultiplayerStateManagerOptions<S, M> & {
|
|
24
26
|
sync?: (options: {
|
|
25
27
|
ms: MultiplayerStateManager<S, M>;
|
|
26
28
|
}) => void;
|
|
27
29
|
trackConnectionEvents?: boolean;
|
|
30
|
+
trackTasks?: boolean;
|
|
28
31
|
inspector?: boolean | Pick<ComponentProps<typeof StateInspector>, "colorScheme" | "anchor">;
|
|
29
32
|
}): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, MultiplayerStateManager<S, M>, {
|
|
33
|
+
tasks: Task[];
|
|
30
34
|
connectionEvents: ConnectionEvent<S>[] | undefined;
|
|
31
35
|
connectedUsers: MultiplayerUser[];
|
|
32
36
|
}];
|
package/dist/index.js
CHANGED
|
@@ -75,7 +75,8 @@ function useObservable(observable) {
|
|
|
75
75
|
}, [observable]);
|
|
76
76
|
return value;
|
|
77
77
|
}
|
|
78
|
-
var
|
|
78
|
+
var shouldTrackEvents$ = new Observable(false);
|
|
79
|
+
var shouldTrackTasks$ = new Observable(false);
|
|
79
80
|
|
|
80
81
|
// src/inspector/useStateInspector.tsx
|
|
81
82
|
var import_react4 = __toESM(require("react"));
|
|
@@ -241,7 +242,7 @@ function DisclosureSection({
|
|
|
241
242
|
}
|
|
242
243
|
}
|
|
243
244
|
),
|
|
244
|
-
/* @__PURE__ */ import_react3.default.createElement("span", { style: { flex: "1 1 0" } }, title),
|
|
245
|
+
/* @__PURE__ */ import_react3.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
|
|
245
246
|
right
|
|
246
247
|
),
|
|
247
248
|
open && children
|
|
@@ -292,11 +293,13 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
292
293
|
state,
|
|
293
294
|
connectionEvents,
|
|
294
295
|
connectedUsers,
|
|
296
|
+
tasks,
|
|
295
297
|
userId,
|
|
296
298
|
unstyled,
|
|
297
299
|
colorScheme = "light",
|
|
298
|
-
|
|
300
|
+
multiplayerStateManager,
|
|
299
301
|
anchor = "right",
|
|
302
|
+
forceInit,
|
|
300
303
|
...props
|
|
301
304
|
}) {
|
|
302
305
|
const [didMount, setDidMount] = import_react3.default.useState(false);
|
|
@@ -325,15 +328,22 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
325
328
|
"noya-multiplayer-react-show-data",
|
|
326
329
|
true
|
|
327
330
|
);
|
|
331
|
+
const [showTasks, setShowTasks] = useLocalStorageState(
|
|
332
|
+
"noya-multiplayer-react-show-tasks",
|
|
333
|
+
false
|
|
334
|
+
);
|
|
328
335
|
(0, import_react3.useEffect)(() => {
|
|
329
|
-
|
|
336
|
+
shouldTrackEvents$.set(showEvents);
|
|
330
337
|
}, [showEvents]);
|
|
338
|
+
(0, import_react3.useEffect)(() => {
|
|
339
|
+
shouldTrackTasks$.set(showTasks);
|
|
340
|
+
}, [showTasks]);
|
|
331
341
|
(0, import_react3.useEffect)(() => {
|
|
332
342
|
if (eventsContainerRef.current) {
|
|
333
343
|
eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
|
|
334
344
|
}
|
|
335
345
|
}, [connectionEvents]);
|
|
336
|
-
const historySnapshot = useManagedHistory(
|
|
346
|
+
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
337
347
|
(0, import_react3.useEffect)(() => {
|
|
338
348
|
if (historyContainerRef.current) {
|
|
339
349
|
historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
|
|
@@ -357,7 +367,7 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
357
367
|
const baseStyle = {
|
|
358
368
|
position: "fixed",
|
|
359
369
|
top: 12,
|
|
360
|
-
...anchor
|
|
370
|
+
...anchor.includes("right") ? { right: 12 } : { left: 12 },
|
|
361
371
|
bottom: 12,
|
|
362
372
|
width: 400,
|
|
363
373
|
background: colorScheme === "light" ? "rgba(255,255,255,0.95)" : "rgba(0,0,0,0.95)",
|
|
@@ -383,8 +393,8 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
383
393
|
style: {
|
|
384
394
|
...baseStyle,
|
|
385
395
|
padding: "4px 10px",
|
|
386
|
-
|
|
387
|
-
|
|
396
|
+
width: void 0,
|
|
397
|
+
...anchor.includes("bottom") ? { bottom: 12, top: void 0 } : { bottom: void 0 }
|
|
388
398
|
},
|
|
389
399
|
onClick: () => setShowInspector(true)
|
|
390
400
|
},
|
|
@@ -461,19 +471,42 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
461
471
|
title: "Data",
|
|
462
472
|
colorScheme,
|
|
463
473
|
setOpen: setShowData,
|
|
464
|
-
open: showData
|
|
474
|
+
open: showData,
|
|
475
|
+
right: /* @__PURE__ */ import_react3.default.createElement(
|
|
476
|
+
"span",
|
|
477
|
+
{
|
|
478
|
+
style: {
|
|
479
|
+
display: "flex",
|
|
480
|
+
gap: "4px"
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
484
|
+
SmallButton,
|
|
485
|
+
{
|
|
486
|
+
theme,
|
|
487
|
+
onClick: () => {
|
|
488
|
+
forceInit();
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
"Reset"
|
|
492
|
+
)
|
|
493
|
+
)
|
|
465
494
|
},
|
|
466
|
-
/* @__PURE__ */ import_react3.default.createElement(
|
|
467
|
-
|
|
495
|
+
/* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react3.default.createElement(
|
|
496
|
+
import_react_inspector.ObjectInspector,
|
|
468
497
|
{
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
498
|
+
name: multiplayerStateManager.sm.schema ? "state" : void 0,
|
|
499
|
+
data: state,
|
|
500
|
+
theme
|
|
501
|
+
}
|
|
502
|
+
)), multiplayerStateManager.sm.schema && /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react3.default.createElement(
|
|
503
|
+
import_react_inspector.ObjectInspector,
|
|
504
|
+
{
|
|
505
|
+
name: "schema",
|
|
506
|
+
data: multiplayerStateManager.sm.schema,
|
|
507
|
+
theme
|
|
508
|
+
}
|
|
509
|
+
)))
|
|
477
510
|
),
|
|
478
511
|
/* @__PURE__ */ import_react3.default.createElement(
|
|
479
512
|
DisclosureSection,
|
|
@@ -481,7 +514,68 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
481
514
|
open: showHistory,
|
|
482
515
|
setOpen: setShowHistory,
|
|
483
516
|
title: "History",
|
|
484
|
-
colorScheme
|
|
517
|
+
colorScheme,
|
|
518
|
+
right: /* @__PURE__ */ import_react3.default.createElement(
|
|
519
|
+
"span",
|
|
520
|
+
{
|
|
521
|
+
style: {
|
|
522
|
+
display: "flex",
|
|
523
|
+
gap: "4px"
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
527
|
+
SmallButton,
|
|
528
|
+
{
|
|
529
|
+
disabled: !historySnapshot.canUndo,
|
|
530
|
+
theme,
|
|
531
|
+
onClick: () => {
|
|
532
|
+
multiplayerStateManager.sm.undo();
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
/* @__PURE__ */ import_react3.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
536
|
+
"svg",
|
|
537
|
+
{
|
|
538
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
539
|
+
width: "1em",
|
|
540
|
+
height: "1em",
|
|
541
|
+
viewBox: "0 0 20 20"
|
|
542
|
+
},
|
|
543
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
544
|
+
"path",
|
|
545
|
+
{
|
|
546
|
+
fill: "currentColor",
|
|
547
|
+
d: "M12 5H7V2L1 6l6 4V7h5c2.2 0 4 1.8 4 4s-1.8 4-4 4H7v2h5c3.3 0 6-2.7 6-6s-2.7-6-6-6"
|
|
548
|
+
}
|
|
549
|
+
)
|
|
550
|
+
))
|
|
551
|
+
),
|
|
552
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
553
|
+
SmallButton,
|
|
554
|
+
{
|
|
555
|
+
disabled: !historySnapshot.canRedo,
|
|
556
|
+
theme,
|
|
557
|
+
onClick: () => {
|
|
558
|
+
multiplayerStateManager.sm.redo();
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
/* @__PURE__ */ import_react3.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
562
|
+
"svg",
|
|
563
|
+
{
|
|
564
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
565
|
+
width: "1em",
|
|
566
|
+
height: "1em",
|
|
567
|
+
viewBox: "0 0 20 20"
|
|
568
|
+
},
|
|
569
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
570
|
+
"path",
|
|
571
|
+
{
|
|
572
|
+
fill: "currentColor",
|
|
573
|
+
d: "M8 5h5V2l6 4l-6 4V7H8c-2.2 0-4 1.8-4 4s1.8 4 4 4h5v2H8c-3.3 0-6-2.7-6-6s2.7-6 6-6"
|
|
574
|
+
}
|
|
575
|
+
)
|
|
576
|
+
))
|
|
577
|
+
)
|
|
578
|
+
)
|
|
485
579
|
},
|
|
486
580
|
/* @__PURE__ */ import_react3.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react3.default.createElement(
|
|
487
581
|
"div",
|
|
@@ -536,6 +630,33 @@ var StateInspector = (0, import_react3.memo)(function StateInspector2({
|
|
|
536
630
|
))
|
|
537
631
|
)))
|
|
538
632
|
),
|
|
633
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
634
|
+
DisclosureSection,
|
|
635
|
+
{
|
|
636
|
+
title: "Tasks",
|
|
637
|
+
colorScheme,
|
|
638
|
+
open: showTasks,
|
|
639
|
+
setOpen: setShowTasks
|
|
640
|
+
},
|
|
641
|
+
/* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react3.default.createElement(
|
|
642
|
+
InspectorRow,
|
|
643
|
+
{
|
|
644
|
+
key: task.id,
|
|
645
|
+
colorScheme,
|
|
646
|
+
style: {
|
|
647
|
+
backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
651
|
+
import_react_inspector.ObjectInspector,
|
|
652
|
+
{
|
|
653
|
+
name: task.name,
|
|
654
|
+
data: task.payload,
|
|
655
|
+
theme
|
|
656
|
+
}
|
|
657
|
+
)
|
|
658
|
+
)))
|
|
659
|
+
),
|
|
539
660
|
/* @__PURE__ */ import_react3.default.createElement(
|
|
540
661
|
DisclosureSection,
|
|
541
662
|
{
|
|
@@ -666,6 +787,42 @@ function ellipsis(str, maxLength, position = "end") {
|
|
|
666
787
|
return `${str.slice(0, maxLength)}\u2026`;
|
|
667
788
|
}
|
|
668
789
|
}
|
|
790
|
+
function SmallButton({
|
|
791
|
+
children,
|
|
792
|
+
onClick,
|
|
793
|
+
style,
|
|
794
|
+
theme,
|
|
795
|
+
disabled
|
|
796
|
+
}) {
|
|
797
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
798
|
+
"button",
|
|
799
|
+
{
|
|
800
|
+
type: "button",
|
|
801
|
+
disabled,
|
|
802
|
+
onClick: (event) => {
|
|
803
|
+
event.stopPropagation();
|
|
804
|
+
onClick();
|
|
805
|
+
},
|
|
806
|
+
style: {
|
|
807
|
+
flex: "0",
|
|
808
|
+
appearance: "none",
|
|
809
|
+
background: "none",
|
|
810
|
+
color: theme.BASE_COLOR,
|
|
811
|
+
opacity: disabled ? 0.25 : 1,
|
|
812
|
+
border: "none",
|
|
813
|
+
fontSize: "12px",
|
|
814
|
+
whiteSpace: "nowrap",
|
|
815
|
+
display: "inline-flex",
|
|
816
|
+
alignItems: "center",
|
|
817
|
+
justifyContent: "center",
|
|
818
|
+
padding: "2px 0",
|
|
819
|
+
cursor: "pointer",
|
|
820
|
+
...style
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
children
|
|
824
|
+
);
|
|
825
|
+
}
|
|
669
826
|
|
|
670
827
|
// src/inspector/useStateInspector.tsx
|
|
671
828
|
function createPortalElement() {
|
|
@@ -677,11 +834,13 @@ function useStateInspector({
|
|
|
677
834
|
state,
|
|
678
835
|
connectionEvents,
|
|
679
836
|
connectedUsers,
|
|
837
|
+
tasks,
|
|
680
838
|
userId,
|
|
681
839
|
disabled = false,
|
|
682
840
|
colorScheme,
|
|
683
841
|
anchor,
|
|
684
|
-
|
|
842
|
+
multiplayerStateManager,
|
|
843
|
+
forceInit
|
|
685
844
|
}) {
|
|
686
845
|
const [root, setRoot] = import_react4.default.useState(null);
|
|
687
846
|
(0, import_react4.useLayoutEffect)(() => {
|
|
@@ -705,10 +864,12 @@ function useStateInspector({
|
|
|
705
864
|
state,
|
|
706
865
|
connectionEvents,
|
|
707
866
|
connectedUsers,
|
|
867
|
+
tasks,
|
|
708
868
|
userId,
|
|
709
869
|
colorScheme,
|
|
710
870
|
anchor,
|
|
711
|
-
|
|
871
|
+
forceInit,
|
|
872
|
+
multiplayerStateManager
|
|
712
873
|
}
|
|
713
874
|
)
|
|
714
875
|
);
|
|
@@ -719,8 +880,10 @@ function useStateInspector({
|
|
|
719
880
|
connectionEvents,
|
|
720
881
|
root,
|
|
721
882
|
state,
|
|
722
|
-
|
|
723
|
-
userId
|
|
883
|
+
multiplayerStateManager,
|
|
884
|
+
userId,
|
|
885
|
+
tasks,
|
|
886
|
+
forceInit
|
|
724
887
|
]);
|
|
725
888
|
}
|
|
726
889
|
|
|
@@ -792,58 +955,87 @@ function useSyncMultiplayerStateManager(multiplayerStateManager) {
|
|
|
792
955
|
}
|
|
793
956
|
var defaultStubSync = (0, import_state_manager.stubSync)();
|
|
794
957
|
function useMultiplayerState(initialState, options) {
|
|
795
|
-
const { sync = defaultStubSync, ...rest } = options;
|
|
958
|
+
const { sync = defaultStubSync, ...rest } = options ?? {};
|
|
796
959
|
const [multiplayerStateManager] = (0, import_react5.useState)(
|
|
797
960
|
() => new import_state_manager.MultiplayerStateManager(initialState, rest)
|
|
798
961
|
);
|
|
799
962
|
const syncRef = (0, import_react5.useRef)(sync);
|
|
800
963
|
const [connectionEvents, setConnectionEvents] = (0, import_react5.useState)();
|
|
801
964
|
const [connectedUsers, setConnectedUsers] = (0, import_react5.useState)([]);
|
|
965
|
+
const [tasks, setTasks] = (0, import_react5.useState)([]);
|
|
802
966
|
const [userId, setUserId] = (0, import_react5.useState)();
|
|
803
967
|
const extras = (0, import_react5.useMemo)(() => {
|
|
804
968
|
return {
|
|
969
|
+
tasks,
|
|
805
970
|
connectionEvents,
|
|
806
971
|
connectedUsers
|
|
972
|
+
// evaluate: async (code: string) => {
|
|
973
|
+
// const payload = await rpcManager.request({ type: "eval", code });
|
|
974
|
+
// if (payload.type !== "eval") {
|
|
975
|
+
// throw new Error(`Unexpected rpc response type: ${payload.type}`);
|
|
976
|
+
// }
|
|
977
|
+
// },
|
|
807
978
|
};
|
|
808
|
-
}, [connectionEvents, connectedUsers]);
|
|
809
|
-
const globalTrackEvents = useObservable(
|
|
810
|
-
const
|
|
979
|
+
}, [tasks, connectionEvents, connectedUsers]);
|
|
980
|
+
const globalTrackEvents = useObservable(shouldTrackEvents$);
|
|
981
|
+
const globalTrackTasks = useObservable(shouldTrackTasks$);
|
|
982
|
+
const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;
|
|
983
|
+
const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;
|
|
811
984
|
const trackEventsCallbackRef = (0, import_react5.useRef)();
|
|
812
985
|
const trackConnectedUsersCallbackRef = (0, import_react5.useRef)();
|
|
986
|
+
const trackTasksCallbackRef = (0, import_react5.useRef)();
|
|
813
987
|
(0, import_react5.useEffect)(() => {
|
|
814
|
-
trackEventsCallbackRef.current =
|
|
988
|
+
trackEventsCallbackRef.current = shouldTrackEvents ? (e) => setConnectionEvents((events) => {
|
|
815
989
|
const updated = events ? [...events, e] : [e];
|
|
816
990
|
return updated.length > 50 ? updated.slice(-50) : updated;
|
|
817
991
|
}) : void 0;
|
|
818
|
-
}, [
|
|
992
|
+
}, [shouldTrackEvents]);
|
|
819
993
|
(0, import_react5.useEffect)(() => {
|
|
820
994
|
trackConnectedUsersCallbackRef.current = (users, userId2) => {
|
|
821
995
|
setConnectedUsers(users);
|
|
822
996
|
setUserId(userId2);
|
|
823
997
|
};
|
|
824
|
-
});
|
|
998
|
+
}, []);
|
|
999
|
+
(0, import_react5.useEffect)(() => {
|
|
1000
|
+
trackTasksCallbackRef.current = shouldTrackTasks ? (tasks2) => {
|
|
1001
|
+
setTasks((old) => {
|
|
1002
|
+
const newIds = new Set(tasks2.map((t) => t.id));
|
|
1003
|
+
const unchanged = old.filter((t) => !newIds.has(t.id));
|
|
1004
|
+
return [...unchanged, ...tasks2];
|
|
1005
|
+
});
|
|
1006
|
+
} : void 0;
|
|
1007
|
+
}, [shouldTrackTasks]);
|
|
825
1008
|
(0, import_react5.useEffect)(() => {
|
|
826
1009
|
if (syncRef.current) {
|
|
827
1010
|
return syncRef.current({
|
|
828
1011
|
ms: multiplayerStateManager,
|
|
829
1012
|
onConnectionEvent: (e) => trackEventsCallbackRef.current?.(e),
|
|
830
|
-
onChangeConnectedUsers: (users, userId2) => trackConnectedUsersCallbackRef.current?.(users, userId2)
|
|
1013
|
+
onChangeConnectedUsers: (users, userId2) => trackConnectedUsersCallbackRef.current?.(users, userId2),
|
|
1014
|
+
onChangeTasks: (tasks2) => trackTasksCallbackRef.current?.(tasks2)
|
|
831
1015
|
});
|
|
832
1016
|
}
|
|
833
1017
|
}, [multiplayerStateManager]);
|
|
834
1018
|
const state = useSyncMultiplayerStateManager(multiplayerStateManager);
|
|
1019
|
+
const forceInit = (0, import_react5.useCallback)(() => {
|
|
1020
|
+
const state2 = typeof initialState === "function" ? initialState() : initialState;
|
|
1021
|
+
const schema = options?.schema;
|
|
1022
|
+
multiplayerStateManager.sm.clearHistory();
|
|
1023
|
+
multiplayerStateManager.sendInit({ force: true, state: state2, schema });
|
|
1024
|
+
}, [initialState, multiplayerStateManager, options?.schema]);
|
|
835
1025
|
useStateInspector({
|
|
836
|
-
|
|
1026
|
+
multiplayerStateManager,
|
|
837
1027
|
state,
|
|
838
1028
|
connectionEvents,
|
|
839
1029
|
connectedUsers,
|
|
1030
|
+
tasks,
|
|
840
1031
|
userId,
|
|
841
|
-
|
|
842
|
-
|
|
1032
|
+
forceInit,
|
|
1033
|
+
disabled: !options?.inspector,
|
|
1034
|
+
...typeof options?.inspector === "object" && options.inspector
|
|
843
1035
|
});
|
|
844
1036
|
return [
|
|
845
1037
|
state,
|
|
846
|
-
multiplayerStateManager.
|
|
1038
|
+
multiplayerStateManager.setState,
|
|
847
1039
|
multiplayerStateManager,
|
|
848
1040
|
extras
|
|
849
1041
|
];
|