@noya-app/noya-multiplayer-react 0.1.21 → 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.
@@ -5,14 +5,14 @@
5
5
  CLI Target: esnext
6
6
  CJS Build start
7
7
  ESM Build start
8
- CJS dist/index.js 42.34 KB
9
- CJS dist/index.js.map 67.91 KB
10
- CJS ⚡️ Build success in 46ms
11
- ESM dist/index.mjs 37.54 KB
12
- ESM dist/index.mjs.map 68.07 KB
13
- ESM ⚡️ Build success in 46ms
8
+ ESM dist/index.mjs 40.89 KB
9
+ ESM dist/index.mjs.map 75.66 KB
10
+ ESM ⚡️ Build success in 49ms
11
+ CJS dist/index.js 46.11 KB
12
+ CJS dist/index.js.map 75.44 KB
13
+ CJS ⚡️ Build success in 49ms
14
14
  DTS Build start
15
15
  "ComponentPropsWithoutRef" is imported from external module "react" but never used in "src/components/UserPointersOverlay.tsx", "src/inspector/StateInspector.tsx" and "src/hooks.ts".
16
- DTS ⚡️ Build success in 3045ms
17
- DTS dist/index.d.ts 4.71 KB
18
- DTS dist/index.d.mts 4.71 KB
16
+ DTS ⚡️ Build success in 2229ms
17
+ DTS dist/index.d.ts 7.15 KB
18
+ DTS dist/index.d.mts 7.15 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @noya-app/state-manager
2
2
 
3
+ ## 0.1.23
4
+
5
+ ### Patch Changes
6
+
7
+ - 3d308c6: Improve noya app hook
8
+ - f14970a: Add useNoyaAppState
9
+ - Updated dependencies [f14970a]
10
+ - @noya-app/state-manager@0.1.22
11
+
12
+ ## 0.1.22
13
+
14
+ ### Patch Changes
15
+
16
+ - 7306000: Improve embedded apis
17
+ - Updated dependencies [7306000]
18
+ - @noya-app/state-manager@0.1.21
19
+
3
20
  ## 0.1.21
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _noya_app_state_manager from '@noya-app/state-manager';
2
- import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions } from '@noya-app/state-manager';
2
+ import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema } from '@noya-app/state-manager';
3
3
  export * from '@noya-app/state-manager';
4
- import React, { SetStateAction, ComponentProps } from 'react';
4
+ import React, { SetStateAction } from 'react';
5
5
 
6
6
  declare function getAvatarInitials(name: string): string;
7
7
  /**
@@ -45,7 +45,11 @@ declare const UserPointerIcon: React.NamedExoticComponent<{
45
45
  color?: string | undefined;
46
46
  }>;
47
47
 
48
- type Anchor = "left" | "right" | "bottom left" | "bottom right";
48
+ type StateInspectorAnchor = "left" | "right" | "bottom left" | "bottom right";
49
+ type StateInspectorOptions = {
50
+ colorScheme?: "light" | "dark";
51
+ anchor?: StateInspectorAnchor;
52
+ };
49
53
  declare const StateInspector: React.MemoExoticComponent<(<S extends object, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, ephemeralUserData, anchor, forceInit, ...props }: {
50
54
  state: S;
51
55
  connectionEvents?: ConnectionEvent<S>[] | undefined;
@@ -53,12 +57,10 @@ declare const StateInspector: React.MemoExoticComponent<(<S extends object, M, E
53
57
  tasks?: Task[] | undefined;
54
58
  userId?: string | undefined;
55
59
  unstyled?: boolean | undefined;
56
- colorScheme?: "light" | "dark" | undefined;
57
60
  multiplayerStateManager: MultiplayerStateManager<S, M>;
58
61
  ephemeralUserData: EphemeralUserData<E>;
59
- anchor?: Anchor | undefined;
60
62
  forceInit: () => void;
61
- } & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
63
+ } & StateInspectorOptions & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
62
64
 
63
65
  declare function useSyncStateManager<S extends object, M>(stateManager: StateManager<S, M>): S;
64
66
  declare function useSyncStateManager<S extends object, M, P extends string>(stateManager: StateManager<S, M>, path: P): Get<S, P, unknown>;
@@ -70,20 +72,71 @@ declare function useEphemeralUserData<E>(ephemeralUserData: EphemeralUserData<E>
70
72
  metadata: Record<string, _noya_app_state_manager.EphemeralUserMetadata | undefined>;
71
73
  currentUserId: string | undefined;
72
74
  };
73
- declare function useMultiplayerState<S extends object, M = void, E = void>(initialState: S | (() => S), options?: MultiplayerStateManagerOptions<S, M> & {
74
- sync?: (options: {
75
- ms: MultiplayerStateManager<S, M>;
76
- ephemeralUserData: EphemeralUserData<E>;
77
- }) => void;
75
+ type UseMultiplayerStateOptions<S extends object, M = void, E = void> = MultiplayerStateManagerOptions<S, M> & {
76
+ sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData">) => void;
78
77
  trackConnectionEvents?: boolean;
79
78
  trackTasks?: boolean;
80
- inspector?: boolean | Pick<ComponentProps<typeof StateInspector>, "colorScheme" | "anchor">;
81
- }): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, MultiplayerStateManager<S, M>, {
79
+ inspector?: boolean | StateInspectorOptions;
80
+ };
81
+ declare function useMultiplayerState<S extends object, M = void, E = void>(initialState: S | (() => S), options?: UseMultiplayerStateOptions<S, M, E>): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, {
82
82
  tasks: Task[];
83
83
  userId: string | undefined;
84
84
  connectionEvents: ConnectionEvent<S>[] | undefined;
85
85
  connectedUsers: MultiplayerUser[];
86
86
  ephemeralUserData: EphemeralUserData<E>;
87
+ multiplayerStateManager: MultiplayerStateManager<S, M>;
88
+ }];
89
+
90
+ type AppViewType = "editable" | "readOnly" | "preview";
91
+ type AppTheme = "light" | "dark";
92
+ type AppData<State> = {
93
+ multiplayerUrl?: string;
94
+ theme: AppTheme;
95
+ viewType: AppViewType;
96
+ initialState: State;
97
+ inspector: boolean | StateInspectorOptions;
98
+ };
99
+ declare function createDefaultAppData<State>(initialState: State): AppData<State>;
100
+ declare function getAppData<State>(): AppData<State> | undefined;
101
+ declare function getAppData<State>(initialState: State): AppData<State>;
102
+ type AppDataOptions = {
103
+ schema?: TSchema;
104
+ };
105
+ /**
106
+ * Get data from host app. Fall back to default data.
107
+ */
108
+ declare function useAppData<S extends object>(initialState: S, { schema }?: AppDataOptions): AppData<S>;
109
+ type IframeToHostMessage = {
110
+ type: "application.setMenuItems";
111
+ payload: {
112
+ menuItems: any[];
113
+ };
114
+ } | {
115
+ type: "multiplayer.setUsers";
116
+ payload: {
117
+ users: any[];
118
+ };
119
+ };
120
+ type HostToIframeMessage = {
121
+ type: "application.selectMenuItem";
122
+ payload: {
123
+ value: string;
124
+ };
125
+ };
126
+ declare function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]): void;
127
+ declare function useBroadcastMenuItems<T>(menuItems: any[], handleSelectMenuItem: (value: T) => void): void;
128
+ declare function isEmbeddedApp(): boolean;
129
+ declare function useNoyaAppState<S extends object, M = void, E = void>(initialState: S | (() => S), options: UseMultiplayerStateOptions<S, M, E> & {
130
+ localStorageKey?: string;
131
+ }): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, {
132
+ readonly theme: AppTheme;
133
+ readonly viewType: AppViewType;
134
+ readonly tasks: _noya_app_state_manager.Task[];
135
+ readonly userId: string | undefined;
136
+ readonly connectionEvents: _noya_app_state_manager.ConnectionEvent<S>[] | undefined;
137
+ readonly connectedUsers: MultiplayerUser[];
138
+ readonly ephemeralUserData: _noya_app_state_manager.EphemeralUserData<E>;
139
+ readonly multiplayerStateManager: _noya_app_state_manager.MultiplayerStateManager<S, M>;
87
140
  }];
88
141
 
89
- export { StateInspector, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, getAvatarInitials, getAvatarStyle, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useSyncMultiplayerStateManager, useSyncStateManager };
142
+ export { type AppData, type AppTheme, type AppViewType, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, createDefaultAppData, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, useAppData, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaAppState, useSyncMultiplayerStateManager, useSyncStateManager };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _noya_app_state_manager from '@noya-app/state-manager';
2
- import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions } from '@noya-app/state-manager';
2
+ import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema } from '@noya-app/state-manager';
3
3
  export * from '@noya-app/state-manager';
4
- import React, { SetStateAction, ComponentProps } from 'react';
4
+ import React, { SetStateAction } from 'react';
5
5
 
6
6
  declare function getAvatarInitials(name: string): string;
7
7
  /**
@@ -45,7 +45,11 @@ declare const UserPointerIcon: React.NamedExoticComponent<{
45
45
  color?: string | undefined;
46
46
  }>;
47
47
 
48
- type Anchor = "left" | "right" | "bottom left" | "bottom right";
48
+ type StateInspectorAnchor = "left" | "right" | "bottom left" | "bottom right";
49
+ type StateInspectorOptions = {
50
+ colorScheme?: "light" | "dark";
51
+ anchor?: StateInspectorAnchor;
52
+ };
49
53
  declare const StateInspector: React.MemoExoticComponent<(<S extends object, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, ephemeralUserData, anchor, forceInit, ...props }: {
50
54
  state: S;
51
55
  connectionEvents?: ConnectionEvent<S>[] | undefined;
@@ -53,12 +57,10 @@ declare const StateInspector: React.MemoExoticComponent<(<S extends object, M, E
53
57
  tasks?: Task[] | undefined;
54
58
  userId?: string | undefined;
55
59
  unstyled?: boolean | undefined;
56
- colorScheme?: "light" | "dark" | undefined;
57
60
  multiplayerStateManager: MultiplayerStateManager<S, M>;
58
61
  ephemeralUserData: EphemeralUserData<E>;
59
- anchor?: Anchor | undefined;
60
62
  forceInit: () => void;
61
- } & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
63
+ } & StateInspectorOptions & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
62
64
 
63
65
  declare function useSyncStateManager<S extends object, M>(stateManager: StateManager<S, M>): S;
64
66
  declare function useSyncStateManager<S extends object, M, P extends string>(stateManager: StateManager<S, M>, path: P): Get<S, P, unknown>;
@@ -70,20 +72,71 @@ declare function useEphemeralUserData<E>(ephemeralUserData: EphemeralUserData<E>
70
72
  metadata: Record<string, _noya_app_state_manager.EphemeralUserMetadata | undefined>;
71
73
  currentUserId: string | undefined;
72
74
  };
73
- declare function useMultiplayerState<S extends object, M = void, E = void>(initialState: S | (() => S), options?: MultiplayerStateManagerOptions<S, M> & {
74
- sync?: (options: {
75
- ms: MultiplayerStateManager<S, M>;
76
- ephemeralUserData: EphemeralUserData<E>;
77
- }) => void;
75
+ type UseMultiplayerStateOptions<S extends object, M = void, E = void> = MultiplayerStateManagerOptions<S, M> & {
76
+ sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData">) => void;
78
77
  trackConnectionEvents?: boolean;
79
78
  trackTasks?: boolean;
80
- inspector?: boolean | Pick<ComponentProps<typeof StateInspector>, "colorScheme" | "anchor">;
81
- }): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, MultiplayerStateManager<S, M>, {
79
+ inspector?: boolean | StateInspectorOptions;
80
+ };
81
+ declare function useMultiplayerState<S extends object, M = void, E = void>(initialState: S | (() => S), options?: UseMultiplayerStateOptions<S, M, E>): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, {
82
82
  tasks: Task[];
83
83
  userId: string | undefined;
84
84
  connectionEvents: ConnectionEvent<S>[] | undefined;
85
85
  connectedUsers: MultiplayerUser[];
86
86
  ephemeralUserData: EphemeralUserData<E>;
87
+ multiplayerStateManager: MultiplayerStateManager<S, M>;
88
+ }];
89
+
90
+ type AppViewType = "editable" | "readOnly" | "preview";
91
+ type AppTheme = "light" | "dark";
92
+ type AppData<State> = {
93
+ multiplayerUrl?: string;
94
+ theme: AppTheme;
95
+ viewType: AppViewType;
96
+ initialState: State;
97
+ inspector: boolean | StateInspectorOptions;
98
+ };
99
+ declare function createDefaultAppData<State>(initialState: State): AppData<State>;
100
+ declare function getAppData<State>(): AppData<State> | undefined;
101
+ declare function getAppData<State>(initialState: State): AppData<State>;
102
+ type AppDataOptions = {
103
+ schema?: TSchema;
104
+ };
105
+ /**
106
+ * Get data from host app. Fall back to default data.
107
+ */
108
+ declare function useAppData<S extends object>(initialState: S, { schema }?: AppDataOptions): AppData<S>;
109
+ type IframeToHostMessage = {
110
+ type: "application.setMenuItems";
111
+ payload: {
112
+ menuItems: any[];
113
+ };
114
+ } | {
115
+ type: "multiplayer.setUsers";
116
+ payload: {
117
+ users: any[];
118
+ };
119
+ };
120
+ type HostToIframeMessage = {
121
+ type: "application.selectMenuItem";
122
+ payload: {
123
+ value: string;
124
+ };
125
+ };
126
+ declare function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]): void;
127
+ declare function useBroadcastMenuItems<T>(menuItems: any[], handleSelectMenuItem: (value: T) => void): void;
128
+ declare function isEmbeddedApp(): boolean;
129
+ declare function useNoyaAppState<S extends object, M = void, E = void>(initialState: S | (() => S), options: UseMultiplayerStateOptions<S, M, E> & {
130
+ localStorageKey?: string;
131
+ }): readonly [S, (...args: M extends {} ? [metadata: M, action: S | ((prevState: S) => S)] : [action: S | ((prevState: S) => S)]) => void, {
132
+ readonly theme: AppTheme;
133
+ readonly viewType: AppViewType;
134
+ readonly tasks: _noya_app_state_manager.Task[];
135
+ readonly userId: string | undefined;
136
+ readonly connectionEvents: _noya_app_state_manager.ConnectionEvent<S>[] | undefined;
137
+ readonly connectedUsers: MultiplayerUser[];
138
+ readonly ephemeralUserData: _noya_app_state_manager.EphemeralUserData<E>;
139
+ readonly multiplayerStateManager: _noya_app_state_manager.MultiplayerStateManager<S, M>;
87
140
  }];
88
141
 
89
- export { StateInspector, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, getAvatarInitials, getAvatarStyle, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useSyncMultiplayerStateManager, useSyncStateManager };
142
+ export { type AppData, type AppTheme, type AppViewType, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, createDefaultAppData, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, useAppData, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaAppState, useSyncMultiplayerStateManager, useSyncStateManager };
package/dist/index.js CHANGED
@@ -37,12 +37,19 @@ __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
+ useAppData: () => useAppData,
46
+ useBroadcastConnectedUsers: () => useBroadcastConnectedUsers,
47
+ useBroadcastMenuItems: () => useBroadcastMenuItems,
42
48
  useEphemeralUserData: () => useEphemeralUserData,
43
49
  useManagedHistory: () => useManagedHistory,
44
50
  useManagedState: () => useManagedState,
45
51
  useMultiplayerState: () => useMultiplayerState,
52
+ useNoyaAppState: () => useNoyaAppState,
46
53
  useSyncMultiplayerStateManager: () => useSyncMultiplayerStateManager,
47
54
  useSyncStateManager: () => useSyncStateManager
48
55
  });
@@ -809,6 +816,17 @@ var StateInspector = (0, import_react4.memo)(function StateInspector2({
809
816
  background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
810
817
  }
811
818
  },
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
+ ),
812
830
  entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react4.default.createElement(
813
831
  "pre",
814
832
  {
@@ -1197,7 +1215,8 @@ function useMultiplayerState(initialState, options) {
1197
1215
  userId,
1198
1216
  connectionEvents,
1199
1217
  connectedUsers,
1200
- ephemeralUserData
1218
+ ephemeralUserData,
1219
+ multiplayerStateManager
1201
1220
  // evaluate: async (code: string) => {
1202
1221
  // const payload = await rpcManager.request({ type: "eval", code });
1203
1222
  // if (payload.type !== "eval") {
@@ -1205,7 +1224,14 @@ function useMultiplayerState(initialState, options) {
1205
1224
  // }
1206
1225
  // },
1207
1226
  };
1208
- }, [tasks, connectionEvents, connectedUsers, ephemeralUserData, userId]);
1227
+ }, [
1228
+ tasks,
1229
+ userId,
1230
+ connectionEvents,
1231
+ connectedUsers,
1232
+ ephemeralUserData,
1233
+ multiplayerStateManager
1234
+ ]);
1209
1235
  const globalTrackEvents = useObservable(shouldTrackEvents$);
1210
1236
  const globalTrackTasks = useObservable(shouldTrackTasks$);
1211
1237
  const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;
@@ -1264,12 +1290,104 @@ function useMultiplayerState(initialState, options) {
1264
1290
  disabled: !options?.inspector,
1265
1291
  ...typeof options?.inspector === "object" && options.inspector
1266
1292
  });
1267
- return [
1268
- state,
1269
- multiplayerStateManager.setState,
1270
- multiplayerStateManager,
1271
- extras
1272
- ];
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];
1273
1391
  }
1274
1392
  // Annotate the CommonJS export names for ESM import in node:
1275
1393
  0 && (module.exports = {
@@ -1279,12 +1397,19 @@ function useMultiplayerState(initialState, options) {
1279
1397
  UserPointerContainer,
1280
1398
  UserPointerIcon,
1281
1399
  UserPointersOverlay,
1400
+ createDefaultAppData,
1401
+ getAppData,
1282
1402
  getAvatarInitials,
1283
1403
  getAvatarStyle,
1404
+ isEmbeddedApp,
1405
+ useAppData,
1406
+ useBroadcastConnectedUsers,
1407
+ useBroadcastMenuItems,
1284
1408
  useEphemeralUserData,
1285
1409
  useManagedHistory,
1286
1410
  useManagedState,
1287
1411
  useMultiplayerState,
1412
+ useNoyaAppState,
1288
1413
  useSyncMultiplayerStateManager,
1289
1414
  useSyncStateManager,
1290
1415
  ...require("@noya-app/state-manager")