@noya-app/noya-multiplayer-react 0.1.36 → 0.1.38
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 +12 -12
- package/CHANGELOG.md +17 -0
- package/dist/index.bundle.js +8 -8
- package/dist/index.d.mts +16 -12
- package/dist/index.d.ts +16 -12
- package/dist/index.js +79 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/hooks.ts +15 -2
- package/src/inspector/StateInspector.tsx +56 -1
- package/src/inspector/useStateInspector.tsx +16 -9
- package/src/noyaApp.ts +16 -16
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _noya_app_state_manager from '@noya-app/state-manager';
|
|
2
|
-
import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema, Static } from '@noya-app/state-manager';
|
|
2
|
+
import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, AssetManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema, Static } from '@noya-app/state-manager';
|
|
3
3
|
export * from '@noya-app/state-manager';
|
|
4
4
|
import React, { SetStateAction } from 'react';
|
|
5
5
|
import { Observable, PathKey, GetWithPath } from '@noya-app/observable';
|
|
@@ -51,7 +51,7 @@ type StateInspectorOptions = {
|
|
|
51
51
|
colorScheme?: "light" | "dark";
|
|
52
52
|
anchor?: StateInspectorAnchor;
|
|
53
53
|
};
|
|
54
|
-
declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, ephemeralUserData, anchor, forceInit, ...props }: {
|
|
54
|
+
declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, assetManager, ephemeralUserData, anchor, forceInit, ...props }: {
|
|
55
55
|
state: S;
|
|
56
56
|
connectionEvents?: ConnectionEvent<S>[] | undefined;
|
|
57
57
|
connectedUsers?: MultiplayerUser[] | undefined;
|
|
@@ -59,6 +59,7 @@ declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, conn
|
|
|
59
59
|
userId?: string | undefined;
|
|
60
60
|
unstyled?: boolean | undefined;
|
|
61
61
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
62
|
+
assetManager: AssetManager;
|
|
62
63
|
ephemeralUserData: EphemeralUserData<E>;
|
|
63
64
|
forceInit: () => void;
|
|
64
65
|
} & StateInspectorOptions & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
|
|
@@ -76,7 +77,7 @@ declare function useEphemeralUserData<E>(ephemeralUserData: EphemeralUserData<E>
|
|
|
76
77
|
currentUserId: string | undefined;
|
|
77
78
|
};
|
|
78
79
|
type UseMultiplayerStateOptions<S, M = void, E = void> = MultiplayerStateManagerOptions<S, M> & {
|
|
79
|
-
sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData">) => void;
|
|
80
|
+
sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData" | "assetManager">) => void;
|
|
80
81
|
trackConnectionEvents?: boolean;
|
|
81
82
|
trackTasks?: boolean;
|
|
82
83
|
inspector?: boolean | StateInspectorOptions;
|
|
@@ -88,6 +89,9 @@ declare function useMultiplayerState<S, M = void, E = void>(initialState: S | ((
|
|
|
88
89
|
connectedUsers: MultiplayerUser[];
|
|
89
90
|
ephemeralUserData: EphemeralUserData<E>;
|
|
90
91
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
92
|
+
assets: _noya_app_state_manager.Asset[];
|
|
93
|
+
createAsset: (options: Uint8Array | _noya_app_state_manager.CreateAssetOptions) => Promise<_noya_app_state_manager.Asset>;
|
|
94
|
+
deleteAsset: (id: string) => Promise<void>;
|
|
91
95
|
}];
|
|
92
96
|
|
|
93
97
|
type AppViewType = "editable" | "readOnly" | "preview";
|
|
@@ -131,10 +135,10 @@ type HostToIframeMessage = {
|
|
|
131
135
|
declare function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]): void;
|
|
132
136
|
declare function useBroadcastMenuItems<T>(menuItems: any[], handleSelectMenuItem: (value: T) => void): void;
|
|
133
137
|
declare function isEmbeddedApp(): boolean;
|
|
134
|
-
type
|
|
135
|
-
|
|
138
|
+
type UseNoyaStateOptions<S, M = void, E = void> = UseMultiplayerStateOptions<S, M, E> & {
|
|
139
|
+
offlineStorageKey?: string;
|
|
136
140
|
};
|
|
137
|
-
type
|
|
141
|
+
type UseNoyaStateResult<S, M = void, E = void> = [
|
|
138
142
|
ReturnType<typeof useMultiplayerState<S, M, E>>[0],
|
|
139
143
|
ReturnType<typeof useMultiplayerState<S, M, E>>[1],
|
|
140
144
|
ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {
|
|
@@ -147,18 +151,18 @@ type UseNoyaAppStateResult<S, M = void, E = void> = [
|
|
|
147
151
|
*
|
|
148
152
|
* There are 3 ways to use this hook:
|
|
149
153
|
*
|
|
150
|
-
* 1. Pass an initial state: `
|
|
151
|
-
* 2. Pass an initial state and a schema: `
|
|
152
|
-
* 3. Pass only a schema, and a conforming initial state is created automatically: `
|
|
154
|
+
* 1. Pass an initial state: `useNoyaState(initialState)`
|
|
155
|
+
* 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`
|
|
156
|
+
* 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`
|
|
153
157
|
*/
|
|
154
|
-
declare function
|
|
158
|
+
declare function useNoyaState<S, M = void, E = void, O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>>(...args: [
|
|
155
159
|
initialState: O["schema"] extends TSchema ? Static<O["schema"]> | (() => Static<O["schema"]>) : S | (() => S),
|
|
156
160
|
options?: O
|
|
157
161
|
] | [options: O & {
|
|
158
162
|
schema: TSchema;
|
|
159
|
-
}]):
|
|
163
|
+
}]): UseNoyaStateResult<O["schema"] extends TSchema ? Static<O["schema"]> : S, M, E>;
|
|
160
164
|
|
|
161
165
|
declare function useObservable<T>(observable: Observable<T>): T;
|
|
162
166
|
declare function useObservable<T, P extends PathKey[]>(observable: Observable<T>, path: P): GetWithPath<T, P>;
|
|
163
167
|
|
|
164
|
-
export { type AppData, type AppTheme, type AppViewType, type GetAppDataOptions, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, type
|
|
168
|
+
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, enforceSchema, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, parseAppDataParameter, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaState, useObservable, useSyncMultiplayerStateManager, useSyncStateManager };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _noya_app_state_manager from '@noya-app/state-manager';
|
|
2
|
-
import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema, Static } from '@noya-app/state-manager';
|
|
2
|
+
import { MultiplayerUser, EphemeralUserData, ConnectionEvent, Task, MultiplayerStateManager, AssetManager, StateManager, Get, StateManagerOptions, MultiplayerStateManagerOptions, SyncAdapterOptions, TSchema, Static } from '@noya-app/state-manager';
|
|
3
3
|
export * from '@noya-app/state-manager';
|
|
4
4
|
import React, { SetStateAction } from 'react';
|
|
5
5
|
import { Observable, PathKey, GetWithPath } from '@noya-app/observable';
|
|
@@ -51,7 +51,7 @@ type StateInspectorOptions = {
|
|
|
51
51
|
colorScheme?: "light" | "dark";
|
|
52
52
|
anchor?: StateInspectorAnchor;
|
|
53
53
|
};
|
|
54
|
-
declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, ephemeralUserData, anchor, forceInit, ...props }: {
|
|
54
|
+
declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, connectionEvents, connectedUsers, tasks, userId, unstyled, colorScheme, multiplayerStateManager, assetManager, ephemeralUserData, anchor, forceInit, ...props }: {
|
|
55
55
|
state: S;
|
|
56
56
|
connectionEvents?: ConnectionEvent<S>[] | undefined;
|
|
57
57
|
connectedUsers?: MultiplayerUser[] | undefined;
|
|
@@ -59,6 +59,7 @@ declare const StateInspector: React.MemoExoticComponent<(<S, M, E>({ state, conn
|
|
|
59
59
|
userId?: string | undefined;
|
|
60
60
|
unstyled?: boolean | undefined;
|
|
61
61
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
62
|
+
assetManager: AssetManager;
|
|
62
63
|
ephemeralUserData: EphemeralUserData<E>;
|
|
63
64
|
forceInit: () => void;
|
|
64
65
|
} & StateInspectorOptions & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">) => React.JSX.Element | null)>;
|
|
@@ -76,7 +77,7 @@ declare function useEphemeralUserData<E>(ephemeralUserData: EphemeralUserData<E>
|
|
|
76
77
|
currentUserId: string | undefined;
|
|
77
78
|
};
|
|
78
79
|
type UseMultiplayerStateOptions<S, M = void, E = void> = MultiplayerStateManagerOptions<S, M> & {
|
|
79
|
-
sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData">) => void;
|
|
80
|
+
sync?: (options: Pick<SyncAdapterOptions<S, M, E>, "ms" | "ephemeralUserData" | "assetManager">) => void;
|
|
80
81
|
trackConnectionEvents?: boolean;
|
|
81
82
|
trackTasks?: boolean;
|
|
82
83
|
inspector?: boolean | StateInspectorOptions;
|
|
@@ -88,6 +89,9 @@ declare function useMultiplayerState<S, M = void, E = void>(initialState: S | ((
|
|
|
88
89
|
connectedUsers: MultiplayerUser[];
|
|
89
90
|
ephemeralUserData: EphemeralUserData<E>;
|
|
90
91
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
92
|
+
assets: _noya_app_state_manager.Asset[];
|
|
93
|
+
createAsset: (options: Uint8Array | _noya_app_state_manager.CreateAssetOptions) => Promise<_noya_app_state_manager.Asset>;
|
|
94
|
+
deleteAsset: (id: string) => Promise<void>;
|
|
91
95
|
}];
|
|
92
96
|
|
|
93
97
|
type AppViewType = "editable" | "readOnly" | "preview";
|
|
@@ -131,10 +135,10 @@ type HostToIframeMessage = {
|
|
|
131
135
|
declare function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]): void;
|
|
132
136
|
declare function useBroadcastMenuItems<T>(menuItems: any[], handleSelectMenuItem: (value: T) => void): void;
|
|
133
137
|
declare function isEmbeddedApp(): boolean;
|
|
134
|
-
type
|
|
135
|
-
|
|
138
|
+
type UseNoyaStateOptions<S, M = void, E = void> = UseMultiplayerStateOptions<S, M, E> & {
|
|
139
|
+
offlineStorageKey?: string;
|
|
136
140
|
};
|
|
137
|
-
type
|
|
141
|
+
type UseNoyaStateResult<S, M = void, E = void> = [
|
|
138
142
|
ReturnType<typeof useMultiplayerState<S, M, E>>[0],
|
|
139
143
|
ReturnType<typeof useMultiplayerState<S, M, E>>[1],
|
|
140
144
|
ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {
|
|
@@ -147,18 +151,18 @@ type UseNoyaAppStateResult<S, M = void, E = void> = [
|
|
|
147
151
|
*
|
|
148
152
|
* There are 3 ways to use this hook:
|
|
149
153
|
*
|
|
150
|
-
* 1. Pass an initial state: `
|
|
151
|
-
* 2. Pass an initial state and a schema: `
|
|
152
|
-
* 3. Pass only a schema, and a conforming initial state is created automatically: `
|
|
154
|
+
* 1. Pass an initial state: `useNoyaState(initialState)`
|
|
155
|
+
* 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`
|
|
156
|
+
* 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`
|
|
153
157
|
*/
|
|
154
|
-
declare function
|
|
158
|
+
declare function useNoyaState<S, M = void, E = void, O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>>(...args: [
|
|
155
159
|
initialState: O["schema"] extends TSchema ? Static<O["schema"]> | (() => Static<O["schema"]>) : S | (() => S),
|
|
156
160
|
options?: O
|
|
157
161
|
] | [options: O & {
|
|
158
162
|
schema: TSchema;
|
|
159
|
-
}]):
|
|
163
|
+
}]): UseNoyaStateResult<O["schema"] extends TSchema ? Static<O["schema"]> : S, M, E>;
|
|
160
164
|
|
|
161
165
|
declare function useObservable<T>(observable: Observable<T>): T;
|
|
162
166
|
declare function useObservable<T, P extends PathKey[]>(observable: Observable<T>, path: P): GetWithPath<T, P>;
|
|
163
167
|
|
|
164
|
-
export { type AppData, type AppTheme, type AppViewType, type GetAppDataOptions, type HostToIframeMessage, type IframeToHostMessage, StateInspector, type StateInspectorAnchor, type StateInspectorOptions, type UseMultiplayerStateOptions, type
|
|
168
|
+
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, enforceSchema, getAppData, getAvatarInitials, getAvatarStyle, isEmbeddedApp, parseAppDataParameter, useBroadcastConnectedUsers, useBroadcastMenuItems, useEphemeralUserData, useManagedHistory, useManagedState, useMultiplayerState, useNoyaState, useObservable, useSyncMultiplayerStateManager, useSyncStateManager };
|
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ __export(src_exports, {
|
|
|
50
50
|
useManagedHistory: () => useManagedHistory,
|
|
51
51
|
useManagedState: () => useManagedState,
|
|
52
52
|
useMultiplayerState: () => useMultiplayerState,
|
|
53
|
-
|
|
53
|
+
useNoyaState: () => useNoyaState,
|
|
54
54
|
useObservable: () => useObservable,
|
|
55
55
|
useSyncMultiplayerStateManager: () => useSyncMultiplayerStateManager,
|
|
56
56
|
useSyncStateManager: () => useSyncStateManager
|
|
@@ -554,6 +554,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
554
554
|
unstyled,
|
|
555
555
|
colorScheme = "light",
|
|
556
556
|
multiplayerStateManager,
|
|
557
|
+
assetManager,
|
|
557
558
|
ephemeralUserData,
|
|
558
559
|
anchor = "right",
|
|
559
560
|
forceInit,
|
|
@@ -593,6 +594,10 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
593
594
|
"noya-multiplayer-react-show-ephemeral",
|
|
594
595
|
false
|
|
595
596
|
);
|
|
597
|
+
const [showAssets, setShowAssets] = useLocalStorageState(
|
|
598
|
+
"noya-multiplayer-react-show-assets",
|
|
599
|
+
false
|
|
600
|
+
);
|
|
596
601
|
(0, import_react5.useEffect)(() => {
|
|
597
602
|
shouldTrackEvents$.set(showEvents);
|
|
598
603
|
}, [showEvents]);
|
|
@@ -606,6 +611,7 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
606
611
|
}, [connectionEvents]);
|
|
607
612
|
const ephemeral = useEphemeralUserData(ephemeralUserData);
|
|
608
613
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
614
|
+
const assets = useObservable(assetManager.assets$);
|
|
609
615
|
(0, import_react5.useEffect)(() => {
|
|
610
616
|
if (historyContainerRef.current) {
|
|
611
617
|
historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
|
|
@@ -921,6 +927,46 @@ var StateInspector = (0, import_react5.memo)(function StateInspector2({
|
|
|
921
927
|
))
|
|
922
928
|
)))
|
|
923
929
|
),
|
|
930
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
931
|
+
DisclosureSection,
|
|
932
|
+
{
|
|
933
|
+
open: showAssets,
|
|
934
|
+
setOpen: setShowAssets,
|
|
935
|
+
title: "Assets",
|
|
936
|
+
colorScheme,
|
|
937
|
+
right: /* @__PURE__ */ import_react5.default.createElement("span", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ import_react5.default.createElement(
|
|
938
|
+
SmallButton,
|
|
939
|
+
{
|
|
940
|
+
theme,
|
|
941
|
+
onClick: () => {
|
|
942
|
+
const input = document.createElement("input");
|
|
943
|
+
input.type = "file";
|
|
944
|
+
input.onchange = () => {
|
|
945
|
+
const file = input.files?.[0];
|
|
946
|
+
if (file) {
|
|
947
|
+
const reader = new FileReader();
|
|
948
|
+
reader.onload = () => {
|
|
949
|
+
const buffer = reader.result;
|
|
950
|
+
assetManager.create(new Uint8Array(buffer));
|
|
951
|
+
};
|
|
952
|
+
reader.readAsArrayBuffer(file);
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
input.click();
|
|
956
|
+
}
|
|
957
|
+
},
|
|
958
|
+
"Upload"
|
|
959
|
+
))
|
|
960
|
+
},
|
|
961
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { style: styles.sectionInner }, assets.map((asset) => /* @__PURE__ */ import_react5.default.createElement(InspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ import_react5.default.createElement(import_react_inspector.ObjectInspector, { name: asset.id, data: asset, theme }), /* @__PURE__ */ import_react5.default.createElement(
|
|
962
|
+
SmallButton,
|
|
963
|
+
{
|
|
964
|
+
theme,
|
|
965
|
+
onClick: () => assetManager.delete(asset.id)
|
|
966
|
+
},
|
|
967
|
+
"Delete"
|
|
968
|
+
))))
|
|
969
|
+
),
|
|
924
970
|
/* @__PURE__ */ import_react5.default.createElement(
|
|
925
971
|
DisclosureSection,
|
|
926
972
|
{
|
|
@@ -1124,7 +1170,7 @@ function SmallButton({
|
|
|
1124
1170
|
display: "inline-flex",
|
|
1125
1171
|
alignItems: "center",
|
|
1126
1172
|
justifyContent: "center",
|
|
1127
|
-
padding: "
|
|
1173
|
+
padding: "0",
|
|
1128
1174
|
cursor: "pointer",
|
|
1129
1175
|
...style
|
|
1130
1176
|
}
|
|
@@ -1134,10 +1180,13 @@ function SmallButton({
|
|
|
1134
1180
|
}
|
|
1135
1181
|
|
|
1136
1182
|
// src/inspector/useStateInspector.tsx
|
|
1137
|
-
function
|
|
1138
|
-
const
|
|
1139
|
-
|
|
1140
|
-
|
|
1183
|
+
function createShadowRootElement() {
|
|
1184
|
+
const host = document.createElement("div");
|
|
1185
|
+
host.id = "noya-multiplayer-react-inspector-host";
|
|
1186
|
+
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
1187
|
+
const container = document.createElement("div");
|
|
1188
|
+
shadowRoot.appendChild(container);
|
|
1189
|
+
return { host, container };
|
|
1141
1190
|
}
|
|
1142
1191
|
function useStateInspector({
|
|
1143
1192
|
state,
|
|
@@ -1149,6 +1198,7 @@ function useStateInspector({
|
|
|
1149
1198
|
colorScheme,
|
|
1150
1199
|
anchor,
|
|
1151
1200
|
multiplayerStateManager,
|
|
1201
|
+
assetManager,
|
|
1152
1202
|
ephemeralUserData,
|
|
1153
1203
|
forceInit
|
|
1154
1204
|
}) {
|
|
@@ -1156,12 +1206,12 @@ function useStateInspector({
|
|
|
1156
1206
|
(0, import_react6.useLayoutEffect)(() => {
|
|
1157
1207
|
if (disabled)
|
|
1158
1208
|
return;
|
|
1159
|
-
const
|
|
1160
|
-
const root2 = (0, import_client.createRoot)(
|
|
1161
|
-
document.body.appendChild(
|
|
1209
|
+
const { host, container } = createShadowRootElement();
|
|
1210
|
+
const root2 = (0, import_client.createRoot)(container);
|
|
1211
|
+
document.body.appendChild(host);
|
|
1162
1212
|
setRoot(root2);
|
|
1163
1213
|
return () => {
|
|
1164
|
-
document.body.removeChild(
|
|
1214
|
+
document.body.removeChild(host);
|
|
1165
1215
|
};
|
|
1166
1216
|
}, [disabled]);
|
|
1167
1217
|
(0, import_react6.useLayoutEffect)(() => {
|
|
@@ -1180,6 +1230,7 @@ function useStateInspector({
|
|
|
1180
1230
|
anchor,
|
|
1181
1231
|
forceInit,
|
|
1182
1232
|
multiplayerStateManager,
|
|
1233
|
+
assetManager,
|
|
1183
1234
|
ephemeralUserData
|
|
1184
1235
|
}
|
|
1185
1236
|
)
|
|
@@ -1195,7 +1246,8 @@ function useStateInspector({
|
|
|
1195
1246
|
userId,
|
|
1196
1247
|
tasks,
|
|
1197
1248
|
forceInit,
|
|
1198
|
-
ephemeralUserData
|
|
1249
|
+
ephemeralUserData,
|
|
1250
|
+
assetManager
|
|
1199
1251
|
]);
|
|
1200
1252
|
}
|
|
1201
1253
|
|
|
@@ -1310,6 +1362,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1310
1362
|
const [multiplayerStateManager] = (0, import_react7.useState)(
|
|
1311
1363
|
() => new import_state_manager.MultiplayerStateManager(initialState, rest)
|
|
1312
1364
|
);
|
|
1365
|
+
const [assetManager] = (0, import_react7.useState)(() => new import_state_manager.AssetManager());
|
|
1313
1366
|
const syncRef = (0, import_react7.useRef)(sync);
|
|
1314
1367
|
const [connectionEvents, setConnectionEvents] = (0, import_react7.useState)();
|
|
1315
1368
|
const [connectedUsers, setConnectedUsers] = (0, import_react7.useState)([]);
|
|
@@ -1318,6 +1371,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1318
1371
|
);
|
|
1319
1372
|
const [tasks, setTasks] = (0, import_react7.useState)([]);
|
|
1320
1373
|
const [userId, setUserId] = (0, import_react7.useState)();
|
|
1374
|
+
const assets = useObservable(assetManager.assets$);
|
|
1321
1375
|
const extras = (0, import_react7.useMemo)(() => {
|
|
1322
1376
|
return {
|
|
1323
1377
|
tasks,
|
|
@@ -1325,7 +1379,10 @@ function useMultiplayerState(initialState, options) {
|
|
|
1325
1379
|
connectionEvents,
|
|
1326
1380
|
connectedUsers,
|
|
1327
1381
|
ephemeralUserData,
|
|
1328
|
-
multiplayerStateManager
|
|
1382
|
+
multiplayerStateManager,
|
|
1383
|
+
assets,
|
|
1384
|
+
createAsset: assetManager.create,
|
|
1385
|
+
deleteAsset: assetManager.delete
|
|
1329
1386
|
// evaluate: async (code: string) => {
|
|
1330
1387
|
// const payload = await rpcManager.request({ type: "eval", code });
|
|
1331
1388
|
// if (payload.type !== "eval") {
|
|
@@ -1339,7 +1396,9 @@ function useMultiplayerState(initialState, options) {
|
|
|
1339
1396
|
connectionEvents,
|
|
1340
1397
|
connectedUsers,
|
|
1341
1398
|
ephemeralUserData,
|
|
1342
|
-
multiplayerStateManager
|
|
1399
|
+
multiplayerStateManager,
|
|
1400
|
+
assetManager,
|
|
1401
|
+
assets
|
|
1343
1402
|
]);
|
|
1344
1403
|
const globalTrackEvents = useObservable(shouldTrackEvents$);
|
|
1345
1404
|
const globalTrackTasks = useObservable(shouldTrackTasks$);
|
|
@@ -1373,13 +1432,14 @@ function useMultiplayerState(initialState, options) {
|
|
|
1373
1432
|
if (syncRef.current) {
|
|
1374
1433
|
return syncRef.current({
|
|
1375
1434
|
ms: multiplayerStateManager,
|
|
1435
|
+
assetManager,
|
|
1376
1436
|
ephemeralUserData,
|
|
1377
1437
|
onConnectionEvent: (e) => trackEventsCallbackRef.current?.(e),
|
|
1378
1438
|
onChangeConnectedUsers: (users, userId2) => trackConnectedUsersCallbackRef.current?.(users, userId2),
|
|
1379
1439
|
onChangeTasks: (tasks2) => trackTasksCallbackRef.current?.(tasks2)
|
|
1380
1440
|
});
|
|
1381
1441
|
}
|
|
1382
|
-
}, [ephemeralUserData, multiplayerStateManager]);
|
|
1442
|
+
}, [assetManager, ephemeralUserData, multiplayerStateManager]);
|
|
1383
1443
|
const state = useSyncMultiplayerStateManager(multiplayerStateManager);
|
|
1384
1444
|
const forceInit = (0, import_react7.useCallback)(() => {
|
|
1385
1445
|
const state2 = initialState instanceof Function ? initialState() : initialState;
|
|
@@ -1409,6 +1469,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
1409
1469
|
useStateInspector({
|
|
1410
1470
|
ephemeralUserData,
|
|
1411
1471
|
multiplayerStateManager,
|
|
1472
|
+
assetManager,
|
|
1412
1473
|
state,
|
|
1413
1474
|
connectionEvents,
|
|
1414
1475
|
connectedUsers,
|
|
@@ -1498,7 +1559,7 @@ function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
|
|
|
1498
1559
|
function isEmbeddedApp() {
|
|
1499
1560
|
return window.self !== window.top;
|
|
1500
1561
|
}
|
|
1501
|
-
function
|
|
1562
|
+
function useNoyaState(...args) {
|
|
1502
1563
|
const [initialState, options] = typeof args[0] === "object" && args[0] !== null && "schema" in args[0] && import_state_manager2.TypeGuard.IsSchema(args[0].schema) ? [null, args[0]] : [args[0], args[1]];
|
|
1503
1564
|
const [
|
|
1504
1565
|
{
|
|
@@ -1514,8 +1575,8 @@ function useNoyaAppState(...args) {
|
|
|
1514
1575
|
});
|
|
1515
1576
|
});
|
|
1516
1577
|
const sync = (0, import_react8.useMemo)(() => {
|
|
1517
|
-
return multiplayerUrl ? (0, import_state_manager2.webSocketSync)(multiplayerUrl) : options?.
|
|
1518
|
-
}, [multiplayerUrl, options?.
|
|
1578
|
+
return multiplayerUrl ? (0, import_state_manager2.webSocketSync)(multiplayerUrl) : options?.offlineStorageKey ? (0, import_state_manager2.localStorageSync)({ key: options.offlineStorageKey }) : (0, import_state_manager2.stubSync)();
|
|
1579
|
+
}, [multiplayerUrl, options?.offlineStorageKey]);
|
|
1519
1580
|
const result = useMultiplayerState(noyaAppInitialState, {
|
|
1520
1581
|
...options,
|
|
1521
1582
|
inspector: options?.inspector ?? inspector,
|
|
@@ -1549,7 +1610,7 @@ function useNoyaAppState(...args) {
|
|
|
1549
1610
|
useManagedHistory,
|
|
1550
1611
|
useManagedState,
|
|
1551
1612
|
useMultiplayerState,
|
|
1552
|
-
|
|
1613
|
+
useNoyaState,
|
|
1553
1614
|
useObservable,
|
|
1554
1615
|
useSyncMultiplayerStateManager,
|
|
1555
1616
|
useSyncStateManager,
|