@noya-app/noya-multiplayer-react 0.1.40 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +14 -13
- package/CHANGELOG.md +15 -0
- package/dist/index.bundle.js +7 -7
- package/dist/index.d.mts +206 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/inspector/StateInspector.tsx +5 -3
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import * as _noya_app_state_manager from '@noya-app/state-manager';
|
|
2
|
+
import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, AssetManager, StateManager, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema, Static } from '@noya-app/state-manager';
|
|
3
|
+
export * from '@noya-app/state-manager';
|
|
4
|
+
import React, { ComponentPropsWithoutRef, SetStateAction } from 'react';
|
|
5
|
+
import { GetAtPath, ObservableOptions, PathKey, Observable } from '@noya-app/observable';
|
|
6
|
+
|
|
7
|
+
declare function getAvatarInitials(name: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Create a background color and initials from a name
|
|
10
|
+
*
|
|
11
|
+
* Adapted from https://mui.com/material-ui/react-avatar/
|
|
12
|
+
*/
|
|
13
|
+
declare function getAvatarStyle(name: string): {
|
|
14
|
+
color: string;
|
|
15
|
+
backgroundColor: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type Point = {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
};
|
|
22
|
+
type UserPointerData = {
|
|
23
|
+
pointer?: Point;
|
|
24
|
+
};
|
|
25
|
+
type UserPointerProps<E extends UserPointerData> = {
|
|
26
|
+
user: MultiplayerUser;
|
|
27
|
+
ephemeralUserData: EphemeralUserData<E>;
|
|
28
|
+
hideAfter?: number;
|
|
29
|
+
};
|
|
30
|
+
declare const UserPointer_: <E extends UserPointerData>({ user, ephemeralUserData, hideAfter, }: UserPointerProps<E>) => React.JSX.Element | null;
|
|
31
|
+
declare const UserPointer: typeof UserPointer_;
|
|
32
|
+
declare const UserPointerContainer: React.NamedExoticComponent<{
|
|
33
|
+
point: Point;
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
show?: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
declare const UserNameTag: React.NamedExoticComponent<{
|
|
38
|
+
background: string;
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
}>;
|
|
41
|
+
type UserPointersOverlayProps<E extends UserPointerData> = {
|
|
42
|
+
connectedUsers: MultiplayerUser[];
|
|
43
|
+
ephemeralUserData: EphemeralUserData<E>;
|
|
44
|
+
};
|
|
45
|
+
declare const UserPointersOverlay: React.MemoExoticComponent<(<E extends UserPointerData>({ connectedUsers, ephemeralUserData }: UserPointersOverlayProps<E>) => React.JSX.Element)>;
|
|
46
|
+
declare const UserPointerIcon: React.NamedExoticComponent<{
|
|
47
|
+
color?: string;
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
type StateInspectorAnchor = "left" | "right" | "bottom left" | "bottom right";
|
|
51
|
+
type StateInspectorOptions = {
|
|
52
|
+
colorScheme?: "light" | "dark";
|
|
53
|
+
anchor?: StateInspectorAnchor;
|
|
54
|
+
};
|
|
55
|
+
declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, assetManager, ephemeralUserData, anchor, forceInit, ...props }: {
|
|
56
|
+
state: S;
|
|
57
|
+
connectionEvents?: ConnectionEvent<S>[];
|
|
58
|
+
connectedUsers?: MultiplayerUser[];
|
|
59
|
+
tasks?: Task[];
|
|
60
|
+
userId?: string;
|
|
61
|
+
unstyled?: boolean;
|
|
62
|
+
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
63
|
+
assetManager: AssetManager;
|
|
64
|
+
ephemeralUserData: EphemeralUserData<E>;
|
|
65
|
+
forceInit: () => void;
|
|
66
|
+
} & StateInspectorOptions & ComponentPropsWithoutRef<"div">) => React.JSX.Element | null)>;
|
|
67
|
+
|
|
68
|
+
declare function useSyncStateManager<S, M>(stateManager: StateManager<S, M>): S;
|
|
69
|
+
declare function useSyncStateManager<S, M, P extends string>(stateManager: StateManager<S, M>, path: P): GetAtPath<S, P>;
|
|
70
|
+
declare function useManagedState<S, M = void>(createInitialState: () => S, options?: StateManagerOptions<S, M>): readonly [S, (...args: M extends {} ? [metadata: M, action: SetStateAction<S>] : [action: SetStateAction<S>]) => void, StateManager<S, M>];
|
|
71
|
+
declare function useManagedHistory<S, M = void>(stateManager: StateManager<S, M>): _noya_app_state_manager.HistorySnapshot<S, M>;
|
|
72
|
+
declare function useSyncMultiplayerStateManager<S, M = void>(multiplayerStateManager: MultiplayerStateManager<S, M>): S;
|
|
73
|
+
declare function useEphemeralUserData<E>(ephemeralUserData: EphemeralUserData<E>, options?: {
|
|
74
|
+
throttle?: number;
|
|
75
|
+
}): {
|
|
76
|
+
data: Record<string, E | undefined>;
|
|
77
|
+
metadata: Record<string, _noya_app_state_manager.EphemeralUserMetadata | undefined>;
|
|
78
|
+
currentUserId: string | undefined;
|
|
79
|
+
};
|
|
80
|
+
type UseMultiplayerStateOptions<S, M = void, E = void> = MultiplayerStateManagerOptions<S, M> & {
|
|
81
|
+
sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData" | "assetManager">) => void;
|
|
82
|
+
trackConnectionEvents?: boolean;
|
|
83
|
+
trackTasks?: boolean;
|
|
84
|
+
inspector?: boolean | StateInspectorOptions;
|
|
85
|
+
};
|
|
86
|
+
declare function useMultiplayerState<S, 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, {
|
|
87
|
+
tasks: Task[];
|
|
88
|
+
userId: string | undefined;
|
|
89
|
+
connectionEvents: ConnectionEvent<S>[] | undefined;
|
|
90
|
+
connectedUsers: MultiplayerUser[];
|
|
91
|
+
ephemeralUserData: EphemeralUserData<E>;
|
|
92
|
+
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
93
|
+
assets: _noya_app_state_manager.Asset[];
|
|
94
|
+
assetManager: AssetManager;
|
|
95
|
+
createAsset: (options: _noya_app_state_manager.CreateAssetOptions | Uint8Array | File | Blob) => Promise<_noya_app_state_manager.Asset>;
|
|
96
|
+
deleteAsset: (id: string) => Promise<void>;
|
|
97
|
+
}];
|
|
98
|
+
|
|
99
|
+
type AppViewType = "editable" | "readOnly" | "preview";
|
|
100
|
+
type AppTheme = "light" | "dark";
|
|
101
|
+
type AppData<State> = {
|
|
102
|
+
multiplayerUrl?: string;
|
|
103
|
+
theme: AppTheme;
|
|
104
|
+
viewType: AppViewType;
|
|
105
|
+
initialState: State;
|
|
106
|
+
inspector: boolean | StateInspectorOptions;
|
|
107
|
+
};
|
|
108
|
+
declare function createDefaultAppData<State>(initialState: State): AppData<State>;
|
|
109
|
+
type GetAppDataOptions = {
|
|
110
|
+
window?: {
|
|
111
|
+
location: {
|
|
112
|
+
hash: string;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
overrideExistingState?: boolean;
|
|
116
|
+
};
|
|
117
|
+
declare function enforceSchema<State>(initialState: State, schema?: TSchema): State;
|
|
118
|
+
declare function parseAppDataParameter(options?: GetAppDataOptions): AppData<unknown> | null;
|
|
119
|
+
declare function getAppData<State>(initialState: State | (() => State), schema?: TSchema, options?: GetAppDataOptions): AppData<State>;
|
|
120
|
+
type IframeToHostMessage = {
|
|
121
|
+
type: "application.setMenuItems";
|
|
122
|
+
payload: {
|
|
123
|
+
menuItems: any[];
|
|
124
|
+
};
|
|
125
|
+
} | {
|
|
126
|
+
type: "multiplayer.setUsers";
|
|
127
|
+
payload: {
|
|
128
|
+
users: any[];
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
type HostToIframeMessage = {
|
|
132
|
+
type: "application.selectMenuItem";
|
|
133
|
+
payload: {
|
|
134
|
+
value: string;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
declare function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]): void;
|
|
138
|
+
declare function useBroadcastMenuItems<T>(menuItems: any[], handleSelectMenuItem: (value: T) => void): void;
|
|
139
|
+
declare function isEmbeddedApp(): boolean;
|
|
140
|
+
type UseNoyaStateOptions<S, M = void, E = void> = UseMultiplayerStateOptions<S, M, E> & {
|
|
141
|
+
offlineStorageKey?: string;
|
|
142
|
+
};
|
|
143
|
+
type UseNoyaStateResult<S, M = void, E = void> = [
|
|
144
|
+
ReturnType<typeof useMultiplayerState<S, M, E>>[0],
|
|
145
|
+
ReturnType<typeof useMultiplayerState<S, M, E>>[1],
|
|
146
|
+
ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {
|
|
147
|
+
theme: AppTheme;
|
|
148
|
+
viewType: AppViewType;
|
|
149
|
+
}
|
|
150
|
+
];
|
|
151
|
+
/**
|
|
152
|
+
* Sync data locally or to a multiplayer server.
|
|
153
|
+
*
|
|
154
|
+
* There are 3 ways to use this hook:
|
|
155
|
+
*
|
|
156
|
+
* 1. Pass an initial state: `useNoyaState(initialState)`
|
|
157
|
+
* 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`
|
|
158
|
+
* 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`
|
|
159
|
+
*/
|
|
160
|
+
declare function useNoyaState<S, M = void, E = void, O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>>(...args: [
|
|
161
|
+
initialState: O["schema"] extends TSchema ? Static<O["schema"]> | (() => Static<O["schema"]>) : S | (() => S),
|
|
162
|
+
options?: O
|
|
163
|
+
] | [options: O & {
|
|
164
|
+
schema: TSchema;
|
|
165
|
+
}]): UseNoyaStateResult<O["schema"] extends TSchema ? Static<O["schema"]> : S, M, E>;
|
|
166
|
+
|
|
167
|
+
interface NoyaStateProviderProps<S, M, E> extends Omit<UseNoyaStateOptions<S, M, E>, "schema" | "mergeHistoryEntries"> {
|
|
168
|
+
children: React.ReactNode;
|
|
169
|
+
initialState?: S;
|
|
170
|
+
}
|
|
171
|
+
declare function useAssets(): _noya_app_state_manager.Asset[];
|
|
172
|
+
declare function useAsset(id: string | undefined): _noya_app_state_manager.Asset | undefined;
|
|
173
|
+
declare function useAssetManager(): {
|
|
174
|
+
create: (options: _noya_app_state_manager.CreateAssetOptions | Uint8Array | File | Blob) => Promise<_noya_app_state_manager.Asset>;
|
|
175
|
+
delete: (id: string) => Promise<void>;
|
|
176
|
+
};
|
|
177
|
+
declare function createNoyaContext<Schema extends TSchema, M = void, E = void>({ schema, mergeHistoryEntries, }: {
|
|
178
|
+
schema: Schema;
|
|
179
|
+
mergeHistoryEntries?: StateManagerOptions<Static<Schema>, M>["mergeHistoryEntries"];
|
|
180
|
+
}): {
|
|
181
|
+
Context: React.Context<{
|
|
182
|
+
ms: MultiplayerStateManager<Static<Schema>, M>;
|
|
183
|
+
assetManager: AssetManager;
|
|
184
|
+
} | undefined>;
|
|
185
|
+
Provider: ({ children, initialState, ...options }: NoyaStateProviderProps<Static<Schema>, M, E>) => React.JSX.Element;
|
|
186
|
+
useValue: {
|
|
187
|
+
(): Static<Schema>;
|
|
188
|
+
<A>(selector: (value: Static<Schema>) => A, options?: Pick<ObservableOptions, "isEqual">): A;
|
|
189
|
+
<P extends PathKey[] | string>(path: P): GetAtPath<Static<Schema>, P>;
|
|
190
|
+
};
|
|
191
|
+
useSetValue: {
|
|
192
|
+
(): M extends {} ? (metadata: M, value: SetStateAction<Static<Schema>>) => void : (value: SetStateAction<Static<Schema>>) => void;
|
|
193
|
+
<P extends PathKey[] | string>(path: P): M extends {} ? (metadata: M, value: SetStateAction<GetAtPath<Static<Schema>, P>>) => void : (value: SetStateAction<GetAtPath<Static<Schema>, P>>) => void;
|
|
194
|
+
};
|
|
195
|
+
useValueState: {
|
|
196
|
+
(): [Static<Schema>, M extends {} ? (metadata: M, value: SetStateAction<Static<Schema>>) => void : (value: SetStateAction<Static<Schema>>) => void];
|
|
197
|
+
<A>(selector: (value: Static<Schema>) => A, options?: ObservableOptions): [A, M extends {} ? (metadata: M, value: SetStateAction<Static<Schema>>) => void : (value: SetStateAction<Static<Schema>>) => void];
|
|
198
|
+
<P extends PathKey[] | string>(path?: P): [GetAtPath<Static<Schema>, P>, M extends {} ? (metadata: M, value: SetStateAction<GetAtPath<Static<Schema>, P>>) => void : (value: SetStateAction<GetAtPath<Static<Schema>, P>>) => void];
|
|
199
|
+
};
|
|
200
|
+
useStateManager: () => MultiplayerStateManager<Static<Schema>, M>;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
declare function useObservable<T>(observable: Observable<T>): T;
|
|
204
|
+
declare function useObservable<T, P extends PathKey[] | string>(observable: Observable<T>, path: P): GetAtPath<T, P>;
|
|
205
|
+
|
|
206
|
+
export { type AppData, type AppTheme, type AppViewType, type GetAppDataOptions, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, type UseNoyaStateOptions, type UseNoyaStateResult, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, createDefaultAppData, createNoyaContext, enforceSchema, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, parseAppDataParameter, useAsset, useAssetManager, useAssets, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaState, useObservable, useSyncMultiplayerStateManager, useSyncStateManager };
|
package/dist/index.d.ts
CHANGED
|
@@ -203,4 +203,4 @@ declare function createNoyaContext<Schema extends TSchema, M = void, E = void>({
|
|
|
203
203
|
declare function useObservable<T>(observable: Observable<T>): T;
|
|
204
204
|
declare function useObservable<T, P extends PathKey[] | string>(observable: Observable<T>, path: P): GetAtPath<T, P>;
|
|
205
205
|
|
|
206
|
-
export { AppData, AppTheme, AppViewType, GetAppDataOptions, HostToIframeMessage, IframeToHostMessage, StateInspector, StateInspectorAnchor, StateInspectorOptions, UseMultiplayerStateOptions, UseNoyaStateOptions, UseNoyaStateResult, UserNameTag, UserPointer, UserPointerContainer, UserPointerData, UserPointerIcon, UserPointerProps, UserPointersOverlay, UserPointersOverlayProps, createDefaultAppData, createNoyaContext, enforceSchema, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, parseAppDataParameter, useAsset, useAssetManager, useAssets, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaState, useObservable, useSyncMultiplayerStateManager, useSyncStateManager };
|
|
206
|
+
export { type AppData, type AppTheme, type AppViewType, type GetAppDataOptions, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, type UseNoyaStateOptions, type UseNoyaStateResult, UserNameTag, UserPointer, UserPointerContainer, type UserPointerData, UserPointerIcon, type UserPointerProps, UserPointersOverlay, type UserPointersOverlayProps, createDefaultAppData, createNoyaContext, enforceSchema, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, parseAppDataParameter, useAsset, useAssetManager, useAssets, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaState, useObservable, useSyncMultiplayerStateManager, useSyncStateManager };
|
package/dist/index.js
CHANGED
|
@@ -139,16 +139,14 @@ var UserPointer_ = function UserPointer({
|
|
|
139
139
|
const [, setForceUpdate] = (0, import_react2.useState)(0);
|
|
140
140
|
const updatedAt = metadata?.updatedAt ?? 0;
|
|
141
141
|
(0, import_react2.useEffect)(() => {
|
|
142
|
-
if (!shouldShow(hideAfter, updatedAt))
|
|
143
|
-
return;
|
|
142
|
+
if (!shouldShow(hideAfter, updatedAt)) return;
|
|
144
143
|
const timeoutId = setTimeout(() => {
|
|
145
144
|
setForceUpdate((prev) => prev + 1);
|
|
146
145
|
}, hideAfter);
|
|
147
146
|
return () => clearTimeout(timeoutId);
|
|
148
147
|
}, [hideAfter, updatedAt]);
|
|
149
148
|
const show = shouldShow(hideAfter, updatedAt);
|
|
150
|
-
if (!data || !data.pointer)
|
|
151
|
-
return null;
|
|
149
|
+
if (!data || !data.pointer) return null;
|
|
152
150
|
return /* @__PURE__ */ import_react2.default.createElement(UserPointerContainer, { key: user.id, point: data.pointer, show }, /* @__PURE__ */ import_react2.default.createElement(UserPointerIcon, { color: avatarStyle.backgroundColor }), /* @__PURE__ */ import_react2.default.createElement(UserNameTag, { background: avatarStyle.backgroundColor }, user.name));
|
|
153
151
|
};
|
|
154
152
|
var UserPointer2 = (0, import_react2.memo)(UserPointer_);
|
|
@@ -204,8 +202,7 @@ var UserNameTag = (0, import_react2.memo)(function UserNameTag2({
|
|
|
204
202
|
var UserPointersOverlay = (0, import_react2.memo)(function UserPointers({ connectedUsers, ephemeralUserData }) {
|
|
205
203
|
const currentUserId = useObservable(ephemeralUserData.currentUserId$);
|
|
206
204
|
return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, connectedUsers.map((user) => {
|
|
207
|
-
if (user.id === currentUserId)
|
|
208
|
-
return null;
|
|
205
|
+
if (user.id === currentUserId) return null;
|
|
209
206
|
return /* @__PURE__ */ import_react2.default.createElement(
|
|
210
207
|
UserPointer2,
|
|
211
208
|
{
|
|
@@ -622,8 +619,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
622
619
|
}
|
|
623
620
|
}, [historySnapshot]);
|
|
624
621
|
(0, import_react5.useEffect)(() => {
|
|
625
|
-
if (!historyContainerRef.current)
|
|
626
|
-
return;
|
|
622
|
+
if (!historyContainerRef.current) return;
|
|
627
623
|
const historyEntry = historyContainerRef.current.querySelector(
|
|
628
624
|
`#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
|
|
629
625
|
);
|
|
@@ -655,8 +651,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
655
651
|
zIndex: 9999,
|
|
656
652
|
lineHeight: "13px"
|
|
657
653
|
};
|
|
658
|
-
if (!didMount)
|
|
659
|
-
return null;
|
|
654
|
+
if (!didMount) return null;
|
|
660
655
|
if (!showInspector) {
|
|
661
656
|
return /* @__PURE__ */ import_react5.default.createElement(
|
|
662
657
|
"div",
|
|
@@ -725,14 +720,14 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
725
720
|
src: user.image,
|
|
726
721
|
alt: user.name,
|
|
727
722
|
style: {
|
|
728
|
-
width: "
|
|
729
|
-
height: "
|
|
723
|
+
width: "13px",
|
|
724
|
+
height: "13px",
|
|
730
725
|
borderRadius: "50%",
|
|
731
726
|
marginRight: "4px",
|
|
732
727
|
display: "inline-block",
|
|
733
728
|
position: "relative",
|
|
734
|
-
|
|
735
|
-
|
|
729
|
+
background: solidBorderColor,
|
|
730
|
+
verticalAlign: "middle"
|
|
736
731
|
}
|
|
737
732
|
}
|
|
738
733
|
),
|
|
@@ -909,7 +904,8 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
909
904
|
style: {
|
|
910
905
|
fontSize: "11px",
|
|
911
906
|
display: "flex",
|
|
912
|
-
flexWrap: "wrap"
|
|
907
|
+
flexWrap: "wrap",
|
|
908
|
+
margin: 0
|
|
913
909
|
}
|
|
914
910
|
},
|
|
915
911
|
entry.metadata.name
|
|
@@ -921,7 +917,8 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
921
917
|
style: {
|
|
922
918
|
fontSize: "11px",
|
|
923
919
|
display: "flex",
|
|
924
|
-
flexWrap: "wrap"
|
|
920
|
+
flexWrap: "wrap",
|
|
921
|
+
margin: 0
|
|
925
922
|
}
|
|
926
923
|
},
|
|
927
924
|
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 })),
|
|
@@ -1134,8 +1131,7 @@ function pathToString(extendedPath) {
|
|
|
1134
1131
|
).join("");
|
|
1135
1132
|
}
|
|
1136
1133
|
function ellipsis(str, maxLength, position = "end") {
|
|
1137
|
-
if (str.length <= maxLength)
|
|
1138
|
-
return str;
|
|
1134
|
+
if (str.length <= maxLength) return str;
|
|
1139
1135
|
switch (position) {
|
|
1140
1136
|
case "start":
|
|
1141
1137
|
return `\u2026${str.slice(str.length - maxLength)}`;
|
|
@@ -1208,8 +1204,7 @@ function useStateInspector({
|
|
|
1208
1204
|
}) {
|
|
1209
1205
|
const [root, setRoot] = import_react6.default.useState(null);
|
|
1210
1206
|
(0, import_react6.useLayoutEffect)(() => {
|
|
1211
|
-
if (disabled)
|
|
1212
|
-
return;
|
|
1207
|
+
if (disabled) return;
|
|
1213
1208
|
const { host, container } = createShadowRootElement();
|
|
1214
1209
|
const root2 = (0, import_client.createRoot)(container);
|
|
1215
1210
|
document.body.appendChild(host);
|
|
@@ -1219,8 +1214,7 @@ function useStateInspector({
|
|
|
1219
1214
|
};
|
|
1220
1215
|
}, [disabled]);
|
|
1221
1216
|
(0, import_react6.useLayoutEffect)(() => {
|
|
1222
|
-
if (!root)
|
|
1223
|
-
return;
|
|
1217
|
+
if (!root) return;
|
|
1224
1218
|
root.render(
|
|
1225
1219
|
/* @__PURE__ */ import_react6.default.createElement(
|
|
1226
1220
|
StateInspector,
|
|
@@ -1327,8 +1321,7 @@ function throttle(fn, ms) {
|
|
|
1327
1321
|
return (...args) => {
|
|
1328
1322
|
const now = Date.now();
|
|
1329
1323
|
if (now - lastCall < ms) {
|
|
1330
|
-
if (timeoutId)
|
|
1331
|
-
clearTimeout(timeoutId);
|
|
1324
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1332
1325
|
timeoutId = setTimeout(
|
|
1333
1326
|
() => {
|
|
1334
1327
|
lastCall = now;
|
|
@@ -1467,8 +1460,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1467
1460
|
});
|
|
1468
1461
|
}, [multiplayerStateManager]);
|
|
1469
1462
|
(0, import_react7.useEffect)(() => {
|
|
1470
|
-
if (!unrecoverableError)
|
|
1471
|
-
return;
|
|
1463
|
+
if (!unrecoverableError) return;
|
|
1472
1464
|
const el = document.createElement("div");
|
|
1473
1465
|
el.id = "noya-multiplayer-react-error-overlay";
|
|
1474
1466
|
document.body.appendChild(el);
|
|
@@ -1516,13 +1508,11 @@ function enforceSchema(initialState, schema) {
|
|
|
1516
1508
|
function parseAppDataParameter(options) {
|
|
1517
1509
|
const window2 = options?.window ?? globalThis;
|
|
1518
1510
|
const location = window2.location;
|
|
1519
|
-
if (!location)
|
|
1520
|
-
return null;
|
|
1511
|
+
if (!location) return null;
|
|
1521
1512
|
const urlHash = (location.hash || "").replace(/^#/, "");
|
|
1522
1513
|
const params = new URLSearchParams(urlHash);
|
|
1523
1514
|
const data = params.get("data");
|
|
1524
|
-
if (!data)
|
|
1525
|
-
return null;
|
|
1515
|
+
if (!data) return null;
|
|
1526
1516
|
try {
|
|
1527
1517
|
return JSON.parse(data);
|
|
1528
1518
|
} catch (e) {
|
|
@@ -1540,8 +1530,7 @@ function getAppData(initialState, schema, options) {
|
|
|
1540
1530
|
}
|
|
1541
1531
|
function useBroadcastConnectedUsers(connectedUsers) {
|
|
1542
1532
|
(0, import_react8.useEffect)(() => {
|
|
1543
|
-
if (!isEmbeddedApp())
|
|
1544
|
-
return;
|
|
1533
|
+
if (!isEmbeddedApp()) return;
|
|
1545
1534
|
const message = {
|
|
1546
1535
|
type: "multiplayer.setUsers",
|
|
1547
1536
|
payload: { users: connectedUsers }
|
|
@@ -1551,8 +1540,7 @@ function useBroadcastConnectedUsers(connectedUsers) {
|
|
|
1551
1540
|
}
|
|
1552
1541
|
function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
|
|
1553
1542
|
(0, import_react8.useEffect)(() => {
|
|
1554
|
-
if (!isEmbeddedApp())
|
|
1555
|
-
return;
|
|
1543
|
+
if (!isEmbeddedApp()) return;
|
|
1556
1544
|
const message = {
|
|
1557
1545
|
type: "application.setMenuItems",
|
|
1558
1546
|
payload: { menuItems }
|