@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/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
- useNoyaApp: () => useNoyaApp,
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 import_state_manager2 = require("@noya-app/state-manager");
323
- var import_react7 = require("react");
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 import_react6 = __toESM(require("react"));
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 import_react5 = __toESM(require("react"));
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 import_react4 = __toESM(require("react"));
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] = import_react4.default.useState(() => {
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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, import_react5.memo)(function StateInspector2({
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] = import_react5.default.useState(false);
556
- (0, import_react5.useLayoutEffect)(() => {
485
+ const [didMount, setDidMount] = import_react4.default.useState(false);
486
+ (0, import_react4.useLayoutEffect)(() => {
557
487
  setDidMount(true);
558
488
  }, []);
559
- const eventsContainerRef = import_react5.default.useRef(null);
560
- const historyContainerRef = import_react5.default.useRef(null);
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, import_react5.useEffect)(() => {
519
+ (0, import_react4.useEffect)(() => {
590
520
  shouldTrackEvents$.set(showEvents);
591
521
  }, [showEvents]);
592
- (0, import_react5.useEffect)(() => {
522
+ (0, import_react4.useEffect)(() => {
593
523
  shouldTrackTasks$.set(showTasks);
594
524
  }, [showTasks]);
595
- (0, import_react5.useEffect)(() => {
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, import_react5.useEffect)(() => {
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, import_react5.useEffect)(() => {
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", null, "No connected users")
667
+ /* @__PURE__ */ import_react4.default.createElement("span", null, "No connected users")
738
668
  ))
739
669
  ),
740
- /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react5.default.createElement(
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__ */ 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)))
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ 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(
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__ */ import_react5.default.createElement(
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__ */ 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(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement("span", null, "No recorded events")
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__ */ 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 }));
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__ */ import_react5.default.createElement("span", null, /* @__PURE__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data }));
976
+ ), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
1036
977
  } else {
1037
- return /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectPreview, { data });
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__ */ import_react5.default.createElement(
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__ */ import_react5.default.createElement(
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] = import_react6.default.useState(null);
1138
- (0, import_react6.useLayoutEffect)(() => {
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, import_react6.useLayoutEffect)(() => {
1090
+ (0, import_react5.useLayoutEffect)(() => {
1150
1091
  if (!root)
1151
1092
  return;
1152
1093
  root.render(
1153
- /* @__PURE__ */ import_react6.default.createElement(
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, import_react7.useCallback)(
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, import_react7.useSyncExternalStore)(
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, import_react7.useState)(
1198
- () => new import_state_manager2.StateManager(createInitialState(), options)
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, import_react7.useCallback)(
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, import_react7.useSyncExternalStore)(
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, import_react7.useSyncExternalStore)(
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, import_react7.useSyncExternalStore)(
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, import_state_manager2.stubSync)();
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, import_react7.useState)(
1261
- () => new import_state_manager2.MultiplayerStateManager(initialState, rest)
1201
+ const [multiplayerStateManager] = (0, import_react6.useState)(
1202
+ () => new import_state_manager.MultiplayerStateManager(initialState, rest)
1262
1203
  );
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()
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, import_react7.useState)([]);
1270
- const [userId, setUserId] = (0, import_react7.useState)();
1271
- const extras = (0, import_react7.useMemo)(() => {
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
- }, [tasks, connectionEvents, connectedUsers, ephemeralUserData, userId]);
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, import_react7.useRef)();
1291
- const trackConnectedUsersCallbackRef = (0, import_react7.useRef)();
1292
- const trackTasksCallbackRef = (0, import_react7.useRef)();
1293
- (0, import_react7.useEffect)(() => {
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, import_react7.useEffect)(() => {
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, import_react7.useEffect)(() => {
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, import_react7.useEffect)(() => {
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, import_react7.useCallback)(() => {
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
- useBroadcastConnectedUsers(connectedUsers);
1345
- return [
1346
- state,
1347
- multiplayerStateManager.setState,
1348
- multiplayerStateManager,
1349
- extras
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
- useNoyaApp,
1412
+ useNoyaAppState,
1372
1413
  useSyncMultiplayerStateManager,
1373
1414
  useSyncStateManager,
1374
1415
  ...require("@noya-app/state-manager")