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