@noya-app/noya-multiplayer-react 0.1.21 → 0.1.22

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/dist/index.js CHANGED
@@ -37,12 +37,18 @@ __export(src_exports, {
37
37
  UserPointerContainer: () => UserPointerContainer,
38
38
  UserPointerIcon: () => UserPointerIcon,
39
39
  UserPointersOverlay: () => UserPointersOverlay,
40
+ createDefaultAppData: () => createDefaultAppData,
41
+ getAppData: () => getAppData,
40
42
  getAvatarInitials: () => getAvatarInitials,
41
43
  getAvatarStyle: () => getAvatarStyle,
44
+ isEmbeddedApp: () => isEmbeddedApp,
45
+ useBroadcastConnectedUsers: () => useBroadcastConnectedUsers,
46
+ useBroadcastMenuItems: () => useBroadcastMenuItems,
42
47
  useEphemeralUserData: () => useEphemeralUserData,
43
48
  useManagedHistory: () => useManagedHistory,
44
49
  useManagedState: () => useManagedState,
45
50
  useMultiplayerState: () => useMultiplayerState,
51
+ useNoyaApp: () => useNoyaApp,
46
52
  useSyncMultiplayerStateManager: () => useSyncMultiplayerStateManager,
47
53
  useSyncStateManager: () => useSyncStateManager
48
54
  });
@@ -241,9 +247,80 @@ var UserPointerIcon = (0, import_react2.memo)(function CursorIcon({
241
247
  );
242
248
  });
243
249
 
244
- // src/hooks.ts
250
+ // src/embedded.ts
245
251
  var import_state_manager = require("@noya-app/state-manager");
246
- var import_react6 = require("react");
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
+ // src/hooks.ts
322
+ var import_state_manager2 = require("@noya-app/state-manager");
323
+ var import_react7 = require("react");
247
324
 
248
325
  // src/globals.ts
249
326
  var import_observable = require("@noya-app/observable");
@@ -251,18 +328,18 @@ var shouldTrackEvents$ = new import_observable.Observable(false);
251
328
  var shouldTrackTasks$ = new import_observable.Observable(false);
252
329
 
253
330
  // src/inspector/useStateInspector.tsx
254
- var import_react5 = __toESM(require("react"));
331
+ var import_react6 = __toESM(require("react"));
255
332
  var import_client = require("react-dom/client");
256
333
 
257
334
  // src/inspector/StateInspector.tsx
258
- var import_react4 = __toESM(require("react"));
335
+ var import_react5 = __toESM(require("react"));
259
336
  var import_react_inspector = require("react-inspector");
260
337
 
261
338
  // src/inspector/useLocalStorageState.tsx
262
- var import_react3 = __toESM(require("react"));
339
+ var import_react4 = __toESM(require("react"));
263
340
  var localStorage = typeof window !== "undefined" ? window.localStorage : null;
264
341
  function useLocalStorageState(key, defaultValue) {
265
- const [state, setState] = import_react3.default.useState(() => {
342
+ const [state, setState] = import_react4.default.useState(() => {
266
343
  const value = localStorage?.getItem(key);
267
344
  let result = defaultValue;
268
345
  if (value) {
@@ -307,7 +384,7 @@ function ToggleButton({
307
384
  theme,
308
385
  anchor
309
386
  }) {
310
- return /* @__PURE__ */ import_react4.default.createElement(
387
+ return /* @__PURE__ */ import_react5.default.createElement(
311
388
  "span",
312
389
  {
313
390
  role: "button",
@@ -328,7 +405,7 @@ function ToggleButton({
328
405
  setShowInspector(!showInspector);
329
406
  }
330
407
  },
331
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react4.default.createElement(
408
+ /* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react5.default.createElement(
332
409
  "svg",
333
410
  {
334
411
  xmlns: "http://www.w3.org/2000/svg",
@@ -338,7 +415,7 @@ function ToggleButton({
338
415
  stroke: "currentColor",
339
416
  className: "size-6"
340
417
  },
341
- /* @__PURE__ */ import_react4.default.createElement(
418
+ /* @__PURE__ */ import_react5.default.createElement(
342
419
  "path",
343
420
  {
344
421
  strokeLinecap: "round",
@@ -346,7 +423,7 @@ function ToggleButton({
346
423
  d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
347
424
  }
348
425
  )
349
- ) : /* @__PURE__ */ import_react4.default.createElement(
426
+ ) : /* @__PURE__ */ import_react5.default.createElement(
350
427
  "svg",
351
428
  {
352
429
  xmlns: "http://www.w3.org/2000/svg",
@@ -356,7 +433,7 @@ function ToggleButton({
356
433
  stroke: "currentColor",
357
434
  className: "size-6"
358
435
  },
359
- /* @__PURE__ */ import_react4.default.createElement(
436
+ /* @__PURE__ */ import_react5.default.createElement(
360
437
  "path",
361
438
  {
362
439
  strokeLinecap: "round",
@@ -379,7 +456,7 @@ function DisclosureSection({
379
456
  }) {
380
457
  const theme = colorScheme === "light" ? lightTheme : darkTheme;
381
458
  const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
382
- return /* @__PURE__ */ import_react4.default.createElement(
459
+ return /* @__PURE__ */ import_react5.default.createElement(
383
460
  "div",
384
461
  {
385
462
  style: {
@@ -389,7 +466,7 @@ function DisclosureSection({
389
466
  ...style
390
467
  }
391
468
  },
392
- /* @__PURE__ */ import_react4.default.createElement(
469
+ /* @__PURE__ */ import_react5.default.createElement(
393
470
  "div",
394
471
  {
395
472
  onClick: () => setOpen?.(!open),
@@ -403,7 +480,7 @@ function DisclosureSection({
403
480
  ...open && { borderBottom: `1px solid ${borderColor}` }
404
481
  }
405
482
  },
406
- setOpen && /* @__PURE__ */ import_react4.default.createElement(
483
+ setOpen && /* @__PURE__ */ import_react5.default.createElement(
407
484
  Arrow,
408
485
  {
409
486
  expanded: open,
@@ -414,7 +491,7 @@ function DisclosureSection({
414
491
  }
415
492
  }
416
493
  ),
417
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
494
+ /* @__PURE__ */ import_react5.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
418
495
  right
419
496
  ),
420
497
  open && children
@@ -428,7 +505,7 @@ function InspectorRow({
428
505
  variant
429
506
  }) {
430
507
  const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
431
- return /* @__PURE__ */ import_react4.default.createElement(
508
+ return /* @__PURE__ */ import_react5.default.createElement(
432
509
  "div",
433
510
  {
434
511
  style: {
@@ -446,7 +523,7 @@ function InspectorRow({
446
523
  ...style
447
524
  }
448
525
  },
449
- /* @__PURE__ */ import_react4.default.createElement(
526
+ /* @__PURE__ */ import_react5.default.createElement(
450
527
  "span",
451
528
  {
452
529
  style: {
@@ -461,7 +538,7 @@ function InspectorRow({
461
538
  );
462
539
  }
463
540
  var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
464
- var StateInspector = (0, import_react4.memo)(function StateInspector2({
541
+ var StateInspector = (0, import_react5.memo)(function StateInspector2({
465
542
  state,
466
543
  connectionEvents,
467
544
  connectedUsers,
@@ -475,12 +552,12 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
475
552
  forceInit,
476
553
  ...props
477
554
  }) {
478
- const [didMount, setDidMount] = import_react4.default.useState(false);
479
- (0, import_react4.useLayoutEffect)(() => {
555
+ const [didMount, setDidMount] = import_react5.default.useState(false);
556
+ (0, import_react5.useLayoutEffect)(() => {
480
557
  setDidMount(true);
481
558
  }, []);
482
- const eventsContainerRef = import_react4.default.useRef(null);
483
- const historyContainerRef = import_react4.default.useRef(null);
559
+ const eventsContainerRef = import_react5.default.useRef(null);
560
+ const historyContainerRef = import_react5.default.useRef(null);
484
561
  const [showInspector, setShowInspector] = useLocalStorageState(
485
562
  "noya-multiplayer-react-show-inspector",
486
563
  true
@@ -509,25 +586,25 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
509
586
  "noya-multiplayer-react-show-ephemeral",
510
587
  false
511
588
  );
512
- (0, import_react4.useEffect)(() => {
589
+ (0, import_react5.useEffect)(() => {
513
590
  shouldTrackEvents$.set(showEvents);
514
591
  }, [showEvents]);
515
- (0, import_react4.useEffect)(() => {
592
+ (0, import_react5.useEffect)(() => {
516
593
  shouldTrackTasks$.set(showTasks);
517
594
  }, [showTasks]);
518
- (0, import_react4.useEffect)(() => {
595
+ (0, import_react5.useEffect)(() => {
519
596
  if (eventsContainerRef.current) {
520
597
  eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
521
598
  }
522
599
  }, [connectionEvents]);
523
600
  const ephemeral = useEphemeralUserData(ephemeralUserData);
524
601
  const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
525
- (0, import_react4.useEffect)(() => {
602
+ (0, import_react5.useEffect)(() => {
526
603
  if (historyContainerRef.current) {
527
604
  historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
528
605
  }
529
606
  }, [historySnapshot]);
530
- (0, import_react4.useEffect)(() => {
607
+ (0, import_react5.useEffect)(() => {
531
608
  if (!historyContainerRef.current)
532
609
  return;
533
610
  const historyEntry = historyContainerRef.current.querySelector(
@@ -564,7 +641,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
564
641
  if (!didMount)
565
642
  return null;
566
643
  if (!showInspector) {
567
- return /* @__PURE__ */ import_react4.default.createElement(
644
+ return /* @__PURE__ */ import_react5.default.createElement(
568
645
  "div",
569
646
  {
570
647
  ...props,
@@ -576,7 +653,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
576
653
  },
577
654
  onClick: () => setShowInspector(true)
578
655
  },
579
- /* @__PURE__ */ import_react4.default.createElement(
656
+ /* @__PURE__ */ import_react5.default.createElement(
580
657
  ToggleButton,
581
658
  {
582
659
  showInspector,
@@ -587,7 +664,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
587
664
  )
588
665
  );
589
666
  }
590
- return /* @__PURE__ */ import_react4.default.createElement(
667
+ return /* @__PURE__ */ import_react5.default.createElement(
591
668
  "div",
592
669
  {
593
670
  ...props,
@@ -596,7 +673,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
596
673
  ...props.style
597
674
  }
598
675
  },
599
- /* @__PURE__ */ import_react4.default.createElement(
676
+ /* @__PURE__ */ import_react5.default.createElement(
600
677
  DisclosureSection,
601
678
  {
602
679
  isFirst: true,
@@ -608,7 +685,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
608
685
  flex: "0 0 auto",
609
686
  maxHeight: "200px"
610
687
  },
611
- right: /* @__PURE__ */ import_react4.default.createElement(
688
+ right: /* @__PURE__ */ import_react5.default.createElement(
612
689
  ToggleButton,
613
690
  {
614
691
  showInspector,
@@ -618,14 +695,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
618
695
  }
619
696
  )
620
697
  },
621
- /* @__PURE__ */ import_react4.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react4.default.createElement(
698
+ /* @__PURE__ */ import_react5.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react5.default.createElement(
622
699
  InspectorRow,
623
700
  {
624
701
  key: user.id,
625
702
  colorScheme,
626
703
  variant: user.id === userId ? "up" : void 0
627
704
  },
628
- user.image && /* @__PURE__ */ import_react4.default.createElement(
705
+ user.image && /* @__PURE__ */ import_react5.default.createElement(
629
706
  "img",
630
707
  {
631
708
  src: user.image,
@@ -646,7 +723,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
646
723
  " (",
647
724
  ellipsis(user.id.toString(), 8, "middle"),
648
725
  ")"
649
- )), !connectedUsers && /* @__PURE__ */ import_react4.default.createElement(
726
+ )), !connectedUsers && /* @__PURE__ */ import_react5.default.createElement(
650
727
  "div",
651
728
  {
652
729
  style: {
@@ -657,17 +734,17 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
657
734
  gap: "4px"
658
735
  }
659
736
  },
660
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No connected users")
737
+ /* @__PURE__ */ import_react5.default.createElement("span", null, "No connected users")
661
738
  ))
662
739
  ),
663
- /* @__PURE__ */ import_react4.default.createElement(
740
+ /* @__PURE__ */ import_react5.default.createElement(
664
741
  DisclosureSection,
665
742
  {
666
743
  title: "Data",
667
744
  colorScheme,
668
745
  setOpen: setShowData,
669
746
  open: showData,
670
- right: /* @__PURE__ */ import_react4.default.createElement(
747
+ right: /* @__PURE__ */ import_react5.default.createElement(
671
748
  "span",
672
749
  {
673
750
  style: {
@@ -675,7 +752,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
675
752
  gap: "4px"
676
753
  }
677
754
  },
678
- /* @__PURE__ */ import_react4.default.createElement(
755
+ /* @__PURE__ */ import_react5.default.createElement(
679
756
  SmallButton,
680
757
  {
681
758
  theme,
@@ -687,14 +764,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
687
764
  )
688
765
  )
689
766
  },
690
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
767
+ /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
691
768
  import_react_inspector.ObjectInspector,
692
769
  {
693
770
  name: multiplayerStateManager.schema ? "state" : void 0,
694
771
  data: state,
695
772
  theme
696
773
  }
697
- )), multiplayerStateManager.schema && /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
774
+ )), multiplayerStateManager.schema && /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
698
775
  import_react_inspector.ObjectInspector,
699
776
  {
700
777
  name: "schema",
@@ -703,14 +780,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
703
780
  }
704
781
  )))
705
782
  ),
706
- /* @__PURE__ */ import_react4.default.createElement(
783
+ /* @__PURE__ */ import_react5.default.createElement(
707
784
  DisclosureSection,
708
785
  {
709
786
  open: showHistory,
710
787
  setOpen: setShowHistory,
711
788
  title: "History",
712
789
  colorScheme,
713
- right: /* @__PURE__ */ import_react4.default.createElement(
790
+ right: /* @__PURE__ */ import_react5.default.createElement(
714
791
  "span",
715
792
  {
716
793
  style: {
@@ -718,7 +795,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
718
795
  gap: "4px"
719
796
  }
720
797
  },
721
- /* @__PURE__ */ import_react4.default.createElement(
798
+ /* @__PURE__ */ import_react5.default.createElement(
722
799
  SmallButton,
723
800
  {
724
801
  disabled: !historySnapshot.canUndo,
@@ -727,7 +804,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
727
804
  multiplayerStateManager.undo();
728
805
  }
729
806
  },
730
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
807
+ /* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
731
808
  "svg",
732
809
  {
733
810
  xmlns: "http://www.w3.org/2000/svg",
@@ -735,7 +812,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
735
812
  height: "1em",
736
813
  viewBox: "0 0 20 20"
737
814
  },
738
- /* @__PURE__ */ import_react4.default.createElement(
815
+ /* @__PURE__ */ import_react5.default.createElement(
739
816
  "path",
740
817
  {
741
818
  fill: "currentColor",
@@ -744,7 +821,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
744
821
  )
745
822
  ))
746
823
  ),
747
- /* @__PURE__ */ import_react4.default.createElement(
824
+ /* @__PURE__ */ import_react5.default.createElement(
748
825
  SmallButton,
749
826
  {
750
827
  disabled: !historySnapshot.canRedo,
@@ -753,7 +830,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
753
830
  multiplayerStateManager.redo();
754
831
  }
755
832
  },
756
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
833
+ /* @__PURE__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
757
834
  "svg",
758
835
  {
759
836
  xmlns: "http://www.w3.org/2000/svg",
@@ -761,7 +838,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
761
838
  height: "1em",
762
839
  viewBox: "0 0 20 20"
763
840
  },
764
- /* @__PURE__ */ import_react4.default.createElement(
841
+ /* @__PURE__ */ import_react5.default.createElement(
765
842
  "path",
766
843
  {
767
844
  fill: "currentColor",
@@ -772,7 +849,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
772
849
  )
773
850
  )
774
851
  },
775
- /* @__PURE__ */ import_react4.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(
852
+ /* @__PURE__ */ import_react5.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(
776
853
  "div",
777
854
  {
778
855
  id: `${HISTORY_ELEMENT_PREFIX}0`,
@@ -786,7 +863,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
786
863
  background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
787
864
  }
788
865
  },
789
- /* @__PURE__ */ import_react4.default.createElement(
866
+ /* @__PURE__ */ import_react5.default.createElement(
790
867
  "span",
791
868
  {
792
869
  style: {
@@ -798,7 +875,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
798
875
  },
799
876
  "Initial state"
800
877
  )
801
- ), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(
878
+ ), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react5.default.createElement(
802
879
  "div",
803
880
  {
804
881
  id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
@@ -809,7 +886,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
809
886
  background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
810
887
  }
811
888
  },
812
- entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react4.default.createElement(
889
+ entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react5.default.createElement(
813
890
  "pre",
814
891
  {
815
892
  key: j,
@@ -819,14 +896,14 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
819
896
  flexWrap: "wrap"
820
897
  }
821
898
  },
822
- 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 })),
823
- 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 })),
824
- 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))),
825
- 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)))
899
+ 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 })),
900
+ 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 })),
901
+ 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))),
902
+ 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)))
826
903
  ))
827
904
  )))
828
905
  ),
829
- /* @__PURE__ */ import_react4.default.createElement(
906
+ /* @__PURE__ */ import_react5.default.createElement(
830
907
  DisclosureSection,
831
908
  {
832
909
  title: "Tasks",
@@ -834,7 +911,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
834
911
  open: showTasks,
835
912
  setOpen: setShowTasks
836
913
  },
837
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react4.default.createElement(
914
+ /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react5.default.createElement(
838
915
  InspectorRow,
839
916
  {
840
917
  key: task.id,
@@ -843,7 +920,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
843
920
  backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
844
921
  }
845
922
  },
846
- /* @__PURE__ */ import_react4.default.createElement(
923
+ /* @__PURE__ */ import_react5.default.createElement(
847
924
  import_react_inspector.ObjectInspector,
848
925
  {
849
926
  name: task.name,
@@ -853,7 +930,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
853
930
  )
854
931
  )))
855
932
  ),
856
- /* @__PURE__ */ import_react4.default.createElement(
933
+ /* @__PURE__ */ import_react5.default.createElement(
857
934
  DisclosureSection,
858
935
  {
859
936
  open: showEphemeral,
@@ -861,7 +938,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
861
938
  title: "Ephemeral User Data",
862
939
  colorScheme
863
940
  },
864
- /* @__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(
941
+ /* @__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(
865
942
  import_react_inspector.ObjectInspector,
866
943
  {
867
944
  name: key,
@@ -871,7 +948,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
871
948
  }
872
949
  ))))
873
950
  ),
874
- /* @__PURE__ */ import_react4.default.createElement(
951
+ /* @__PURE__ */ import_react5.default.createElement(
875
952
  DisclosureSection,
876
953
  {
877
954
  open: showEvents,
@@ -879,8 +956,8 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
879
956
  title: "Events",
880
957
  colorScheme
881
958
  },
882
- /* @__PURE__ */ import_react4.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
883
- (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(
959
+ /* @__PURE__ */ import_react5.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
960
+ (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(
884
961
  InspectorRow,
885
962
  {
886
963
  key: index,
@@ -890,7 +967,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
890
967
  padding: "0px 12px 1px"
891
968
  }
892
969
  },
893
- /* @__PURE__ */ import_react4.default.createElement(
970
+ /* @__PURE__ */ import_react5.default.createElement(
894
971
  import_react_inspector.ObjectInspector,
895
972
  {
896
973
  data: event.message,
@@ -903,7 +980,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
903
980
  expanded
904
981
  }) => {
905
982
  const direction = event.type === "send" ? "up" : "down";
906
- return depth === 0 ? /* @__PURE__ */ import_react4.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react4.default.createElement(
983
+ return depth === 0 ? /* @__PURE__ */ import_react5.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react5.default.createElement(
907
984
  import_react_inspector.ObjectLabel,
908
985
  {
909
986
  direction,
@@ -916,7 +993,7 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
916
993
  }
917
994
  )
918
995
  )
919
- ), !connectionEvents && /* @__PURE__ */ import_react4.default.createElement(
996
+ ), !connectionEvents && /* @__PURE__ */ import_react5.default.createElement(
920
997
  "div",
921
998
  {
922
999
  style: {
@@ -927,18 +1004,18 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
927
1004
  gap: "4px"
928
1005
  }
929
1006
  },
930
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No recorded events")
1007
+ /* @__PURE__ */ import_react5.default.createElement("span", null, "No recorded events")
931
1008
  ))
932
1009
  )
933
1010
  );
934
1011
  });
935
1012
  var ObjectRootLabel = ({ name, data, direction }) => {
936
1013
  if (typeof name === "string") {
937
- 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 }));
1014
+ 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 }));
938
1015
  }
939
1016
  if (direction === "up" || direction === "down") {
940
1017
  const arrow = direction === "up" ? "\u2191" : "\u2193";
941
- return /* @__PURE__ */ import_react4.default.createElement("span", null, /* @__PURE__ */ import_react4.default.createElement(
1018
+ return /* @__PURE__ */ import_react5.default.createElement("span", null, /* @__PURE__ */ import_react5.default.createElement(
942
1019
  "span",
943
1020
  {
944
1021
  style: {
@@ -955,9 +1032,9 @@ var ObjectRootLabel = ({ name, data, direction }) => {
955
1032
  }
956
1033
  },
957
1034
  arrow
958
- ), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
1035
+ ), /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data }));
959
1036
  } else {
960
- return /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data });
1037
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data });
961
1038
  }
962
1039
  };
963
1040
  function Arrow({
@@ -965,7 +1042,7 @@ function Arrow({
965
1042
  onClick,
966
1043
  style
967
1044
  }) {
968
- return /* @__PURE__ */ import_react4.default.createElement(
1045
+ return /* @__PURE__ */ import_react5.default.createElement(
969
1046
  "span",
970
1047
  {
971
1048
  role: "button",
@@ -1008,7 +1085,7 @@ function SmallButton({
1008
1085
  theme,
1009
1086
  disabled
1010
1087
  }) {
1011
- return /* @__PURE__ */ import_react4.default.createElement(
1088
+ return /* @__PURE__ */ import_react5.default.createElement(
1012
1089
  "button",
1013
1090
  {
1014
1091
  type: "button",
@@ -1057,8 +1134,8 @@ function useStateInspector({
1057
1134
  ephemeralUserData,
1058
1135
  forceInit
1059
1136
  }) {
1060
- const [root, setRoot] = import_react5.default.useState(null);
1061
- (0, import_react5.useLayoutEffect)(() => {
1137
+ const [root, setRoot] = import_react6.default.useState(null);
1138
+ (0, import_react6.useLayoutEffect)(() => {
1062
1139
  if (disabled)
1063
1140
  return;
1064
1141
  const portalElement = createPortalElement();
@@ -1069,11 +1146,11 @@ function useStateInspector({
1069
1146
  document.body.removeChild(portalElement);
1070
1147
  };
1071
1148
  }, [disabled]);
1072
- (0, import_react5.useLayoutEffect)(() => {
1149
+ (0, import_react6.useLayoutEffect)(() => {
1073
1150
  if (!root)
1074
1151
  return;
1075
1152
  root.render(
1076
- /* @__PURE__ */ import_react5.default.createElement(
1153
+ /* @__PURE__ */ import_react6.default.createElement(
1077
1154
  StateInspector,
1078
1155
  {
1079
1156
  state,
@@ -1106,22 +1183,22 @@ function useStateInspector({
1106
1183
 
1107
1184
  // src/hooks.ts
1108
1185
  function useSyncStateManager(stateManager, path) {
1109
- const getSnapshot = (0, import_react6.useCallback)(
1186
+ const getSnapshot = (0, import_react7.useCallback)(
1110
1187
  () => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
1111
1188
  [stateManager, path]
1112
1189
  );
1113
- return (0, import_react6.useSyncExternalStore)(
1190
+ return (0, import_react7.useSyncExternalStore)(
1114
1191
  stateManager.addListener,
1115
1192
  getSnapshot,
1116
1193
  getSnapshot
1117
1194
  );
1118
1195
  }
1119
1196
  function useManagedState(createInitialState, options) {
1120
- const [stateManager] = (0, import_react6.useState)(
1121
- () => new import_state_manager.StateManager(createInitialState(), options)
1197
+ const [stateManager] = (0, import_react7.useState)(
1198
+ () => new import_state_manager2.StateManager(createInitialState(), options)
1122
1199
  );
1123
1200
  const state = useSyncStateManager(stateManager);
1124
- const setState = (0, import_react6.useCallback)(
1201
+ const setState = (0, import_react7.useCallback)(
1125
1202
  (...args) => {
1126
1203
  const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
1127
1204
  if (metadata === void 0) {
@@ -1157,41 +1234,41 @@ function useManagedState(createInitialState, options) {
1157
1234
  return [state, setState, stateManager];
1158
1235
  }
1159
1236
  function useManagedHistory(stateManager) {
1160
- return (0, import_react6.useSyncExternalStore)(
1237
+ return (0, import_react7.useSyncExternalStore)(
1161
1238
  stateManager.historyEmittor.addListener,
1162
1239
  stateManager.getHistorySnapshot,
1163
1240
  stateManager.getHistorySnapshot
1164
1241
  );
1165
1242
  }
1166
1243
  function useSyncMultiplayerStateManager(multiplayerStateManager) {
1167
- return (0, import_react6.useSyncExternalStore)(
1244
+ return (0, import_react7.useSyncExternalStore)(
1168
1245
  multiplayerStateManager.addListener,
1169
1246
  multiplayerStateManager.getOptimisticState,
1170
1247
  multiplayerStateManager.getOptimisticState
1171
1248
  );
1172
1249
  }
1173
1250
  function useEphemeralUserData(ephemeralUserData) {
1174
- return (0, import_react6.useSyncExternalStore)(
1251
+ return (0, import_react7.useSyncExternalStore)(
1175
1252
  ephemeralUserData.addListener,
1176
1253
  ephemeralUserData.getSnapshot,
1177
1254
  ephemeralUserData.getSnapshot
1178
1255
  );
1179
1256
  }
1180
- var defaultStubSync = (0, import_state_manager.stubSync)();
1257
+ var defaultStubSync = (0, import_state_manager2.stubSync)();
1181
1258
  function useMultiplayerState(initialState, options) {
1182
1259
  const { sync = defaultStubSync, ...rest } = options ?? {};
1183
- const [multiplayerStateManager] = (0, import_react6.useState)(
1184
- () => new import_state_manager.MultiplayerStateManager(initialState, rest)
1260
+ const [multiplayerStateManager] = (0, import_react7.useState)(
1261
+ () => new import_state_manager2.MultiplayerStateManager(initialState, rest)
1185
1262
  );
1186
- const syncRef = (0, import_react6.useRef)(sync);
1187
- const [connectionEvents, setConnectionEvents] = (0, import_react6.useState)();
1188
- const [connectedUsers, setConnectedUsers] = (0, import_react6.useState)([]);
1189
- const [ephemeralUserData] = (0, import_react6.useState)(
1190
- () => new import_state_manager.EphemeralUserData()
1263
+ const syncRef = (0, import_react7.useRef)(sync);
1264
+ const [connectionEvents, setConnectionEvents] = (0, import_react7.useState)();
1265
+ const [connectedUsers, setConnectedUsers] = (0, import_react7.useState)([]);
1266
+ const [ephemeralUserData] = (0, import_react7.useState)(
1267
+ () => new import_state_manager2.EphemeralUserData()
1191
1268
  );
1192
- const [tasks, setTasks] = (0, import_react6.useState)([]);
1193
- const [userId, setUserId] = (0, import_react6.useState)();
1194
- const extras = (0, import_react6.useMemo)(() => {
1269
+ const [tasks, setTasks] = (0, import_react7.useState)([]);
1270
+ const [userId, setUserId] = (0, import_react7.useState)();
1271
+ const extras = (0, import_react7.useMemo)(() => {
1195
1272
  return {
1196
1273
  tasks,
1197
1274
  userId,
@@ -1210,22 +1287,22 @@ function useMultiplayerState(initialState, options) {
1210
1287
  const globalTrackTasks = useObservable(shouldTrackTasks$);
1211
1288
  const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;
1212
1289
  const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;
1213
- const trackEventsCallbackRef = (0, import_react6.useRef)();
1214
- const trackConnectedUsersCallbackRef = (0, import_react6.useRef)();
1215
- const trackTasksCallbackRef = (0, import_react6.useRef)();
1216
- (0, import_react6.useEffect)(() => {
1290
+ const trackEventsCallbackRef = (0, import_react7.useRef)();
1291
+ const trackConnectedUsersCallbackRef = (0, import_react7.useRef)();
1292
+ const trackTasksCallbackRef = (0, import_react7.useRef)();
1293
+ (0, import_react7.useEffect)(() => {
1217
1294
  trackEventsCallbackRef.current = shouldTrackEvents ? (e) => setConnectionEvents((events) => {
1218
1295
  const updated = events ? [...events, e] : [e];
1219
1296
  return updated.length > 50 ? updated.slice(-50) : updated;
1220
1297
  }) : void 0;
1221
1298
  }, [shouldTrackEvents]);
1222
- (0, import_react6.useEffect)(() => {
1299
+ (0, import_react7.useEffect)(() => {
1223
1300
  trackConnectedUsersCallbackRef.current = (users, userId2) => {
1224
1301
  setConnectedUsers(users);
1225
1302
  setUserId(userId2);
1226
1303
  };
1227
1304
  }, []);
1228
- (0, import_react6.useEffect)(() => {
1305
+ (0, import_react7.useEffect)(() => {
1229
1306
  trackTasksCallbackRef.current = shouldTrackTasks ? (tasks2) => {
1230
1307
  setTasks((old) => {
1231
1308
  const newIds = new Set(tasks2.map((t) => t.id));
@@ -1234,7 +1311,7 @@ function useMultiplayerState(initialState, options) {
1234
1311
  });
1235
1312
  } : void 0;
1236
1313
  }, [shouldTrackTasks]);
1237
- (0, import_react6.useEffect)(() => {
1314
+ (0, import_react7.useEffect)(() => {
1238
1315
  if (syncRef.current) {
1239
1316
  return syncRef.current({
1240
1317
  ms: multiplayerStateManager,
@@ -1246,7 +1323,7 @@ function useMultiplayerState(initialState, options) {
1246
1323
  }
1247
1324
  }, [ephemeralUserData, multiplayerStateManager]);
1248
1325
  const state = useSyncMultiplayerStateManager(multiplayerStateManager);
1249
- const forceInit = (0, import_react6.useCallback)(() => {
1326
+ const forceInit = (0, import_react7.useCallback)(() => {
1250
1327
  const state2 = typeof initialState === "function" ? initialState() : initialState;
1251
1328
  const schema = options?.schema;
1252
1329
  multiplayerStateManager.sm.clearHistory();
@@ -1264,6 +1341,7 @@ function useMultiplayerState(initialState, options) {
1264
1341
  disabled: !options?.inspector,
1265
1342
  ...typeof options?.inspector === "object" && options.inspector
1266
1343
  });
1344
+ useBroadcastConnectedUsers(connectedUsers);
1267
1345
  return [
1268
1346
  state,
1269
1347
  multiplayerStateManager.setState,
@@ -1279,12 +1357,18 @@ function useMultiplayerState(initialState, options) {
1279
1357
  UserPointerContainer,
1280
1358
  UserPointerIcon,
1281
1359
  UserPointersOverlay,
1360
+ createDefaultAppData,
1361
+ getAppData,
1282
1362
  getAvatarInitials,
1283
1363
  getAvatarStyle,
1364
+ isEmbeddedApp,
1365
+ useBroadcastConnectedUsers,
1366
+ useBroadcastMenuItems,
1284
1367
  useEphemeralUserData,
1285
1368
  useManagedHistory,
1286
1369
  useManagedState,
1287
1370
  useMultiplayerState,
1371
+ useNoyaApp,
1288
1372
  useSyncMultiplayerStateManager,
1289
1373
  useSyncStateManager,
1290
1374
  ...require("@noya-app/state-manager")