@noya-app/noya-multiplayer-react 0.1.22 → 0.1.23
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 +9 -0
- package/dist/index.d.mts +59 -46
- package/dist/index.d.ts +59 -46
- package/dist/index.js +229 -188
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +138 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/hooks.ts +26 -23
- package/src/index.ts +1 -1
- package/src/inspector/StateInspector.tsx +25 -5
- package/src/{embedded.ts → noyaApp.ts} +58 -7
package/dist/index.js
CHANGED
|
@@ -42,13 +42,14 @@ __export(src_exports, {
|
|
|
42
42
|
getAvatarInitials: () => getAvatarInitials,
|
|
43
43
|
getAvatarStyle: () => getAvatarStyle,
|
|
44
44
|
isEmbeddedApp: () => isEmbeddedApp,
|
|
45
|
+
useAppData: () => useAppData,
|
|
45
46
|
useBroadcastConnectedUsers: () => useBroadcastConnectedUsers,
|
|
46
47
|
useBroadcastMenuItems: () => useBroadcastMenuItems,
|
|
47
48
|
useEphemeralUserData: () => useEphemeralUserData,
|
|
48
49
|
useManagedHistory: () => useManagedHistory,
|
|
49
50
|
useManagedState: () => useManagedState,
|
|
50
51
|
useMultiplayerState: () => useMultiplayerState,
|
|
51
|
-
|
|
52
|
+
useNoyaAppState: () => useNoyaAppState,
|
|
52
53
|
useSyncMultiplayerStateManager: () => useSyncMultiplayerStateManager,
|
|
53
54
|
useSyncStateManager: () => useSyncStateManager
|
|
54
55
|
});
|
|
@@ -247,80 +248,9 @@ var UserPointerIcon = (0, import_react2.memo)(function CursorIcon({
|
|
|
247
248
|
);
|
|
248
249
|
});
|
|
249
250
|
|
|
250
|
-
// src/embedded.ts
|
|
251
|
-
var import_state_manager = require("@noya-app/state-manager");
|
|
252
|
-
var import_react3 = require("react");
|
|
253
|
-
function createDefaultAppData(initialState) {
|
|
254
|
-
return {
|
|
255
|
-
theme: "light",
|
|
256
|
-
viewType: "editable",
|
|
257
|
-
initialState,
|
|
258
|
-
inspector: false
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function getAppData(initialState) {
|
|
262
|
-
try {
|
|
263
|
-
const urlHash = (window.location.hash || "").replace(/^#/, "");
|
|
264
|
-
const params = new URLSearchParams(urlHash);
|
|
265
|
-
const data = params.get("data");
|
|
266
|
-
if (!data) {
|
|
267
|
-
return initialState ? createDefaultAppData(initialState) : void 0;
|
|
268
|
-
}
|
|
269
|
-
const parsed = JSON.parse(data);
|
|
270
|
-
if (!parsed.initialState) {
|
|
271
|
-
parsed.initialState = initialState;
|
|
272
|
-
}
|
|
273
|
-
return parsed;
|
|
274
|
-
} catch (e) {
|
|
275
|
-
return initialState ? createDefaultAppData(initialState) : void 0;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
function useNoyaApp(initialState, { schema } = {}) {
|
|
279
|
-
const appData = (0, import_react3.useMemo)(() => {
|
|
280
|
-
return getAppData(
|
|
281
|
-
schema ? (0, import_state_manager.createValue)(schema, initialState) : initialState
|
|
282
|
-
);
|
|
283
|
-
}, [initialState, schema]);
|
|
284
|
-
return appData;
|
|
285
|
-
}
|
|
286
|
-
function useBroadcastConnectedUsers(connectedUsers) {
|
|
287
|
-
(0, import_react3.useEffect)(() => {
|
|
288
|
-
if (!isEmbeddedApp())
|
|
289
|
-
return;
|
|
290
|
-
const message = {
|
|
291
|
-
type: "multiplayer.setUsers",
|
|
292
|
-
payload: { users: connectedUsers }
|
|
293
|
-
};
|
|
294
|
-
parent?.postMessage(message, "*");
|
|
295
|
-
}, [connectedUsers]);
|
|
296
|
-
}
|
|
297
|
-
function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
|
|
298
|
-
(0, import_react3.useEffect)(() => {
|
|
299
|
-
if (!isEmbeddedApp())
|
|
300
|
-
return;
|
|
301
|
-
const message = {
|
|
302
|
-
type: "application.setMenuItems",
|
|
303
|
-
payload: { menuItems }
|
|
304
|
-
};
|
|
305
|
-
parent?.postMessage(message, "*");
|
|
306
|
-
const listener = (event) => {
|
|
307
|
-
if (event.data.type === "application.selectMenuItem") {
|
|
308
|
-
handleSelectMenuItem(event.data.payload.value);
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
window.addEventListener("message", listener);
|
|
312
|
-
return () => {
|
|
313
|
-
window.removeEventListener("message", listener);
|
|
314
|
-
};
|
|
315
|
-
}, [handleSelectMenuItem, menuItems]);
|
|
316
|
-
}
|
|
317
|
-
function isEmbeddedApp() {
|
|
318
|
-
return window.self !== window.top;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
251
|
// src/hooks.ts
|
|
322
|
-
var
|
|
323
|
-
var
|
|
252
|
+
var import_state_manager = require("@noya-app/state-manager");
|
|
253
|
+
var import_react6 = require("react");
|
|
324
254
|
|
|
325
255
|
// src/globals.ts
|
|
326
256
|
var import_observable = require("@noya-app/observable");
|
|
@@ -328,18 +258,18 @@ var shouldTrackEvents$ = new import_observable.Observable(false);
|
|
|
328
258
|
var shouldTrackTasks$ = new import_observable.Observable(false);
|
|
329
259
|
|
|
330
260
|
// src/inspector/useStateInspector.tsx
|
|
331
|
-
var
|
|
261
|
+
var import_react5 = __toESM(require("react"));
|
|
332
262
|
var import_client = require("react-dom/client");
|
|
333
263
|
|
|
334
264
|
// src/inspector/StateInspector.tsx
|
|
335
|
-
var
|
|
265
|
+
var import_react4 = __toESM(require("react"));
|
|
336
266
|
var import_react_inspector = require("react-inspector");
|
|
337
267
|
|
|
338
268
|
// src/inspector/useLocalStorageState.tsx
|
|
339
|
-
var
|
|
269
|
+
var import_react3 = __toESM(require("react"));
|
|
340
270
|
var localStorage = typeof window !== "undefined" ? window.localStorage : null;
|
|
341
271
|
function useLocalStorageState(key, defaultValue) {
|
|
342
|
-
const [state, setState] =
|
|
272
|
+
const [state, setState] = import_react3.default.useState(() => {
|
|
343
273
|
const value = localStorage?.getItem(key);
|
|
344
274
|
let result = defaultValue;
|
|
345
275
|
if (value) {
|
|
@@ -384,7 +314,7 @@ function ToggleButton({
|
|
|
384
314
|
theme,
|
|
385
315
|
anchor
|
|
386
316
|
}) {
|
|
387
|
-
return /* @__PURE__ */
|
|
317
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
388
318
|
"span",
|
|
389
319
|
{
|
|
390
320
|
role: "button",
|
|
@@ -405,7 +335,7 @@ function ToggleButton({
|
|
|
405
335
|
setShowInspector(!showInspector);
|
|
406
336
|
}
|
|
407
337
|
},
|
|
408
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react4.default.createElement(
|
|
409
339
|
"svg",
|
|
410
340
|
{
|
|
411
341
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -415,7 +345,7 @@ function ToggleButton({
|
|
|
415
345
|
stroke: "currentColor",
|
|
416
346
|
className: "size-6"
|
|
417
347
|
},
|
|
418
|
-
/* @__PURE__ */
|
|
348
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
419
349
|
"path",
|
|
420
350
|
{
|
|
421
351
|
strokeLinecap: "round",
|
|
@@ -423,7 +353,7 @@ function ToggleButton({
|
|
|
423
353
|
d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
424
354
|
}
|
|
425
355
|
)
|
|
426
|
-
) : /* @__PURE__ */
|
|
356
|
+
) : /* @__PURE__ */ import_react4.default.createElement(
|
|
427
357
|
"svg",
|
|
428
358
|
{
|
|
429
359
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -433,7 +363,7 @@ function ToggleButton({
|
|
|
433
363
|
stroke: "currentColor",
|
|
434
364
|
className: "size-6"
|
|
435
365
|
},
|
|
436
|
-
/* @__PURE__ */
|
|
366
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
437
367
|
"path",
|
|
438
368
|
{
|
|
439
369
|
strokeLinecap: "round",
|
|
@@ -456,7 +386,7 @@ function DisclosureSection({
|
|
|
456
386
|
}) {
|
|
457
387
|
const theme = colorScheme === "light" ? lightTheme : darkTheme;
|
|
458
388
|
const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
|
|
459
|
-
return /* @__PURE__ */
|
|
389
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
460
390
|
"div",
|
|
461
391
|
{
|
|
462
392
|
style: {
|
|
@@ -466,7 +396,7 @@ function DisclosureSection({
|
|
|
466
396
|
...style
|
|
467
397
|
}
|
|
468
398
|
},
|
|
469
|
-
/* @__PURE__ */
|
|
399
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
470
400
|
"div",
|
|
471
401
|
{
|
|
472
402
|
onClick: () => setOpen?.(!open),
|
|
@@ -480,7 +410,7 @@ function DisclosureSection({
|
|
|
480
410
|
...open && { borderBottom: `1px solid ${borderColor}` }
|
|
481
411
|
}
|
|
482
412
|
},
|
|
483
|
-
setOpen && /* @__PURE__ */
|
|
413
|
+
setOpen && /* @__PURE__ */ import_react4.default.createElement(
|
|
484
414
|
Arrow,
|
|
485
415
|
{
|
|
486
416
|
expanded: open,
|
|
@@ -491,7 +421,7 @@ function DisclosureSection({
|
|
|
491
421
|
}
|
|
492
422
|
}
|
|
493
423
|
),
|
|
494
|
-
/* @__PURE__ */
|
|
424
|
+
/* @__PURE__ */ import_react4.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
|
|
495
425
|
right
|
|
496
426
|
),
|
|
497
427
|
open && children
|
|
@@ -505,7 +435,7 @@ function InspectorRow({
|
|
|
505
435
|
variant
|
|
506
436
|
}) {
|
|
507
437
|
const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
508
|
-
return /* @__PURE__ */
|
|
438
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
509
439
|
"div",
|
|
510
440
|
{
|
|
511
441
|
style: {
|
|
@@ -523,7 +453,7 @@ function InspectorRow({
|
|
|
523
453
|
...style
|
|
524
454
|
}
|
|
525
455
|
},
|
|
526
|
-
/* @__PURE__ */
|
|
456
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
527
457
|
"span",
|
|
528
458
|
{
|
|
529
459
|
style: {
|
|
@@ -538,7 +468,7 @@ function InspectorRow({
|
|
|
538
468
|
);
|
|
539
469
|
}
|
|
540
470
|
var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
|
|
541
|
-
var StateInspector = (0,
|
|
471
|
+
var StateInspector = (0, import_react4.memo)(function StateInspector2({
|
|
542
472
|
state,
|
|
543
473
|
connectionEvents,
|
|
544
474
|
connectedUsers,
|
|
@@ -552,12 +482,12 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
552
482
|
forceInit,
|
|
553
483
|
...props
|
|
554
484
|
}) {
|
|
555
|
-
const [didMount, setDidMount] =
|
|
556
|
-
(0,
|
|
485
|
+
const [didMount, setDidMount] = import_react4.default.useState(false);
|
|
486
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
557
487
|
setDidMount(true);
|
|
558
488
|
}, []);
|
|
559
|
-
const eventsContainerRef =
|
|
560
|
-
const historyContainerRef =
|
|
489
|
+
const eventsContainerRef = import_react4.default.useRef(null);
|
|
490
|
+
const historyContainerRef = import_react4.default.useRef(null);
|
|
561
491
|
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
562
492
|
"noya-multiplayer-react-show-inspector",
|
|
563
493
|
true
|
|
@@ -586,25 +516,25 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
586
516
|
"noya-multiplayer-react-show-ephemeral",
|
|
587
517
|
false
|
|
588
518
|
);
|
|
589
|
-
(0,
|
|
519
|
+
(0, import_react4.useEffect)(() => {
|
|
590
520
|
shouldTrackEvents$.set(showEvents);
|
|
591
521
|
}, [showEvents]);
|
|
592
|
-
(0,
|
|
522
|
+
(0, import_react4.useEffect)(() => {
|
|
593
523
|
shouldTrackTasks$.set(showTasks);
|
|
594
524
|
}, [showTasks]);
|
|
595
|
-
(0,
|
|
525
|
+
(0, import_react4.useEffect)(() => {
|
|
596
526
|
if (eventsContainerRef.current) {
|
|
597
527
|
eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
|
|
598
528
|
}
|
|
599
529
|
}, [connectionEvents]);
|
|
600
530
|
const ephemeral = useEphemeralUserData(ephemeralUserData);
|
|
601
531
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
602
|
-
(0,
|
|
532
|
+
(0, import_react4.useEffect)(() => {
|
|
603
533
|
if (historyContainerRef.current) {
|
|
604
534
|
historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
|
|
605
535
|
}
|
|
606
536
|
}, [historySnapshot]);
|
|
607
|
-
(0,
|
|
537
|
+
(0, import_react4.useEffect)(() => {
|
|
608
538
|
if (!historyContainerRef.current)
|
|
609
539
|
return;
|
|
610
540
|
const historyEntry = historyContainerRef.current.querySelector(
|
|
@@ -641,7 +571,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
641
571
|
if (!didMount)
|
|
642
572
|
return null;
|
|
643
573
|
if (!showInspector) {
|
|
644
|
-
return /* @__PURE__ */
|
|
574
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
645
575
|
"div",
|
|
646
576
|
{
|
|
647
577
|
...props,
|
|
@@ -653,7 +583,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
653
583
|
},
|
|
654
584
|
onClick: () => setShowInspector(true)
|
|
655
585
|
},
|
|
656
|
-
/* @__PURE__ */
|
|
586
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
657
587
|
ToggleButton,
|
|
658
588
|
{
|
|
659
589
|
showInspector,
|
|
@@ -664,7 +594,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
664
594
|
)
|
|
665
595
|
);
|
|
666
596
|
}
|
|
667
|
-
return /* @__PURE__ */
|
|
597
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
668
598
|
"div",
|
|
669
599
|
{
|
|
670
600
|
...props,
|
|
@@ -673,7 +603,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
673
603
|
...props.style
|
|
674
604
|
}
|
|
675
605
|
},
|
|
676
|
-
/* @__PURE__ */
|
|
606
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
677
607
|
DisclosureSection,
|
|
678
608
|
{
|
|
679
609
|
isFirst: true,
|
|
@@ -685,7 +615,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
685
615
|
flex: "0 0 auto",
|
|
686
616
|
maxHeight: "200px"
|
|
687
617
|
},
|
|
688
|
-
right: /* @__PURE__ */
|
|
618
|
+
right: /* @__PURE__ */ import_react4.default.createElement(
|
|
689
619
|
ToggleButton,
|
|
690
620
|
{
|
|
691
621
|
showInspector,
|
|
@@ -695,14 +625,14 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
695
625
|
}
|
|
696
626
|
)
|
|
697
627
|
},
|
|
698
|
-
/* @__PURE__ */
|
|
628
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react4.default.createElement(
|
|
699
629
|
InspectorRow,
|
|
700
630
|
{
|
|
701
631
|
key: user.id,
|
|
702
632
|
colorScheme,
|
|
703
633
|
variant: user.id === userId ? "up" : void 0
|
|
704
634
|
},
|
|
705
|
-
user.image && /* @__PURE__ */
|
|
635
|
+
user.image && /* @__PURE__ */ import_react4.default.createElement(
|
|
706
636
|
"img",
|
|
707
637
|
{
|
|
708
638
|
src: user.image,
|
|
@@ -723,7 +653,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
723
653
|
" (",
|
|
724
654
|
ellipsis(user.id.toString(), 8, "middle"),
|
|
725
655
|
")"
|
|
726
|
-
)), !connectedUsers && /* @__PURE__ */
|
|
656
|
+
)), !connectedUsers && /* @__PURE__ */ import_react4.default.createElement(
|
|
727
657
|
"div",
|
|
728
658
|
{
|
|
729
659
|
style: {
|
|
@@ -734,17 +664,17 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
734
664
|
gap: "4px"
|
|
735
665
|
}
|
|
736
666
|
},
|
|
737
|
-
/* @__PURE__ */
|
|
667
|
+
/* @__PURE__ */ import_react4.default.createElement("span", null, "No connected users")
|
|
738
668
|
))
|
|
739
669
|
),
|
|
740
|
-
/* @__PURE__ */
|
|
670
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
741
671
|
DisclosureSection,
|
|
742
672
|
{
|
|
743
673
|
title: "Data",
|
|
744
674
|
colorScheme,
|
|
745
675
|
setOpen: setShowData,
|
|
746
676
|
open: showData,
|
|
747
|
-
right: /* @__PURE__ */
|
|
677
|
+
right: /* @__PURE__ */ import_react4.default.createElement(
|
|
748
678
|
"span",
|
|
749
679
|
{
|
|
750
680
|
style: {
|
|
@@ -752,7 +682,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
752
682
|
gap: "4px"
|
|
753
683
|
}
|
|
754
684
|
},
|
|
755
|
-
/* @__PURE__ */
|
|
685
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
756
686
|
SmallButton,
|
|
757
687
|
{
|
|
758
688
|
theme,
|
|
@@ -764,14 +694,14 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
764
694
|
)
|
|
765
695
|
)
|
|
766
696
|
},
|
|
767
|
-
/* @__PURE__ */
|
|
697
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
|
|
768
698
|
import_react_inspector.ObjectInspector,
|
|
769
699
|
{
|
|
770
700
|
name: multiplayerStateManager.schema ? "state" : void 0,
|
|
771
701
|
data: state,
|
|
772
702
|
theme
|
|
773
703
|
}
|
|
774
|
-
)), multiplayerStateManager.schema && /* @__PURE__ */
|
|
704
|
+
)), multiplayerStateManager.schema && /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
|
|
775
705
|
import_react_inspector.ObjectInspector,
|
|
776
706
|
{
|
|
777
707
|
name: "schema",
|
|
@@ -780,14 +710,14 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
780
710
|
}
|
|
781
711
|
)))
|
|
782
712
|
),
|
|
783
|
-
/* @__PURE__ */
|
|
713
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
784
714
|
DisclosureSection,
|
|
785
715
|
{
|
|
786
716
|
open: showHistory,
|
|
787
717
|
setOpen: setShowHistory,
|
|
788
718
|
title: "History",
|
|
789
719
|
colorScheme,
|
|
790
|
-
right: /* @__PURE__ */
|
|
720
|
+
right: /* @__PURE__ */ import_react4.default.createElement(
|
|
791
721
|
"span",
|
|
792
722
|
{
|
|
793
723
|
style: {
|
|
@@ -795,7 +725,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
795
725
|
gap: "4px"
|
|
796
726
|
}
|
|
797
727
|
},
|
|
798
|
-
/* @__PURE__ */
|
|
728
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
799
729
|
SmallButton,
|
|
800
730
|
{
|
|
801
731
|
disabled: !historySnapshot.canUndo,
|
|
@@ -804,7 +734,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
804
734
|
multiplayerStateManager.undo();
|
|
805
735
|
}
|
|
806
736
|
},
|
|
807
|
-
/* @__PURE__ */
|
|
737
|
+
/* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
|
|
808
738
|
"svg",
|
|
809
739
|
{
|
|
810
740
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -812,7 +742,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
812
742
|
height: "1em",
|
|
813
743
|
viewBox: "0 0 20 20"
|
|
814
744
|
},
|
|
815
|
-
/* @__PURE__ */
|
|
745
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
816
746
|
"path",
|
|
817
747
|
{
|
|
818
748
|
fill: "currentColor",
|
|
@@ -821,7 +751,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
821
751
|
)
|
|
822
752
|
))
|
|
823
753
|
),
|
|
824
|
-
/* @__PURE__ */
|
|
754
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
825
755
|
SmallButton,
|
|
826
756
|
{
|
|
827
757
|
disabled: !historySnapshot.canRedo,
|
|
@@ -830,7 +760,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
830
760
|
multiplayerStateManager.redo();
|
|
831
761
|
}
|
|
832
762
|
},
|
|
833
|
-
/* @__PURE__ */
|
|
763
|
+
/* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
|
|
834
764
|
"svg",
|
|
835
765
|
{
|
|
836
766
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -838,7 +768,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
838
768
|
height: "1em",
|
|
839
769
|
viewBox: "0 0 20 20"
|
|
840
770
|
},
|
|
841
|
-
/* @__PURE__ */
|
|
771
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
842
772
|
"path",
|
|
843
773
|
{
|
|
844
774
|
fill: "currentColor",
|
|
@@ -849,7 +779,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
849
779
|
)
|
|
850
780
|
)
|
|
851
781
|
},
|
|
852
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(
|
|
853
783
|
"div",
|
|
854
784
|
{
|
|
855
785
|
id: `${HISTORY_ELEMENT_PREFIX}0`,
|
|
@@ -863,7 +793,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
863
793
|
background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
|
|
864
794
|
}
|
|
865
795
|
},
|
|
866
|
-
/* @__PURE__ */
|
|
796
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
867
797
|
"span",
|
|
868
798
|
{
|
|
869
799
|
style: {
|
|
@@ -875,7 +805,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
875
805
|
},
|
|
876
806
|
"Initial state"
|
|
877
807
|
)
|
|
878
|
-
), historySnapshot.history.map((entry, index) => /* @__PURE__ */
|
|
808
|
+
), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(
|
|
879
809
|
"div",
|
|
880
810
|
{
|
|
881
811
|
id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
|
|
@@ -886,7 +816,18 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
886
816
|
background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
|
|
887
817
|
}
|
|
888
818
|
},
|
|
889
|
-
entry.
|
|
819
|
+
"name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */ import_react4.default.createElement(
|
|
820
|
+
"pre",
|
|
821
|
+
{
|
|
822
|
+
style: {
|
|
823
|
+
fontSize: "11px",
|
|
824
|
+
display: "flex",
|
|
825
|
+
flexWrap: "wrap"
|
|
826
|
+
}
|
|
827
|
+
},
|
|
828
|
+
entry.metadata.name
|
|
829
|
+
),
|
|
830
|
+
entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react4.default.createElement(
|
|
890
831
|
"pre",
|
|
891
832
|
{
|
|
892
833
|
key: j,
|
|
@@ -896,14 +837,14 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
896
837
|
flexWrap: "wrap"
|
|
897
838
|
}
|
|
898
839
|
},
|
|
899
|
-
patch.op === "add" && /* @__PURE__ */
|
|
900
|
-
patch.op === "replace" && /* @__PURE__ */
|
|
901
|
-
patch.op === "remove" && /* @__PURE__ */
|
|
902
|
-
patch.op === "move" && /* @__PURE__ */
|
|
840
|
+
patch.op === "add" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
|
|
841
|
+
patch.op === "replace" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
|
|
842
|
+
patch.op === "remove" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
|
|
843
|
+
patch.op === "move" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
|
|
903
844
|
))
|
|
904
845
|
)))
|
|
905
846
|
),
|
|
906
|
-
/* @__PURE__ */
|
|
847
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
907
848
|
DisclosureSection,
|
|
908
849
|
{
|
|
909
850
|
title: "Tasks",
|
|
@@ -911,7 +852,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
911
852
|
open: showTasks,
|
|
912
853
|
setOpen: setShowTasks
|
|
913
854
|
},
|
|
914
|
-
/* @__PURE__ */
|
|
855
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react4.default.createElement(
|
|
915
856
|
InspectorRow,
|
|
916
857
|
{
|
|
917
858
|
key: task.id,
|
|
@@ -920,7 +861,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
920
861
|
backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
|
|
921
862
|
}
|
|
922
863
|
},
|
|
923
|
-
/* @__PURE__ */
|
|
864
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
924
865
|
import_react_inspector.ObjectInspector,
|
|
925
866
|
{
|
|
926
867
|
name: task.name,
|
|
@@ -930,7 +871,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
930
871
|
)
|
|
931
872
|
)))
|
|
932
873
|
),
|
|
933
|
-
/* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
934
875
|
DisclosureSection,
|
|
935
876
|
{
|
|
936
877
|
open: showEphemeral,
|
|
@@ -938,7 +879,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
938
879
|
title: "Ephemeral User Data",
|
|
939
880
|
colorScheme
|
|
940
881
|
},
|
|
941
|
-
/* @__PURE__ */
|
|
882
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
|
|
942
883
|
import_react_inspector.ObjectInspector,
|
|
943
884
|
{
|
|
944
885
|
name: key,
|
|
@@ -948,7 +889,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
948
889
|
}
|
|
949
890
|
))))
|
|
950
891
|
),
|
|
951
|
-
/* @__PURE__ */
|
|
892
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
952
893
|
DisclosureSection,
|
|
953
894
|
{
|
|
954
895
|
open: showEvents,
|
|
@@ -956,8 +897,8 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
956
897
|
title: "Events",
|
|
957
898
|
colorScheme
|
|
958
899
|
},
|
|
959
|
-
/* @__PURE__ */
|
|
960
|
-
(event, index) => event.type === "stateChange" ? /* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
|
|
901
|
+
(event, index) => event.type === "stateChange" ? /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ import_react4.default.createElement(
|
|
961
902
|
InspectorRow,
|
|
962
903
|
{
|
|
963
904
|
key: index,
|
|
@@ -967,7 +908,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
967
908
|
padding: "0px 12px 1px"
|
|
968
909
|
}
|
|
969
910
|
},
|
|
970
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ import_react4.default.createElement(
|
|
971
912
|
import_react_inspector.ObjectInspector,
|
|
972
913
|
{
|
|
973
914
|
data: event.message,
|
|
@@ -980,7 +921,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
980
921
|
expanded
|
|
981
922
|
}) => {
|
|
982
923
|
const direction = event.type === "send" ? "up" : "down";
|
|
983
|
-
return depth === 0 ? /* @__PURE__ */
|
|
924
|
+
return depth === 0 ? /* @__PURE__ */ import_react4.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react4.default.createElement(
|
|
984
925
|
import_react_inspector.ObjectLabel,
|
|
985
926
|
{
|
|
986
927
|
direction,
|
|
@@ -993,7 +934,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
993
934
|
}
|
|
994
935
|
)
|
|
995
936
|
)
|
|
996
|
-
), !connectionEvents && /* @__PURE__ */
|
|
937
|
+
), !connectionEvents && /* @__PURE__ */ import_react4.default.createElement(
|
|
997
938
|
"div",
|
|
998
939
|
{
|
|
999
940
|
style: {
|
|
@@ -1004,18 +945,18 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
1004
945
|
gap: "4px"
|
|
1005
946
|
}
|
|
1006
947
|
},
|
|
1007
|
-
/* @__PURE__ */
|
|
948
|
+
/* @__PURE__ */ import_react4.default.createElement("span", null, "No recorded events")
|
|
1008
949
|
))
|
|
1009
950
|
)
|
|
1010
951
|
);
|
|
1011
952
|
});
|
|
1012
953
|
var ObjectRootLabel = ({ name, data, direction }) => {
|
|
1013
954
|
if (typeof name === "string") {
|
|
1014
|
-
return /* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ import_react4.default.createElement("span", null, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectName, { name }), /* @__PURE__ */ import_react4.default.createElement("span", null, ": "), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
|
|
1015
956
|
}
|
|
1016
957
|
if (direction === "up" || direction === "down") {
|
|
1017
958
|
const arrow = direction === "up" ? "\u2191" : "\u2193";
|
|
1018
|
-
return /* @__PURE__ */
|
|
959
|
+
return /* @__PURE__ */ import_react4.default.createElement("span", null, /* @__PURE__ */ import_react4.default.createElement(
|
|
1019
960
|
"span",
|
|
1020
961
|
{
|
|
1021
962
|
style: {
|
|
@@ -1032,9 +973,9 @@ var ObjectRootLabel = ({ name, data, direction }) => {
|
|
|
1032
973
|
}
|
|
1033
974
|
},
|
|
1034
975
|
arrow
|
|
1035
|
-
), /* @__PURE__ */
|
|
976
|
+
), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
|
|
1036
977
|
} else {
|
|
1037
|
-
return /* @__PURE__ */
|
|
978
|
+
return /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data });
|
|
1038
979
|
}
|
|
1039
980
|
};
|
|
1040
981
|
function Arrow({
|
|
@@ -1042,7 +983,7 @@ function Arrow({
|
|
|
1042
983
|
onClick,
|
|
1043
984
|
style
|
|
1044
985
|
}) {
|
|
1045
|
-
return /* @__PURE__ */
|
|
986
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
1046
987
|
"span",
|
|
1047
988
|
{
|
|
1048
989
|
role: "button",
|
|
@@ -1085,7 +1026,7 @@ function SmallButton({
|
|
|
1085
1026
|
theme,
|
|
1086
1027
|
disabled
|
|
1087
1028
|
}) {
|
|
1088
|
-
return /* @__PURE__ */
|
|
1029
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
1089
1030
|
"button",
|
|
1090
1031
|
{
|
|
1091
1032
|
type: "button",
|
|
@@ -1134,8 +1075,8 @@ function useStateInspector({
|
|
|
1134
1075
|
ephemeralUserData,
|
|
1135
1076
|
forceInit
|
|
1136
1077
|
}) {
|
|
1137
|
-
const [root, setRoot] =
|
|
1138
|
-
(0,
|
|
1078
|
+
const [root, setRoot] = import_react5.default.useState(null);
|
|
1079
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
1139
1080
|
if (disabled)
|
|
1140
1081
|
return;
|
|
1141
1082
|
const portalElement = createPortalElement();
|
|
@@ -1146,11 +1087,11 @@ function useStateInspector({
|
|
|
1146
1087
|
document.body.removeChild(portalElement);
|
|
1147
1088
|
};
|
|
1148
1089
|
}, [disabled]);
|
|
1149
|
-
(0,
|
|
1090
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
1150
1091
|
if (!root)
|
|
1151
1092
|
return;
|
|
1152
1093
|
root.render(
|
|
1153
|
-
/* @__PURE__ */
|
|
1094
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
1154
1095
|
StateInspector,
|
|
1155
1096
|
{
|
|
1156
1097
|
state,
|
|
@@ -1183,22 +1124,22 @@ function useStateInspector({
|
|
|
1183
1124
|
|
|
1184
1125
|
// src/hooks.ts
|
|
1185
1126
|
function useSyncStateManager(stateManager, path) {
|
|
1186
|
-
const getSnapshot = (0,
|
|
1127
|
+
const getSnapshot = (0, import_react6.useCallback)(
|
|
1187
1128
|
() => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
|
|
1188
1129
|
[stateManager, path]
|
|
1189
1130
|
);
|
|
1190
|
-
return (0,
|
|
1131
|
+
return (0, import_react6.useSyncExternalStore)(
|
|
1191
1132
|
stateManager.addListener,
|
|
1192
1133
|
getSnapshot,
|
|
1193
1134
|
getSnapshot
|
|
1194
1135
|
);
|
|
1195
1136
|
}
|
|
1196
1137
|
function useManagedState(createInitialState, options) {
|
|
1197
|
-
const [stateManager] = (0,
|
|
1198
|
-
() => new
|
|
1138
|
+
const [stateManager] = (0, import_react6.useState)(
|
|
1139
|
+
() => new import_state_manager.StateManager(createInitialState(), options)
|
|
1199
1140
|
);
|
|
1200
1141
|
const state = useSyncStateManager(stateManager);
|
|
1201
|
-
const setState = (0,
|
|
1142
|
+
const setState = (0, import_react6.useCallback)(
|
|
1202
1143
|
(...args) => {
|
|
1203
1144
|
const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
|
|
1204
1145
|
if (metadata === void 0) {
|
|
@@ -1234,47 +1175,48 @@ function useManagedState(createInitialState, options) {
|
|
|
1234
1175
|
return [state, setState, stateManager];
|
|
1235
1176
|
}
|
|
1236
1177
|
function useManagedHistory(stateManager) {
|
|
1237
|
-
return (0,
|
|
1178
|
+
return (0, import_react6.useSyncExternalStore)(
|
|
1238
1179
|
stateManager.historyEmittor.addListener,
|
|
1239
1180
|
stateManager.getHistorySnapshot,
|
|
1240
1181
|
stateManager.getHistorySnapshot
|
|
1241
1182
|
);
|
|
1242
1183
|
}
|
|
1243
1184
|
function useSyncMultiplayerStateManager(multiplayerStateManager) {
|
|
1244
|
-
return (0,
|
|
1185
|
+
return (0, import_react6.useSyncExternalStore)(
|
|
1245
1186
|
multiplayerStateManager.addListener,
|
|
1246
1187
|
multiplayerStateManager.getOptimisticState,
|
|
1247
1188
|
multiplayerStateManager.getOptimisticState
|
|
1248
1189
|
);
|
|
1249
1190
|
}
|
|
1250
1191
|
function useEphemeralUserData(ephemeralUserData) {
|
|
1251
|
-
return (0,
|
|
1192
|
+
return (0, import_react6.useSyncExternalStore)(
|
|
1252
1193
|
ephemeralUserData.addListener,
|
|
1253
1194
|
ephemeralUserData.getSnapshot,
|
|
1254
1195
|
ephemeralUserData.getSnapshot
|
|
1255
1196
|
);
|
|
1256
1197
|
}
|
|
1257
|
-
var defaultStubSync = (0,
|
|
1198
|
+
var defaultStubSync = (0, import_state_manager.stubSync)();
|
|
1258
1199
|
function useMultiplayerState(initialState, options) {
|
|
1259
1200
|
const { sync = defaultStubSync, ...rest } = options ?? {};
|
|
1260
|
-
const [multiplayerStateManager] = (0,
|
|
1261
|
-
() => new
|
|
1201
|
+
const [multiplayerStateManager] = (0, import_react6.useState)(
|
|
1202
|
+
() => new import_state_manager.MultiplayerStateManager(initialState, rest)
|
|
1262
1203
|
);
|
|
1263
|
-
const syncRef = (0,
|
|
1264
|
-
const [connectionEvents, setConnectionEvents] = (0,
|
|
1265
|
-
const [connectedUsers, setConnectedUsers] = (0,
|
|
1266
|
-
const [ephemeralUserData] = (0,
|
|
1267
|
-
() => new
|
|
1204
|
+
const syncRef = (0, import_react6.useRef)(sync);
|
|
1205
|
+
const [connectionEvents, setConnectionEvents] = (0, import_react6.useState)();
|
|
1206
|
+
const [connectedUsers, setConnectedUsers] = (0, import_react6.useState)([]);
|
|
1207
|
+
const [ephemeralUserData] = (0, import_react6.useState)(
|
|
1208
|
+
() => new import_state_manager.EphemeralUserData()
|
|
1268
1209
|
);
|
|
1269
|
-
const [tasks, setTasks] = (0,
|
|
1270
|
-
const [userId, setUserId] = (0,
|
|
1271
|
-
const extras = (0,
|
|
1210
|
+
const [tasks, setTasks] = (0, import_react6.useState)([]);
|
|
1211
|
+
const [userId, setUserId] = (0, import_react6.useState)();
|
|
1212
|
+
const extras = (0, import_react6.useMemo)(() => {
|
|
1272
1213
|
return {
|
|
1273
1214
|
tasks,
|
|
1274
1215
|
userId,
|
|
1275
1216
|
connectionEvents,
|
|
1276
1217
|
connectedUsers,
|
|
1277
|
-
ephemeralUserData
|
|
1218
|
+
ephemeralUserData,
|
|
1219
|
+
multiplayerStateManager
|
|
1278
1220
|
// evaluate: async (code: string) => {
|
|
1279
1221
|
// const payload = await rpcManager.request({ type: "eval", code });
|
|
1280
1222
|
// if (payload.type !== "eval") {
|
|
@@ -1282,27 +1224,34 @@ function useMultiplayerState(initialState, options) {
|
|
|
1282
1224
|
// }
|
|
1283
1225
|
// },
|
|
1284
1226
|
};
|
|
1285
|
-
}, [
|
|
1227
|
+
}, [
|
|
1228
|
+
tasks,
|
|
1229
|
+
userId,
|
|
1230
|
+
connectionEvents,
|
|
1231
|
+
connectedUsers,
|
|
1232
|
+
ephemeralUserData,
|
|
1233
|
+
multiplayerStateManager
|
|
1234
|
+
]);
|
|
1286
1235
|
const globalTrackEvents = useObservable(shouldTrackEvents$);
|
|
1287
1236
|
const globalTrackTasks = useObservable(shouldTrackTasks$);
|
|
1288
1237
|
const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;
|
|
1289
1238
|
const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;
|
|
1290
|
-
const trackEventsCallbackRef = (0,
|
|
1291
|
-
const trackConnectedUsersCallbackRef = (0,
|
|
1292
|
-
const trackTasksCallbackRef = (0,
|
|
1293
|
-
(0,
|
|
1239
|
+
const trackEventsCallbackRef = (0, import_react6.useRef)();
|
|
1240
|
+
const trackConnectedUsersCallbackRef = (0, import_react6.useRef)();
|
|
1241
|
+
const trackTasksCallbackRef = (0, import_react6.useRef)();
|
|
1242
|
+
(0, import_react6.useEffect)(() => {
|
|
1294
1243
|
trackEventsCallbackRef.current = shouldTrackEvents ? (e) => setConnectionEvents((events) => {
|
|
1295
1244
|
const updated = events ? [...events, e] : [e];
|
|
1296
1245
|
return updated.length > 50 ? updated.slice(-50) : updated;
|
|
1297
1246
|
}) : void 0;
|
|
1298
1247
|
}, [shouldTrackEvents]);
|
|
1299
|
-
(0,
|
|
1248
|
+
(0, import_react6.useEffect)(() => {
|
|
1300
1249
|
trackConnectedUsersCallbackRef.current = (users, userId2) => {
|
|
1301
1250
|
setConnectedUsers(users);
|
|
1302
1251
|
setUserId(userId2);
|
|
1303
1252
|
};
|
|
1304
1253
|
}, []);
|
|
1305
|
-
(0,
|
|
1254
|
+
(0, import_react6.useEffect)(() => {
|
|
1306
1255
|
trackTasksCallbackRef.current = shouldTrackTasks ? (tasks2) => {
|
|
1307
1256
|
setTasks((old) => {
|
|
1308
1257
|
const newIds = new Set(tasks2.map((t) => t.id));
|
|
@@ -1311,7 +1260,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1311
1260
|
});
|
|
1312
1261
|
} : void 0;
|
|
1313
1262
|
}, [shouldTrackTasks]);
|
|
1314
|
-
(0,
|
|
1263
|
+
(0, import_react6.useEffect)(() => {
|
|
1315
1264
|
if (syncRef.current) {
|
|
1316
1265
|
return syncRef.current({
|
|
1317
1266
|
ms: multiplayerStateManager,
|
|
@@ -1323,7 +1272,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1323
1272
|
}
|
|
1324
1273
|
}, [ephemeralUserData, multiplayerStateManager]);
|
|
1325
1274
|
const state = useSyncMultiplayerStateManager(multiplayerStateManager);
|
|
1326
|
-
const forceInit = (0,
|
|
1275
|
+
const forceInit = (0, import_react6.useCallback)(() => {
|
|
1327
1276
|
const state2 = typeof initialState === "function" ? initialState() : initialState;
|
|
1328
1277
|
const schema = options?.schema;
|
|
1329
1278
|
multiplayerStateManager.sm.clearHistory();
|
|
@@ -1341,13 +1290,104 @@ function useMultiplayerState(initialState, options) {
|
|
|
1341
1290
|
disabled: !options?.inspector,
|
|
1342
1291
|
...typeof options?.inspector === "object" && options.inspector
|
|
1343
1292
|
});
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1293
|
+
return [state, multiplayerStateManager.setState, extras];
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
// src/noyaApp.ts
|
|
1297
|
+
var import_state_manager2 = require("@noya-app/state-manager");
|
|
1298
|
+
var import_react7 = require("react");
|
|
1299
|
+
function createDefaultAppData(initialState) {
|
|
1300
|
+
return {
|
|
1301
|
+
theme: "light",
|
|
1302
|
+
viewType: "editable",
|
|
1303
|
+
initialState,
|
|
1304
|
+
inspector: false
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
function getAppData(initialState) {
|
|
1308
|
+
try {
|
|
1309
|
+
const urlHash = (window.location.hash || "").replace(/^#/, "");
|
|
1310
|
+
const params = new URLSearchParams(urlHash);
|
|
1311
|
+
const data = params.get("data");
|
|
1312
|
+
if (!data) {
|
|
1313
|
+
return initialState ? createDefaultAppData(initialState) : void 0;
|
|
1314
|
+
}
|
|
1315
|
+
const parsed = JSON.parse(data);
|
|
1316
|
+
if (!parsed.initialState) {
|
|
1317
|
+
parsed.initialState = initialState;
|
|
1318
|
+
}
|
|
1319
|
+
return parsed;
|
|
1320
|
+
} catch (e) {
|
|
1321
|
+
return initialState ? createDefaultAppData(initialState) : void 0;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
function useAppData(initialState, { schema } = {}) {
|
|
1325
|
+
const appData = (0, import_react7.useMemo)(() => {
|
|
1326
|
+
return getAppData(
|
|
1327
|
+
schema ? (0, import_state_manager2.createValue)(schema, initialState) : initialState
|
|
1328
|
+
);
|
|
1329
|
+
}, [initialState, schema]);
|
|
1330
|
+
return appData;
|
|
1331
|
+
}
|
|
1332
|
+
function useBroadcastConnectedUsers(connectedUsers) {
|
|
1333
|
+
(0, import_react7.useEffect)(() => {
|
|
1334
|
+
if (!isEmbeddedApp())
|
|
1335
|
+
return;
|
|
1336
|
+
const message = {
|
|
1337
|
+
type: "multiplayer.setUsers",
|
|
1338
|
+
payload: { users: connectedUsers }
|
|
1339
|
+
};
|
|
1340
|
+
parent?.postMessage(message, "*");
|
|
1341
|
+
}, [connectedUsers]);
|
|
1342
|
+
}
|
|
1343
|
+
function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
|
|
1344
|
+
(0, import_react7.useEffect)(() => {
|
|
1345
|
+
if (!isEmbeddedApp())
|
|
1346
|
+
return;
|
|
1347
|
+
const message = {
|
|
1348
|
+
type: "application.setMenuItems",
|
|
1349
|
+
payload: { menuItems }
|
|
1350
|
+
};
|
|
1351
|
+
parent?.postMessage(message, "*");
|
|
1352
|
+
const listener = (event) => {
|
|
1353
|
+
if (event.data.type === "application.selectMenuItem") {
|
|
1354
|
+
handleSelectMenuItem(event.data.payload.value);
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
window.addEventListener("message", listener);
|
|
1358
|
+
return () => {
|
|
1359
|
+
window.removeEventListener("message", listener);
|
|
1360
|
+
};
|
|
1361
|
+
}, [handleSelectMenuItem, menuItems]);
|
|
1362
|
+
}
|
|
1363
|
+
function isEmbeddedApp() {
|
|
1364
|
+
return window.self !== window.top;
|
|
1365
|
+
}
|
|
1366
|
+
function useNoyaAppState(initialState, options) {
|
|
1367
|
+
const [state] = (0, import_react7.useState)(initialState);
|
|
1368
|
+
const {
|
|
1369
|
+
multiplayerUrl,
|
|
1370
|
+
inspector,
|
|
1371
|
+
initialState: noyaAppInitialState,
|
|
1372
|
+
theme,
|
|
1373
|
+
viewType
|
|
1374
|
+
} = useAppData(state, {
|
|
1375
|
+
schema: options.schema
|
|
1376
|
+
});
|
|
1377
|
+
const sync = (0, import_react7.useMemo)(() => {
|
|
1378
|
+
return multiplayerUrl ? (0, import_state_manager2.webSocketSync)(multiplayerUrl) : (0, import_state_manager2.localStorageSync)({ key: options.localStorageKey || "noya-app" });
|
|
1379
|
+
}, [multiplayerUrl, options.localStorageKey]);
|
|
1380
|
+
const result = useMultiplayerState(noyaAppInitialState, {
|
|
1381
|
+
...options,
|
|
1382
|
+
inspector: options.inspector ?? inspector,
|
|
1383
|
+
sync
|
|
1384
|
+
});
|
|
1385
|
+
const [, , extras] = result;
|
|
1386
|
+
useBroadcastConnectedUsers(extras.connectedUsers);
|
|
1387
|
+
const mergedExtras = (0, import_react7.useMemo)(() => {
|
|
1388
|
+
return { ...extras, theme, viewType };
|
|
1389
|
+
}, [extras, theme, viewType]);
|
|
1390
|
+
return [result[0], result[1], mergedExtras];
|
|
1351
1391
|
}
|
|
1352
1392
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1353
1393
|
0 && (module.exports = {
|
|
@@ -1362,13 +1402,14 @@ function useMultiplayerState(initialState, options) {
|
|
|
1362
1402
|
getAvatarInitials,
|
|
1363
1403
|
getAvatarStyle,
|
|
1364
1404
|
isEmbeddedApp,
|
|
1405
|
+
useAppData,
|
|
1365
1406
|
useBroadcastConnectedUsers,
|
|
1366
1407
|
useBroadcastMenuItems,
|
|
1367
1408
|
useEphemeralUserData,
|
|
1368
1409
|
useManagedHistory,
|
|
1369
1410
|
useManagedState,
|
|
1370
1411
|
useMultiplayerState,
|
|
1371
|
-
|
|
1412
|
+
useNoyaAppState,
|
|
1372
1413
|
useSyncMultiplayerStateManager,
|
|
1373
1414
|
useSyncStateManager,
|
|
1374
1415
|
...require("@noya-app/state-manager")
|