@noya-app/noya-multiplayer-react 0.1.23 → 0.1.25
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 +10 -10
- package/CHANGELOG.md +17 -0
- package/dist/index.d.mts +18 -12
- package/dist/index.d.ts +18 -12
- package/dist/index.js +243 -115
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -75
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/components/ErrorOverlay.tsx +89 -0
- package/src/hooks.ts +82 -16
- package/src/index.ts +1 -0
- package/src/inspector/StateInspector.tsx +2 -6
- package/src/inspector/useStateInspector.tsx +1 -1
- package/src/noyaApp.ts +3 -3
package/dist/index.js
CHANGED
|
@@ -50,6 +50,7 @@ __export(src_exports, {
|
|
|
50
50
|
useManagedState: () => useManagedState,
|
|
51
51
|
useMultiplayerState: () => useMultiplayerState,
|
|
52
52
|
useNoyaAppState: () => useNoyaAppState,
|
|
53
|
+
useObservable: () => useObservable,
|
|
53
54
|
useSyncMultiplayerStateManager: () => useSyncMultiplayerStateManager,
|
|
54
55
|
useSyncStateManager: () => useSyncStateManager
|
|
55
56
|
});
|
|
@@ -250,7 +251,82 @@ var UserPointerIcon = (0, import_react2.memo)(function CursorIcon({
|
|
|
250
251
|
|
|
251
252
|
// src/hooks.ts
|
|
252
253
|
var import_state_manager = require("@noya-app/state-manager");
|
|
253
|
-
var
|
|
254
|
+
var import_react7 = require("react");
|
|
255
|
+
var import_client2 = require("react-dom/client");
|
|
256
|
+
|
|
257
|
+
// src/components/ErrorOverlay.tsx
|
|
258
|
+
var import_react3 = __toESM(require("react"));
|
|
259
|
+
function ErrorOverlay({
|
|
260
|
+
error
|
|
261
|
+
}) {
|
|
262
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
263
|
+
"div",
|
|
264
|
+
{
|
|
265
|
+
style: {
|
|
266
|
+
position: "fixed",
|
|
267
|
+
top: "20px",
|
|
268
|
+
left: "50%",
|
|
269
|
+
transform: "translateX(-50%)",
|
|
270
|
+
maxWidth: "80%",
|
|
271
|
+
width: "fit-content",
|
|
272
|
+
padding: "12px 20px",
|
|
273
|
+
background: "white",
|
|
274
|
+
color: "black",
|
|
275
|
+
zIndex: 1e4,
|
|
276
|
+
display: "flex",
|
|
277
|
+
flexDirection: "column",
|
|
278
|
+
justifyContent: "center",
|
|
279
|
+
borderRadius: "4px",
|
|
280
|
+
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
|
|
281
|
+
fontFamily: "'__Inter_6b0edc', '__Inter_Fallback_6b0edc', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
|
|
282
|
+
fontSize: "14px",
|
|
283
|
+
fontWeight: 400,
|
|
284
|
+
lineHeight: "19px"
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
error.reason === "schemaMigration" ? /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("p", null, "An updated version of Noya is available. Please reload the page to continue.")) : /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("p", null, "An error occurred:", " ", /* @__PURE__ */ import_react3.default.createElement(
|
|
288
|
+
"code",
|
|
289
|
+
{
|
|
290
|
+
style: {
|
|
291
|
+
background: "rgba(255, 0, 0, 0.1)",
|
|
292
|
+
color: "rgba(255, 0, 0, 0.5)",
|
|
293
|
+
padding: "2px 4px",
|
|
294
|
+
borderRadius: "4px"
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
error.reason
|
|
298
|
+
), ". Please reload the page to continue.", /* @__PURE__ */ import_react3.default.createElement("br", null), /* @__PURE__ */ import_react3.default.createElement("br", null), "If this happens repeatedly, please get in touch and the Noya team can help.")),
|
|
299
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
300
|
+
"div",
|
|
301
|
+
{
|
|
302
|
+
style: {
|
|
303
|
+
height: "1px",
|
|
304
|
+
background: "rgba(0, 0, 0, 0.1)",
|
|
305
|
+
margin: "12px -20px"
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
),
|
|
309
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
310
|
+
"button",
|
|
311
|
+
{
|
|
312
|
+
style: {
|
|
313
|
+
background: "black",
|
|
314
|
+
color: "white",
|
|
315
|
+
padding: "8px 16px",
|
|
316
|
+
borderRadius: "4px",
|
|
317
|
+
cursor: "pointer",
|
|
318
|
+
fontSize: "14px",
|
|
319
|
+
fontWeight: 700,
|
|
320
|
+
lineHeight: "19px"
|
|
321
|
+
},
|
|
322
|
+
onClick: () => {
|
|
323
|
+
window.location.reload();
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
"Reload"
|
|
327
|
+
)
|
|
328
|
+
);
|
|
329
|
+
}
|
|
254
330
|
|
|
255
331
|
// src/globals.ts
|
|
256
332
|
var import_observable = require("@noya-app/observable");
|
|
@@ -258,18 +334,18 @@ var shouldTrackEvents$ = new import_observable.Observable(false);
|
|
|
258
334
|
var shouldTrackTasks$ = new import_observable.Observable(false);
|
|
259
335
|
|
|
260
336
|
// src/inspector/useStateInspector.tsx
|
|
261
|
-
var
|
|
337
|
+
var import_react6 = __toESM(require("react"));
|
|
262
338
|
var import_client = require("react-dom/client");
|
|
263
339
|
|
|
264
340
|
// src/inspector/StateInspector.tsx
|
|
265
|
-
var
|
|
341
|
+
var import_react5 = __toESM(require("react"));
|
|
266
342
|
var import_react_inspector = require("react-inspector");
|
|
267
343
|
|
|
268
344
|
// src/inspector/useLocalStorageState.tsx
|
|
269
|
-
var
|
|
345
|
+
var import_react4 = __toESM(require("react"));
|
|
270
346
|
var localStorage = typeof window !== "undefined" ? window.localStorage : null;
|
|
271
347
|
function useLocalStorageState(key, defaultValue) {
|
|
272
|
-
const [state, setState] =
|
|
348
|
+
const [state, setState] = import_react4.default.useState(() => {
|
|
273
349
|
const value = localStorage?.getItem(key);
|
|
274
350
|
let result = defaultValue;
|
|
275
351
|
if (value) {
|
|
@@ -314,7 +390,7 @@ function ToggleButton({
|
|
|
314
390
|
theme,
|
|
315
391
|
anchor
|
|
316
392
|
}) {
|
|
317
|
-
return /* @__PURE__ */
|
|
393
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
318
394
|
"span",
|
|
319
395
|
{
|
|
320
396
|
role: "button",
|
|
@@ -335,7 +411,7 @@ function ToggleButton({
|
|
|
335
411
|
setShowInspector(!showInspector);
|
|
336
412
|
}
|
|
337
413
|
},
|
|
338
|
-
/* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react5.default.createElement(
|
|
339
415
|
"svg",
|
|
340
416
|
{
|
|
341
417
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -345,7 +421,7 @@ function ToggleButton({
|
|
|
345
421
|
stroke: "currentColor",
|
|
346
422
|
className: "size-6"
|
|
347
423
|
},
|
|
348
|
-
/* @__PURE__ */
|
|
424
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
349
425
|
"path",
|
|
350
426
|
{
|
|
351
427
|
strokeLinecap: "round",
|
|
@@ -353,7 +429,7 @@ function ToggleButton({
|
|
|
353
429
|
d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
354
430
|
}
|
|
355
431
|
)
|
|
356
|
-
) : /* @__PURE__ */
|
|
432
|
+
) : /* @__PURE__ */ import_react5.default.createElement(
|
|
357
433
|
"svg",
|
|
358
434
|
{
|
|
359
435
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -363,7 +439,7 @@ function ToggleButton({
|
|
|
363
439
|
stroke: "currentColor",
|
|
364
440
|
className: "size-6"
|
|
365
441
|
},
|
|
366
|
-
/* @__PURE__ */
|
|
442
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
367
443
|
"path",
|
|
368
444
|
{
|
|
369
445
|
strokeLinecap: "round",
|
|
@@ -386,7 +462,7 @@ function DisclosureSection({
|
|
|
386
462
|
}) {
|
|
387
463
|
const theme = colorScheme === "light" ? lightTheme : darkTheme;
|
|
388
464
|
const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
|
|
389
|
-
return /* @__PURE__ */
|
|
465
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
390
466
|
"div",
|
|
391
467
|
{
|
|
392
468
|
style: {
|
|
@@ -396,7 +472,7 @@ function DisclosureSection({
|
|
|
396
472
|
...style
|
|
397
473
|
}
|
|
398
474
|
},
|
|
399
|
-
/* @__PURE__ */
|
|
475
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
400
476
|
"div",
|
|
401
477
|
{
|
|
402
478
|
onClick: () => setOpen?.(!open),
|
|
@@ -410,7 +486,7 @@ function DisclosureSection({
|
|
|
410
486
|
...open && { borderBottom: `1px solid ${borderColor}` }
|
|
411
487
|
}
|
|
412
488
|
},
|
|
413
|
-
setOpen && /* @__PURE__ */
|
|
489
|
+
setOpen && /* @__PURE__ */ import_react5.default.createElement(
|
|
414
490
|
Arrow,
|
|
415
491
|
{
|
|
416
492
|
expanded: open,
|
|
@@ -421,7 +497,7 @@ function DisclosureSection({
|
|
|
421
497
|
}
|
|
422
498
|
}
|
|
423
499
|
),
|
|
424
|
-
/* @__PURE__ */
|
|
500
|
+
/* @__PURE__ */ import_react5.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
|
|
425
501
|
right
|
|
426
502
|
),
|
|
427
503
|
open && children
|
|
@@ -435,7 +511,7 @@ function InspectorRow({
|
|
|
435
511
|
variant
|
|
436
512
|
}) {
|
|
437
513
|
const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
438
|
-
return /* @__PURE__ */
|
|
514
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
439
515
|
"div",
|
|
440
516
|
{
|
|
441
517
|
style: {
|
|
@@ -453,7 +529,7 @@ function InspectorRow({
|
|
|
453
529
|
...style
|
|
454
530
|
}
|
|
455
531
|
},
|
|
456
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
457
533
|
"span",
|
|
458
534
|
{
|
|
459
535
|
style: {
|
|
@@ -468,7 +544,7 @@ function InspectorRow({
|
|
|
468
544
|
);
|
|
469
545
|
}
|
|
470
546
|
var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
|
|
471
|
-
var StateInspector = (0,
|
|
547
|
+
var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
472
548
|
state,
|
|
473
549
|
connectionEvents,
|
|
474
550
|
connectedUsers,
|
|
@@ -482,12 +558,12 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
482
558
|
forceInit,
|
|
483
559
|
...props
|
|
484
560
|
}) {
|
|
485
|
-
const [didMount, setDidMount] =
|
|
486
|
-
(0,
|
|
561
|
+
const [didMount, setDidMount] = import_react5.default.useState(false);
|
|
562
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
487
563
|
setDidMount(true);
|
|
488
564
|
}, []);
|
|
489
|
-
const eventsContainerRef =
|
|
490
|
-
const historyContainerRef =
|
|
565
|
+
const eventsContainerRef = import_react5.default.useRef(null);
|
|
566
|
+
const historyContainerRef = import_react5.default.useRef(null);
|
|
491
567
|
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
492
568
|
"noya-multiplayer-react-show-inspector",
|
|
493
569
|
true
|
|
@@ -516,25 +592,25 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
516
592
|
"noya-multiplayer-react-show-ephemeral",
|
|
517
593
|
false
|
|
518
594
|
);
|
|
519
|
-
(0,
|
|
595
|
+
(0, import_react5.useEffect)(() => {
|
|
520
596
|
shouldTrackEvents$.set(showEvents);
|
|
521
597
|
}, [showEvents]);
|
|
522
|
-
(0,
|
|
598
|
+
(0, import_react5.useEffect)(() => {
|
|
523
599
|
shouldTrackTasks$.set(showTasks);
|
|
524
600
|
}, [showTasks]);
|
|
525
|
-
(0,
|
|
601
|
+
(0, import_react5.useEffect)(() => {
|
|
526
602
|
if (eventsContainerRef.current) {
|
|
527
603
|
eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
|
|
528
604
|
}
|
|
529
605
|
}, [connectionEvents]);
|
|
530
606
|
const ephemeral = useEphemeralUserData(ephemeralUserData);
|
|
531
607
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
532
|
-
(0,
|
|
608
|
+
(0, import_react5.useEffect)(() => {
|
|
533
609
|
if (historyContainerRef.current) {
|
|
534
610
|
historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
|
|
535
611
|
}
|
|
536
612
|
}, [historySnapshot]);
|
|
537
|
-
(0,
|
|
613
|
+
(0, import_react5.useEffect)(() => {
|
|
538
614
|
if (!historyContainerRef.current)
|
|
539
615
|
return;
|
|
540
616
|
const historyEntry = historyContainerRef.current.querySelector(
|
|
@@ -571,7 +647,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
571
647
|
if (!didMount)
|
|
572
648
|
return null;
|
|
573
649
|
if (!showInspector) {
|
|
574
|
-
return /* @__PURE__ */
|
|
650
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
575
651
|
"div",
|
|
576
652
|
{
|
|
577
653
|
...props,
|
|
@@ -583,7 +659,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
583
659
|
},
|
|
584
660
|
onClick: () => setShowInspector(true)
|
|
585
661
|
},
|
|
586
|
-
/* @__PURE__ */
|
|
662
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
587
663
|
ToggleButton,
|
|
588
664
|
{
|
|
589
665
|
showInspector,
|
|
@@ -594,7 +670,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
594
670
|
)
|
|
595
671
|
);
|
|
596
672
|
}
|
|
597
|
-
return /* @__PURE__ */
|
|
673
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
598
674
|
"div",
|
|
599
675
|
{
|
|
600
676
|
...props,
|
|
@@ -603,7 +679,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
603
679
|
...props.style
|
|
604
680
|
}
|
|
605
681
|
},
|
|
606
|
-
/* @__PURE__ */
|
|
682
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
607
683
|
DisclosureSection,
|
|
608
684
|
{
|
|
609
685
|
isFirst: true,
|
|
@@ -615,7 +691,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
615
691
|
flex: "0 0 auto",
|
|
616
692
|
maxHeight: "200px"
|
|
617
693
|
},
|
|
618
|
-
right: /* @__PURE__ */
|
|
694
|
+
right: /* @__PURE__ */ import_react5.default.createElement(
|
|
619
695
|
ToggleButton,
|
|
620
696
|
{
|
|
621
697
|
showInspector,
|
|
@@ -625,14 +701,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
625
701
|
}
|
|
626
702
|
)
|
|
627
703
|
},
|
|
628
|
-
/* @__PURE__ */
|
|
704
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react5.default.createElement(
|
|
629
705
|
InspectorRow,
|
|
630
706
|
{
|
|
631
707
|
key: user.id,
|
|
632
708
|
colorScheme,
|
|
633
709
|
variant: user.id === userId ? "up" : void 0
|
|
634
710
|
},
|
|
635
|
-
user.image && /* @__PURE__ */
|
|
711
|
+
user.image && /* @__PURE__ */ import_react5.default.createElement(
|
|
636
712
|
"img",
|
|
637
713
|
{
|
|
638
714
|
src: user.image,
|
|
@@ -653,7 +729,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
653
729
|
" (",
|
|
654
730
|
ellipsis(user.id.toString(), 8, "middle"),
|
|
655
731
|
")"
|
|
656
|
-
)), !connectedUsers && /* @__PURE__ */
|
|
732
|
+
)), !connectedUsers && /* @__PURE__ */ import_react5.default.createElement(
|
|
657
733
|
"div",
|
|
658
734
|
{
|
|
659
735
|
style: {
|
|
@@ -664,17 +740,17 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
664
740
|
gap: "4px"
|
|
665
741
|
}
|
|
666
742
|
},
|
|
667
|
-
/* @__PURE__ */
|
|
743
|
+
/* @__PURE__ */ import_react5.default.createElement("span", null, "No connected users")
|
|
668
744
|
))
|
|
669
745
|
),
|
|
670
|
-
/* @__PURE__ */
|
|
746
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
671
747
|
DisclosureSection,
|
|
672
748
|
{
|
|
673
749
|
title: "Data",
|
|
674
750
|
colorScheme,
|
|
675
751
|
setOpen: setShowData,
|
|
676
752
|
open: showData,
|
|
677
|
-
right: /* @__PURE__ */
|
|
753
|
+
right: /* @__PURE__ */ import_react5.default.createElement(
|
|
678
754
|
"span",
|
|
679
755
|
{
|
|
680
756
|
style: {
|
|
@@ -682,7 +758,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
682
758
|
gap: "4px"
|
|
683
759
|
}
|
|
684
760
|
},
|
|
685
|
-
/* @__PURE__ */
|
|
761
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
686
762
|
SmallButton,
|
|
687
763
|
{
|
|
688
764
|
theme,
|
|
@@ -694,14 +770,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
694
770
|
)
|
|
695
771
|
)
|
|
696
772
|
},
|
|
697
|
-
/* @__PURE__ */
|
|
773
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
|
|
698
774
|
import_react_inspector.ObjectInspector,
|
|
699
775
|
{
|
|
700
776
|
name: multiplayerStateManager.schema ? "state" : void 0,
|
|
701
777
|
data: state,
|
|
702
778
|
theme
|
|
703
779
|
}
|
|
704
|
-
)), multiplayerStateManager.schema && /* @__PURE__ */
|
|
780
|
+
)), multiplayerStateManager.schema && /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
|
|
705
781
|
import_react_inspector.ObjectInspector,
|
|
706
782
|
{
|
|
707
783
|
name: "schema",
|
|
@@ -710,14 +786,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
710
786
|
}
|
|
711
787
|
)))
|
|
712
788
|
),
|
|
713
|
-
/* @__PURE__ */
|
|
789
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
714
790
|
DisclosureSection,
|
|
715
791
|
{
|
|
716
792
|
open: showHistory,
|
|
717
793
|
setOpen: setShowHistory,
|
|
718
794
|
title: "History",
|
|
719
795
|
colorScheme,
|
|
720
|
-
right: /* @__PURE__ */
|
|
796
|
+
right: /* @__PURE__ */ import_react5.default.createElement(
|
|
721
797
|
"span",
|
|
722
798
|
{
|
|
723
799
|
style: {
|
|
@@ -725,7 +801,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
725
801
|
gap: "4px"
|
|
726
802
|
}
|
|
727
803
|
},
|
|
728
|
-
/* @__PURE__ */
|
|
804
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
729
805
|
SmallButton,
|
|
730
806
|
{
|
|
731
807
|
disabled: !historySnapshot.canUndo,
|
|
@@ -734,7 +810,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
734
810
|
multiplayerStateManager.undo();
|
|
735
811
|
}
|
|
736
812
|
},
|
|
737
|
-
/* @__PURE__ */
|
|
813
|
+
/* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
|
|
738
814
|
"svg",
|
|
739
815
|
{
|
|
740
816
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -742,7 +818,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
742
818
|
height: "1em",
|
|
743
819
|
viewBox: "0 0 20 20"
|
|
744
820
|
},
|
|
745
|
-
/* @__PURE__ */
|
|
821
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
746
822
|
"path",
|
|
747
823
|
{
|
|
748
824
|
fill: "currentColor",
|
|
@@ -751,7 +827,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
751
827
|
)
|
|
752
828
|
))
|
|
753
829
|
),
|
|
754
|
-
/* @__PURE__ */
|
|
830
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
755
831
|
SmallButton,
|
|
756
832
|
{
|
|
757
833
|
disabled: !historySnapshot.canRedo,
|
|
@@ -760,7 +836,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
760
836
|
multiplayerStateManager.redo();
|
|
761
837
|
}
|
|
762
838
|
},
|
|
763
|
-
/* @__PURE__ */
|
|
839
|
+
/* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
|
|
764
840
|
"svg",
|
|
765
841
|
{
|
|
766
842
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -768,7 +844,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
768
844
|
height: "1em",
|
|
769
845
|
viewBox: "0 0 20 20"
|
|
770
846
|
},
|
|
771
|
-
/* @__PURE__ */
|
|
847
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
772
848
|
"path",
|
|
773
849
|
{
|
|
774
850
|
fill: "currentColor",
|
|
@@ -779,7 +855,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
779
855
|
)
|
|
780
856
|
)
|
|
781
857
|
},
|
|
782
|
-
/* @__PURE__ */
|
|
858
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(
|
|
783
859
|
"div",
|
|
784
860
|
{
|
|
785
861
|
id: `${HISTORY_ELEMENT_PREFIX}0`,
|
|
@@ -793,7 +869,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
793
869
|
background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
|
|
794
870
|
}
|
|
795
871
|
},
|
|
796
|
-
/* @__PURE__ */
|
|
872
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
797
873
|
"span",
|
|
798
874
|
{
|
|
799
875
|
style: {
|
|
@@ -805,7 +881,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
805
881
|
},
|
|
806
882
|
"Initial state"
|
|
807
883
|
)
|
|
808
|
-
), historySnapshot.history.map((entry, index) => /* @__PURE__ */
|
|
884
|
+
), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react5.default.createElement(
|
|
809
885
|
"div",
|
|
810
886
|
{
|
|
811
887
|
id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
|
|
@@ -816,7 +892,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
816
892
|
background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
|
|
817
893
|
}
|
|
818
894
|
},
|
|
819
|
-
"name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */
|
|
895
|
+
"name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */ import_react5.default.createElement(
|
|
820
896
|
"pre",
|
|
821
897
|
{
|
|
822
898
|
style: {
|
|
@@ -827,7 +903,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
827
903
|
},
|
|
828
904
|
entry.metadata.name
|
|
829
905
|
),
|
|
830
|
-
entry.redoPatches?.map((patch, j) => /* @__PURE__ */
|
|
906
|
+
entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react5.default.createElement(
|
|
831
907
|
"pre",
|
|
832
908
|
{
|
|
833
909
|
key: j,
|
|
@@ -837,14 +913,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
837
913
|
flexWrap: "wrap"
|
|
838
914
|
}
|
|
839
915
|
},
|
|
840
|
-
patch.op === "add" && /* @__PURE__ */
|
|
841
|
-
patch.op === "replace" && /* @__PURE__ */
|
|
842
|
-
patch.op === "remove" && /* @__PURE__ */
|
|
843
|
-
patch.op === "move" && /* @__PURE__ */
|
|
916
|
+
patch.op === "add" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
|
|
917
|
+
patch.op === "replace" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
|
|
918
|
+
patch.op === "remove" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
|
|
919
|
+
patch.op === "move" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
|
|
844
920
|
))
|
|
845
921
|
)))
|
|
846
922
|
),
|
|
847
|
-
/* @__PURE__ */
|
|
923
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
848
924
|
DisclosureSection,
|
|
849
925
|
{
|
|
850
926
|
title: "Tasks",
|
|
@@ -852,7 +928,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
852
928
|
open: showTasks,
|
|
853
929
|
setOpen: setShowTasks
|
|
854
930
|
},
|
|
855
|
-
/* @__PURE__ */
|
|
931
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react5.default.createElement(
|
|
856
932
|
InspectorRow,
|
|
857
933
|
{
|
|
858
934
|
key: task.id,
|
|
@@ -861,7 +937,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
861
937
|
backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
|
|
862
938
|
}
|
|
863
939
|
},
|
|
864
|
-
/* @__PURE__ */
|
|
940
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
865
941
|
import_react_inspector.ObjectInspector,
|
|
866
942
|
{
|
|
867
943
|
name: task.name,
|
|
@@ -871,7 +947,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
871
947
|
)
|
|
872
948
|
)))
|
|
873
949
|
),
|
|
874
|
-
/* @__PURE__ */
|
|
950
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
875
951
|
DisclosureSection,
|
|
876
952
|
{
|
|
877
953
|
open: showEphemeral,
|
|
@@ -879,7 +955,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
879
955
|
title: "Ephemeral User Data",
|
|
880
956
|
colorScheme
|
|
881
957
|
},
|
|
882
|
-
/* @__PURE__ */
|
|
958
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { key, colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
|
|
883
959
|
import_react_inspector.ObjectInspector,
|
|
884
960
|
{
|
|
885
961
|
name: key,
|
|
@@ -889,7 +965,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
889
965
|
}
|
|
890
966
|
))))
|
|
891
967
|
),
|
|
892
|
-
/* @__PURE__ */
|
|
968
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
893
969
|
DisclosureSection,
|
|
894
970
|
{
|
|
895
971
|
open: showEvents,
|
|
@@ -897,8 +973,8 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
897
973
|
title: "Events",
|
|
898
974
|
colorScheme
|
|
899
975
|
},
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
(event, index) => event.type === "stateChange" ? /* @__PURE__ */
|
|
976
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
|
|
977
|
+
(event, index) => event.type === "stateChange" ? /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ import_react5.default.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ import_react5.default.createElement(
|
|
902
978
|
InspectorRow,
|
|
903
979
|
{
|
|
904
980
|
key: index,
|
|
@@ -908,10 +984,10 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
908
984
|
padding: "0px 12px 1px"
|
|
909
985
|
}
|
|
910
986
|
},
|
|
911
|
-
/* @__PURE__ */
|
|
987
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
912
988
|
import_react_inspector.ObjectInspector,
|
|
913
989
|
{
|
|
914
|
-
data: event.message,
|
|
990
|
+
data: event.type === "error" ? event.error : event.message,
|
|
915
991
|
theme,
|
|
916
992
|
nodeRenderer: ({
|
|
917
993
|
depth,
|
|
@@ -921,7 +997,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
921
997
|
expanded
|
|
922
998
|
}) => {
|
|
923
999
|
const direction = event.type === "send" ? "up" : "down";
|
|
924
|
-
return depth === 0 ? /* @__PURE__ */
|
|
1000
|
+
return depth === 0 ? /* @__PURE__ */ import_react5.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react5.default.createElement(
|
|
925
1001
|
import_react_inspector.ObjectLabel,
|
|
926
1002
|
{
|
|
927
1003
|
direction,
|
|
@@ -934,7 +1010,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
934
1010
|
}
|
|
935
1011
|
)
|
|
936
1012
|
)
|
|
937
|
-
), !connectionEvents && /* @__PURE__ */
|
|
1013
|
+
), !connectionEvents && /* @__PURE__ */ import_react5.default.createElement(
|
|
938
1014
|
"div",
|
|
939
1015
|
{
|
|
940
1016
|
style: {
|
|
@@ -945,18 +1021,18 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
|
945
1021
|
gap: "4px"
|
|
946
1022
|
}
|
|
947
1023
|
},
|
|
948
|
-
/* @__PURE__ */
|
|
1024
|
+
/* @__PURE__ */ import_react5.default.createElement("span", null, "No recorded events")
|
|
949
1025
|
))
|
|
950
1026
|
)
|
|
951
1027
|
);
|
|
952
1028
|
});
|
|
953
1029
|
var ObjectRootLabel = ({ name, data, direction }) => {
|
|
954
1030
|
if (typeof name === "string") {
|
|
955
|
-
return /* @__PURE__ */
|
|
1031
|
+
return /* @__PURE__ */ import_react5.default.createElement("span", null, /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectName, { name }), /* @__PURE__ */ import_react5.default.createElement("span", null, ": "), /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data }));
|
|
956
1032
|
}
|
|
957
1033
|
if (direction === "up" || direction === "down") {
|
|
958
1034
|
const arrow = direction === "up" ? "\u2191" : "\u2193";
|
|
959
|
-
return /* @__PURE__ */
|
|
1035
|
+
return /* @__PURE__ */ import_react5.default.createElement("span", null, /* @__PURE__ */ import_react5.default.createElement(
|
|
960
1036
|
"span",
|
|
961
1037
|
{
|
|
962
1038
|
style: {
|
|
@@ -973,9 +1049,9 @@ var ObjectRootLabel = ({ name, data, direction }) => {
|
|
|
973
1049
|
}
|
|
974
1050
|
},
|
|
975
1051
|
arrow
|
|
976
|
-
), /* @__PURE__ */
|
|
1052
|
+
), /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data }));
|
|
977
1053
|
} else {
|
|
978
|
-
return /* @__PURE__ */
|
|
1054
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data });
|
|
979
1055
|
}
|
|
980
1056
|
};
|
|
981
1057
|
function Arrow({
|
|
@@ -983,7 +1059,7 @@ function Arrow({
|
|
|
983
1059
|
onClick,
|
|
984
1060
|
style
|
|
985
1061
|
}) {
|
|
986
|
-
return /* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
987
1063
|
"span",
|
|
988
1064
|
{
|
|
989
1065
|
role: "button",
|
|
@@ -1026,7 +1102,7 @@ function SmallButton({
|
|
|
1026
1102
|
theme,
|
|
1027
1103
|
disabled
|
|
1028
1104
|
}) {
|
|
1029
|
-
return /* @__PURE__ */
|
|
1105
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
1030
1106
|
"button",
|
|
1031
1107
|
{
|
|
1032
1108
|
type: "button",
|
|
@@ -1075,8 +1151,8 @@ function useStateInspector({
|
|
|
1075
1151
|
ephemeralUserData,
|
|
1076
1152
|
forceInit
|
|
1077
1153
|
}) {
|
|
1078
|
-
const [root, setRoot] =
|
|
1079
|
-
(0,
|
|
1154
|
+
const [root, setRoot] = import_react6.default.useState(null);
|
|
1155
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
1080
1156
|
if (disabled)
|
|
1081
1157
|
return;
|
|
1082
1158
|
const portalElement = createPortalElement();
|
|
@@ -1087,11 +1163,11 @@ function useStateInspector({
|
|
|
1087
1163
|
document.body.removeChild(portalElement);
|
|
1088
1164
|
};
|
|
1089
1165
|
}, [disabled]);
|
|
1090
|
-
(0,
|
|
1166
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
1091
1167
|
if (!root)
|
|
1092
1168
|
return;
|
|
1093
1169
|
root.render(
|
|
1094
|
-
/* @__PURE__ */
|
|
1170
|
+
/* @__PURE__ */ import_react6.default.createElement(
|
|
1095
1171
|
StateInspector,
|
|
1096
1172
|
{
|
|
1097
1173
|
state,
|
|
@@ -1124,27 +1200,27 @@ function useStateInspector({
|
|
|
1124
1200
|
|
|
1125
1201
|
// src/hooks.ts
|
|
1126
1202
|
function useSyncStateManager(stateManager, path) {
|
|
1127
|
-
const getSnapshot = (0,
|
|
1203
|
+
const getSnapshot = (0, import_react7.useCallback)(
|
|
1128
1204
|
() => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
|
|
1129
1205
|
[stateManager, path]
|
|
1130
1206
|
);
|
|
1131
|
-
return (0,
|
|
1207
|
+
return (0, import_react7.useSyncExternalStore)(
|
|
1132
1208
|
stateManager.addListener,
|
|
1133
1209
|
getSnapshot,
|
|
1134
1210
|
getSnapshot
|
|
1135
1211
|
);
|
|
1136
1212
|
}
|
|
1137
1213
|
function useManagedState(createInitialState, options) {
|
|
1138
|
-
const [stateManager] = (0,
|
|
1214
|
+
const [stateManager] = (0, import_react7.useState)(
|
|
1139
1215
|
() => new import_state_manager.StateManager(createInitialState(), options)
|
|
1140
1216
|
);
|
|
1141
1217
|
const state = useSyncStateManager(stateManager);
|
|
1142
|
-
const setState = (0,
|
|
1218
|
+
const setState = (0, import_react7.useCallback)(
|
|
1143
1219
|
(...args) => {
|
|
1144
1220
|
const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
|
|
1145
1221
|
if (metadata === void 0) {
|
|
1146
1222
|
const performActionNoMetadata = stateManager.performAction;
|
|
1147
|
-
if (
|
|
1223
|
+
if (action instanceof Function) {
|
|
1148
1224
|
performActionNoMetadata({
|
|
1149
1225
|
run: action,
|
|
1150
1226
|
undo: () => state
|
|
@@ -1157,7 +1233,7 @@ function useManagedState(createInitialState, options) {
|
|
|
1157
1233
|
}
|
|
1158
1234
|
} else {
|
|
1159
1235
|
const performActionWithMetadata = stateManager.performAction;
|
|
1160
|
-
if (
|
|
1236
|
+
if (action instanceof Function) {
|
|
1161
1237
|
performActionWithMetadata(metadata, {
|
|
1162
1238
|
run: action,
|
|
1163
1239
|
undo: () => state
|
|
@@ -1175,22 +1251,54 @@ function useManagedState(createInitialState, options) {
|
|
|
1175
1251
|
return [state, setState, stateManager];
|
|
1176
1252
|
}
|
|
1177
1253
|
function useManagedHistory(stateManager) {
|
|
1178
|
-
return (0,
|
|
1254
|
+
return (0, import_react7.useSyncExternalStore)(
|
|
1179
1255
|
stateManager.historyEmittor.addListener,
|
|
1180
1256
|
stateManager.getHistorySnapshot,
|
|
1181
1257
|
stateManager.getHistorySnapshot
|
|
1182
1258
|
);
|
|
1183
1259
|
}
|
|
1184
1260
|
function useSyncMultiplayerStateManager(multiplayerStateManager) {
|
|
1185
|
-
return (0,
|
|
1261
|
+
return (0, import_react7.useSyncExternalStore)(
|
|
1186
1262
|
multiplayerStateManager.addListener,
|
|
1187
1263
|
multiplayerStateManager.getOptimisticState,
|
|
1188
1264
|
multiplayerStateManager.getOptimisticState
|
|
1189
1265
|
);
|
|
1190
1266
|
}
|
|
1191
|
-
function
|
|
1192
|
-
|
|
1193
|
-
|
|
1267
|
+
function throttle(fn, ms) {
|
|
1268
|
+
let lastCall = 0;
|
|
1269
|
+
let timeoutId = null;
|
|
1270
|
+
return (...args) => {
|
|
1271
|
+
const now = Date.now();
|
|
1272
|
+
if (now - lastCall < ms) {
|
|
1273
|
+
if (timeoutId)
|
|
1274
|
+
clearTimeout(timeoutId);
|
|
1275
|
+
timeoutId = setTimeout(
|
|
1276
|
+
() => {
|
|
1277
|
+
lastCall = now;
|
|
1278
|
+
fn(...args);
|
|
1279
|
+
},
|
|
1280
|
+
ms - (now - lastCall)
|
|
1281
|
+
);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
lastCall = now;
|
|
1285
|
+
return fn(...args);
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
function useEphemeralUserData(ephemeralUserData, options) {
|
|
1289
|
+
const throttledAddListener = (0, import_react7.useMemo)(() => {
|
|
1290
|
+
const throttleMs = options?.throttle ?? 0;
|
|
1291
|
+
if (throttleMs > 0) {
|
|
1292
|
+
const addListener = (fn) => {
|
|
1293
|
+
const throttledFn = throttle(fn, throttleMs);
|
|
1294
|
+
return ephemeralUserData.addListener(throttledFn);
|
|
1295
|
+
};
|
|
1296
|
+
return addListener;
|
|
1297
|
+
}
|
|
1298
|
+
return ephemeralUserData.addListener;
|
|
1299
|
+
}, [ephemeralUserData, options?.throttle]);
|
|
1300
|
+
return (0, import_react7.useSyncExternalStore)(
|
|
1301
|
+
throttledAddListener,
|
|
1194
1302
|
ephemeralUserData.getSnapshot,
|
|
1195
1303
|
ephemeralUserData.getSnapshot
|
|
1196
1304
|
);
|
|
@@ -1198,18 +1306,18 @@ function useEphemeralUserData(ephemeralUserData) {
|
|
|
1198
1306
|
var defaultStubSync = (0, import_state_manager.stubSync)();
|
|
1199
1307
|
function useMultiplayerState(initialState, options) {
|
|
1200
1308
|
const { sync = defaultStubSync, ...rest } = options ?? {};
|
|
1201
|
-
const [multiplayerStateManager] = (0,
|
|
1309
|
+
const [multiplayerStateManager] = (0, import_react7.useState)(
|
|
1202
1310
|
() => new import_state_manager.MultiplayerStateManager(initialState, rest)
|
|
1203
1311
|
);
|
|
1204
|
-
const syncRef = (0,
|
|
1205
|
-
const [connectionEvents, setConnectionEvents] = (0,
|
|
1206
|
-
const [connectedUsers, setConnectedUsers] = (0,
|
|
1207
|
-
const [ephemeralUserData] = (0,
|
|
1312
|
+
const syncRef = (0, import_react7.useRef)(sync);
|
|
1313
|
+
const [connectionEvents, setConnectionEvents] = (0, import_react7.useState)();
|
|
1314
|
+
const [connectedUsers, setConnectedUsers] = (0, import_react7.useState)([]);
|
|
1315
|
+
const [ephemeralUserData] = (0, import_react7.useState)(
|
|
1208
1316
|
() => new import_state_manager.EphemeralUserData()
|
|
1209
1317
|
);
|
|
1210
|
-
const [tasks, setTasks] = (0,
|
|
1211
|
-
const [userId, setUserId] = (0,
|
|
1212
|
-
const extras = (0,
|
|
1318
|
+
const [tasks, setTasks] = (0, import_react7.useState)([]);
|
|
1319
|
+
const [userId, setUserId] = (0, import_react7.useState)();
|
|
1320
|
+
const extras = (0, import_react7.useMemo)(() => {
|
|
1213
1321
|
return {
|
|
1214
1322
|
tasks,
|
|
1215
1323
|
userId,
|
|
@@ -1236,22 +1344,22 @@ function useMultiplayerState(initialState, options) {
|
|
|
1236
1344
|
const globalTrackTasks = useObservable(shouldTrackTasks$);
|
|
1237
1345
|
const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;
|
|
1238
1346
|
const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;
|
|
1239
|
-
const trackEventsCallbackRef = (0,
|
|
1240
|
-
const trackConnectedUsersCallbackRef = (0,
|
|
1241
|
-
const trackTasksCallbackRef = (0,
|
|
1242
|
-
(0,
|
|
1347
|
+
const trackEventsCallbackRef = (0, import_react7.useRef)();
|
|
1348
|
+
const trackConnectedUsersCallbackRef = (0, import_react7.useRef)();
|
|
1349
|
+
const trackTasksCallbackRef = (0, import_react7.useRef)();
|
|
1350
|
+
(0, import_react7.useEffect)(() => {
|
|
1243
1351
|
trackEventsCallbackRef.current = shouldTrackEvents ? (e) => setConnectionEvents((events) => {
|
|
1244
1352
|
const updated = events ? [...events, e] : [e];
|
|
1245
1353
|
return updated.length > 50 ? updated.slice(-50) : updated;
|
|
1246
1354
|
}) : void 0;
|
|
1247
1355
|
}, [shouldTrackEvents]);
|
|
1248
|
-
(0,
|
|
1356
|
+
(0, import_react7.useEffect)(() => {
|
|
1249
1357
|
trackConnectedUsersCallbackRef.current = (users, userId2) => {
|
|
1250
1358
|
setConnectedUsers(users);
|
|
1251
1359
|
setUserId(userId2);
|
|
1252
1360
|
};
|
|
1253
1361
|
}, []);
|
|
1254
|
-
(0,
|
|
1362
|
+
(0, import_react7.useEffect)(() => {
|
|
1255
1363
|
trackTasksCallbackRef.current = shouldTrackTasks ? (tasks2) => {
|
|
1256
1364
|
setTasks((old) => {
|
|
1257
1365
|
const newIds = new Set(tasks2.map((t) => t.id));
|
|
@@ -1260,7 +1368,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1260
1368
|
});
|
|
1261
1369
|
} : void 0;
|
|
1262
1370
|
}, [shouldTrackTasks]);
|
|
1263
|
-
(0,
|
|
1371
|
+
(0, import_react7.useEffect)(() => {
|
|
1264
1372
|
if (syncRef.current) {
|
|
1265
1373
|
return syncRef.current({
|
|
1266
1374
|
ms: multiplayerStateManager,
|
|
@@ -1272,12 +1380,31 @@ function useMultiplayerState(initialState, options) {
|
|
|
1272
1380
|
}
|
|
1273
1381
|
}, [ephemeralUserData, multiplayerStateManager]);
|
|
1274
1382
|
const state = useSyncMultiplayerStateManager(multiplayerStateManager);
|
|
1275
|
-
const forceInit = (0,
|
|
1276
|
-
const state2 =
|
|
1383
|
+
const forceInit = (0, import_react7.useCallback)(() => {
|
|
1384
|
+
const state2 = initialState instanceof Function ? initialState() : initialState;
|
|
1277
1385
|
const schema = options?.schema;
|
|
1278
1386
|
multiplayerStateManager.sm.clearHistory();
|
|
1279
1387
|
multiplayerStateManager.sendInit({ force: true, state: state2, schema });
|
|
1280
1388
|
}, [initialState, multiplayerStateManager, options?.schema]);
|
|
1389
|
+
const [unrecoverableError, setUnrecoverableError] = (0, import_react7.useState)();
|
|
1390
|
+
(0, import_react7.useEffect)(() => {
|
|
1391
|
+
return multiplayerStateManager.errorEmitter.addListener((error) => {
|
|
1392
|
+
setUnrecoverableError(error);
|
|
1393
|
+
});
|
|
1394
|
+
}, [multiplayerStateManager]);
|
|
1395
|
+
(0, import_react7.useEffect)(() => {
|
|
1396
|
+
if (!unrecoverableError)
|
|
1397
|
+
return;
|
|
1398
|
+
const el = document.createElement("div");
|
|
1399
|
+
el.id = "noya-multiplayer-react-error-overlay";
|
|
1400
|
+
document.body.appendChild(el);
|
|
1401
|
+
const root = (0, import_client2.createRoot)(el);
|
|
1402
|
+
root.render((0, import_react7.createElement)(ErrorOverlay, { error: unrecoverableError }));
|
|
1403
|
+
return () => {
|
|
1404
|
+
root.unmount();
|
|
1405
|
+
el.remove();
|
|
1406
|
+
};
|
|
1407
|
+
});
|
|
1281
1408
|
useStateInspector({
|
|
1282
1409
|
ephemeralUserData,
|
|
1283
1410
|
multiplayerStateManager,
|
|
@@ -1295,7 +1422,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1295
1422
|
|
|
1296
1423
|
// src/noyaApp.ts
|
|
1297
1424
|
var import_state_manager2 = require("@noya-app/state-manager");
|
|
1298
|
-
var
|
|
1425
|
+
var import_react8 = require("react");
|
|
1299
1426
|
function createDefaultAppData(initialState) {
|
|
1300
1427
|
return {
|
|
1301
1428
|
theme: "light",
|
|
@@ -1322,7 +1449,7 @@ function getAppData(initialState) {
|
|
|
1322
1449
|
}
|
|
1323
1450
|
}
|
|
1324
1451
|
function useAppData(initialState, { schema } = {}) {
|
|
1325
|
-
const appData = (0,
|
|
1452
|
+
const appData = (0, import_react8.useMemo)(() => {
|
|
1326
1453
|
return getAppData(
|
|
1327
1454
|
schema ? (0, import_state_manager2.createValue)(schema, initialState) : initialState
|
|
1328
1455
|
);
|
|
@@ -1330,7 +1457,7 @@ function useAppData(initialState, { schema } = {}) {
|
|
|
1330
1457
|
return appData;
|
|
1331
1458
|
}
|
|
1332
1459
|
function useBroadcastConnectedUsers(connectedUsers) {
|
|
1333
|
-
(0,
|
|
1460
|
+
(0, import_react8.useEffect)(() => {
|
|
1334
1461
|
if (!isEmbeddedApp())
|
|
1335
1462
|
return;
|
|
1336
1463
|
const message = {
|
|
@@ -1341,7 +1468,7 @@ function useBroadcastConnectedUsers(connectedUsers) {
|
|
|
1341
1468
|
}, [connectedUsers]);
|
|
1342
1469
|
}
|
|
1343
1470
|
function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
|
|
1344
|
-
(0,
|
|
1471
|
+
(0, import_react8.useEffect)(() => {
|
|
1345
1472
|
if (!isEmbeddedApp())
|
|
1346
1473
|
return;
|
|
1347
1474
|
const message = {
|
|
@@ -1364,7 +1491,7 @@ function isEmbeddedApp() {
|
|
|
1364
1491
|
return window.self !== window.top;
|
|
1365
1492
|
}
|
|
1366
1493
|
function useNoyaAppState(initialState, options) {
|
|
1367
|
-
const [state] = (0,
|
|
1494
|
+
const [state] = (0, import_react8.useState)(initialState);
|
|
1368
1495
|
const {
|
|
1369
1496
|
multiplayerUrl,
|
|
1370
1497
|
inspector,
|
|
@@ -1374,7 +1501,7 @@ function useNoyaAppState(initialState, options) {
|
|
|
1374
1501
|
} = useAppData(state, {
|
|
1375
1502
|
schema: options.schema
|
|
1376
1503
|
});
|
|
1377
|
-
const sync = (0,
|
|
1504
|
+
const sync = (0, import_react8.useMemo)(() => {
|
|
1378
1505
|
return multiplayerUrl ? (0, import_state_manager2.webSocketSync)(multiplayerUrl) : (0, import_state_manager2.localStorageSync)({ key: options.localStorageKey || "noya-app" });
|
|
1379
1506
|
}, [multiplayerUrl, options.localStorageKey]);
|
|
1380
1507
|
const result = useMultiplayerState(noyaAppInitialState, {
|
|
@@ -1384,7 +1511,7 @@ function useNoyaAppState(initialState, options) {
|
|
|
1384
1511
|
});
|
|
1385
1512
|
const [, , extras] = result;
|
|
1386
1513
|
useBroadcastConnectedUsers(extras.connectedUsers);
|
|
1387
|
-
const mergedExtras = (0,
|
|
1514
|
+
const mergedExtras = (0, import_react8.useMemo)(() => {
|
|
1388
1515
|
return { ...extras, theme, viewType };
|
|
1389
1516
|
}, [extras, theme, viewType]);
|
|
1390
1517
|
return [result[0], result[1], mergedExtras];
|
|
@@ -1410,6 +1537,7 @@ function useNoyaAppState(initialState, options) {
|
|
|
1410
1537
|
useManagedState,
|
|
1411
1538
|
useMultiplayerState,
|
|
1412
1539
|
useNoyaAppState,
|
|
1540
|
+
useObservable,
|
|
1413
1541
|
useSyncMultiplayerStateManager,
|
|
1414
1542
|
useSyncStateManager,
|
|
1415
1543
|
...require("@noya-app/state-manager")
|