@noya-app/noya-multiplayer-react 0.1.36 → 0.1.37
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 +9 -0
- package/dist/index.bundle.js +8 -8
- package/dist/index.d.mts +15 -11
- package/dist/index.d.ts +15 -11
- package/dist/index.js +77 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -15
- 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 +12 -12
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
AssetManager,
|
|
4
5
|
ConnectionEvent,
|
|
5
6
|
EphemeralUserData,
|
|
6
7
|
ExtendedPathKey,
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
} from "react-inspector";
|
|
27
28
|
import { shouldTrackEvents$, shouldTrackTasks$ } from "../globals";
|
|
28
29
|
import { useEphemeralUserData, useManagedHistory } from "../hooks";
|
|
30
|
+
import { useObservable } from "../useObservable";
|
|
29
31
|
import { useLocalStorageState } from "./useLocalStorageState";
|
|
30
32
|
|
|
31
33
|
const lightTheme = {
|
|
@@ -258,6 +260,7 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
|
|
|
258
260
|
unstyled,
|
|
259
261
|
colorScheme = "light",
|
|
260
262
|
multiplayerStateManager,
|
|
263
|
+
assetManager,
|
|
261
264
|
ephemeralUserData,
|
|
262
265
|
anchor = "right",
|
|
263
266
|
forceInit,
|
|
@@ -270,6 +273,7 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
|
|
|
270
273
|
userId?: string;
|
|
271
274
|
unstyled?: boolean;
|
|
272
275
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
276
|
+
assetManager: AssetManager;
|
|
273
277
|
ephemeralUserData: EphemeralUserData<E>;
|
|
274
278
|
forceInit: () => void;
|
|
275
279
|
} & StateInspectorOptions &
|
|
@@ -311,6 +315,10 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
|
|
|
311
315
|
"noya-multiplayer-react-show-ephemeral",
|
|
312
316
|
false
|
|
313
317
|
);
|
|
318
|
+
const [showAssets, setShowAssets] = useLocalStorageState(
|
|
319
|
+
"noya-multiplayer-react-show-assets",
|
|
320
|
+
false
|
|
321
|
+
);
|
|
314
322
|
|
|
315
323
|
useEffect(() => {
|
|
316
324
|
shouldTrackEvents$.set(showEvents);
|
|
@@ -329,6 +337,7 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
|
|
|
329
337
|
|
|
330
338
|
const ephemeral = useEphemeralUserData(ephemeralUserData);
|
|
331
339
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
340
|
+
const assets = useObservable(assetManager.assets$);
|
|
332
341
|
|
|
333
342
|
useEffect(() => {
|
|
334
343
|
if (historyContainerRef.current) {
|
|
@@ -680,6 +689,52 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
|
|
|
680
689
|
))}
|
|
681
690
|
</div>
|
|
682
691
|
</DisclosureSection>
|
|
692
|
+
<DisclosureSection
|
|
693
|
+
open={showAssets}
|
|
694
|
+
setOpen={setShowAssets}
|
|
695
|
+
title="Assets"
|
|
696
|
+
colorScheme={colorScheme}
|
|
697
|
+
right={
|
|
698
|
+
<span style={{ display: "flex", gap: "4px" }}>
|
|
699
|
+
<SmallButton
|
|
700
|
+
theme={theme}
|
|
701
|
+
onClick={() => {
|
|
702
|
+
// get file input
|
|
703
|
+
const input = document.createElement("input");
|
|
704
|
+
input.type = "file";
|
|
705
|
+
input.onchange = () => {
|
|
706
|
+
const file = input.files?.[0];
|
|
707
|
+
if (file) {
|
|
708
|
+
const reader = new FileReader();
|
|
709
|
+
reader.onload = () => {
|
|
710
|
+
const buffer = reader.result as ArrayBuffer;
|
|
711
|
+
assetManager.create(new Uint8Array(buffer));
|
|
712
|
+
};
|
|
713
|
+
reader.readAsArrayBuffer(file);
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
input.click();
|
|
717
|
+
}}
|
|
718
|
+
>
|
|
719
|
+
Upload
|
|
720
|
+
</SmallButton>
|
|
721
|
+
</span>
|
|
722
|
+
}
|
|
723
|
+
>
|
|
724
|
+
<div style={styles.sectionInner}>
|
|
725
|
+
{assets.map((asset) => (
|
|
726
|
+
<InspectorRow key={asset.id} colorScheme={colorScheme}>
|
|
727
|
+
<ObjectInspector name={asset.id} data={asset} theme={theme} />
|
|
728
|
+
<SmallButton
|
|
729
|
+
theme={theme}
|
|
730
|
+
onClick={() => assetManager.delete(asset.id)}
|
|
731
|
+
>
|
|
732
|
+
Delete
|
|
733
|
+
</SmallButton>
|
|
734
|
+
</InspectorRow>
|
|
735
|
+
))}
|
|
736
|
+
</div>
|
|
737
|
+
</DisclosureSection>
|
|
683
738
|
<DisclosureSection
|
|
684
739
|
title="Tasks"
|
|
685
740
|
colorScheme={colorScheme}
|
|
@@ -939,7 +994,7 @@ function SmallButton({
|
|
|
939
994
|
display: "inline-flex",
|
|
940
995
|
alignItems: "center",
|
|
941
996
|
justifyContent: "center",
|
|
942
|
-
padding: "
|
|
997
|
+
padding: "0",
|
|
943
998
|
cursor: "pointer",
|
|
944
999
|
...style,
|
|
945
1000
|
}}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
AssetManager,
|
|
4
5
|
ConnectionEvent,
|
|
5
6
|
EphemeralUserData,
|
|
6
7
|
MultiplayerStateManager,
|
|
@@ -13,10 +14,13 @@ import { createRoot } from "react-dom/client";
|
|
|
13
14
|
import { Root } from "react-dom/client";
|
|
14
15
|
import { StateInspector } from "./StateInspector";
|
|
15
16
|
|
|
16
|
-
function
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
function createShadowRootElement() {
|
|
18
|
+
const host = document.createElement("div");
|
|
19
|
+
host.id = "noya-multiplayer-react-inspector-host";
|
|
20
|
+
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
21
|
+
const container = document.createElement("div");
|
|
22
|
+
shadowRoot.appendChild(container);
|
|
23
|
+
return { host, container };
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export function useStateInspector<S, M, E>({
|
|
@@ -29,6 +33,7 @@ export function useStateInspector<S, M, E>({
|
|
|
29
33
|
colorScheme,
|
|
30
34
|
anchor,
|
|
31
35
|
multiplayerStateManager,
|
|
36
|
+
assetManager,
|
|
32
37
|
ephemeralUserData,
|
|
33
38
|
forceInit,
|
|
34
39
|
}: {
|
|
@@ -39,6 +44,7 @@ export function useStateInspector<S, M, E>({
|
|
|
39
44
|
userId?: string;
|
|
40
45
|
disabled: boolean;
|
|
41
46
|
multiplayerStateManager: MultiplayerStateManager<S, M>;
|
|
47
|
+
assetManager: AssetManager;
|
|
42
48
|
ephemeralUserData: EphemeralUserData<E>;
|
|
43
49
|
forceInit: () => void;
|
|
44
50
|
} & Pick<ComponentProps<typeof StateInspector>, "colorScheme" | "anchor">) {
|
|
@@ -47,16 +53,15 @@ export function useStateInspector<S, M, E>({
|
|
|
47
53
|
useLayoutEffect(() => {
|
|
48
54
|
if (disabled) return;
|
|
49
55
|
|
|
50
|
-
const
|
|
56
|
+
const { host, container } = createShadowRootElement();
|
|
57
|
+
const root = createRoot(container);
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
document.body.appendChild(portalElement);
|
|
59
|
+
document.body.appendChild(host);
|
|
55
60
|
|
|
56
61
|
setRoot(root);
|
|
57
62
|
|
|
58
63
|
return () => {
|
|
59
|
-
document.body.removeChild(
|
|
64
|
+
document.body.removeChild(host);
|
|
60
65
|
};
|
|
61
66
|
}, [disabled]);
|
|
62
67
|
|
|
@@ -76,6 +81,7 @@ export function useStateInspector<S, M, E>({
|
|
|
76
81
|
multiplayerStateManager={
|
|
77
82
|
multiplayerStateManager as MultiplayerStateManager<any, any>
|
|
78
83
|
}
|
|
84
|
+
assetManager={assetManager}
|
|
79
85
|
ephemeralUserData={ephemeralUserData as EphemeralUserData<any>}
|
|
80
86
|
/>
|
|
81
87
|
);
|
|
@@ -91,5 +97,6 @@ export function useStateInspector<S, M, E>({
|
|
|
91
97
|
tasks,
|
|
92
98
|
forceInit,
|
|
93
99
|
ephemeralUserData,
|
|
100
|
+
assetManager,
|
|
94
101
|
]);
|
|
95
102
|
}
|
package/src/noyaApp.ts
CHANGED
|
@@ -160,7 +160,7 @@ export function isEmbeddedApp() {
|
|
|
160
160
|
return window.self !== window.top;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
export type
|
|
163
|
+
export type UseNoyaStateOptions<
|
|
164
164
|
S,
|
|
165
165
|
M = void,
|
|
166
166
|
E = void,
|
|
@@ -168,7 +168,7 @@ export type UseNoyaAppStateOptions<
|
|
|
168
168
|
localStorageKey?: string;
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
-
export type
|
|
171
|
+
export type UseNoyaStateResult<S, M = void, E = void> = [
|
|
172
172
|
ReturnType<typeof useMultiplayerState<S, M, E>>[0],
|
|
173
173
|
ReturnType<typeof useMultiplayerState<S, M, E>>[1],
|
|
174
174
|
ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {
|
|
@@ -182,15 +182,15 @@ export type UseNoyaAppStateResult<S, M = void, E = void> = [
|
|
|
182
182
|
*
|
|
183
183
|
* There are 3 ways to use this hook:
|
|
184
184
|
*
|
|
185
|
-
* 1. Pass an initial state: `
|
|
186
|
-
* 2. Pass an initial state and a schema: `
|
|
187
|
-
* 3. Pass only a schema, and a conforming initial state is created automatically: `
|
|
185
|
+
* 1. Pass an initial state: `useNoyaState(initialState)`
|
|
186
|
+
* 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`
|
|
187
|
+
* 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`
|
|
188
188
|
*/
|
|
189
|
-
export function
|
|
189
|
+
export function useNoyaState<
|
|
190
190
|
S,
|
|
191
191
|
M = void,
|
|
192
192
|
E = void,
|
|
193
|
-
O extends
|
|
193
|
+
O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>,
|
|
194
194
|
>(
|
|
195
195
|
...args:
|
|
196
196
|
| [
|
|
@@ -200,7 +200,7 @@ export function useNoyaAppState<
|
|
|
200
200
|
options?: O,
|
|
201
201
|
]
|
|
202
202
|
| [options: O & { schema: TSchema }]
|
|
203
|
-
):
|
|
203
|
+
): UseNoyaStateResult<
|
|
204
204
|
O["schema"] extends TSchema ? Static<O["schema"]> : S,
|
|
205
205
|
M,
|
|
206
206
|
E
|
|
@@ -250,7 +250,7 @@ export function useNoyaAppState<
|
|
|
250
250
|
return { ...extras, theme, viewType } as const;
|
|
251
251
|
}, [extras, theme, viewType]);
|
|
252
252
|
|
|
253
|
-
return [result[0], result[1], mergedExtras] as
|
|
253
|
+
return [result[0], result[1], mergedExtras] as UseNoyaStateResult<
|
|
254
254
|
O["schema"] extends TSchema ? Static<O["schema"]> : S,
|
|
255
255
|
M,
|
|
256
256
|
E
|
|
@@ -258,11 +258,11 @@ export function useNoyaAppState<
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// function typeTest() {
|
|
261
|
-
// const [a, setA] =
|
|
262
|
-
// const [b, setB] =
|
|
261
|
+
// const [a, setA] = useNoyaState(7);
|
|
262
|
+
// const [b, setB] = useNoyaState(7, {
|
|
263
263
|
// schema: Type.Number(),
|
|
264
264
|
// });
|
|
265
|
-
// const [c, setC] =
|
|
265
|
+
// const [c, setC] = useNoyaState({
|
|
266
266
|
// schema: Type.Number(),
|
|
267
267
|
// });
|
|
268
268
|
// }
|