@noya-app/noya-multiplayer-react 0.1.54 → 0.1.55
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 +11 -22
- package/CHANGELOG.md +11 -0
- package/dist/index.bundle.js +24 -13
- package/dist/index.d.mts +18 -9
- package/dist/index.d.ts +18 -9
- package/dist/index.js +363 -154
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +364 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/NoyaStateContext.tsx +4 -0
- package/src/components/UserPointersOverlay.tsx +16 -7
- package/src/hooks.ts +8 -5
- package/src/inspector/StateInspector.tsx +45 -35
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noya-app/noya-multiplayer-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
"dev": "npm run build -- --watch"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@noya-app/state-manager": "0.1.
|
|
15
|
+
"@noya-app/state-manager": "0.1.44",
|
|
16
16
|
"@noya-app/emitter": "0.1.0",
|
|
17
|
-
"@noya-app/observable": "0.1.
|
|
18
|
-
"@noya-app/task-runner": "0.1.
|
|
19
|
-
"@noya-app/react-utils": "0.1.
|
|
17
|
+
"@noya-app/observable": "0.1.6",
|
|
18
|
+
"@noya-app/task-runner": "0.1.6",
|
|
19
|
+
"@noya-app/react-utils": "0.1.18",
|
|
20
20
|
"react-inspector": "6.0.2"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
package/src/NoyaStateContext.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
EphemeralUserDataManager,
|
|
13
13
|
MultiplayerStateManager,
|
|
14
14
|
NoyaManager,
|
|
15
|
+
SafeEval,
|
|
15
16
|
StateManagerOptions,
|
|
16
17
|
Static,
|
|
17
18
|
TSchema,
|
|
@@ -221,12 +222,14 @@ export function createNoyaContext<
|
|
|
221
222
|
mergeHistoryEntries,
|
|
222
223
|
outputTransforms,
|
|
223
224
|
inputs,
|
|
225
|
+
safeEval,
|
|
224
226
|
}: {
|
|
225
227
|
schema: Schema;
|
|
226
228
|
mergeHistoryEntries?: StateManagerOptions<
|
|
227
229
|
Static<Schema>,
|
|
228
230
|
M
|
|
229
231
|
>["mergeHistoryEntries"];
|
|
232
|
+
safeEval?: SafeEval;
|
|
230
233
|
outputTransforms?: CreateParams<OutputTransform>[];
|
|
231
234
|
inputs?: CreateParams<Input>[];
|
|
232
235
|
}) {
|
|
@@ -253,6 +256,7 @@ export function createNoyaContext<
|
|
|
253
256
|
mergeHistoryEntries,
|
|
254
257
|
outputTransforms,
|
|
255
258
|
inputs,
|
|
259
|
+
safeEval,
|
|
256
260
|
...(options as any),
|
|
257
261
|
}
|
|
258
262
|
);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { Observable } from "@noya-app/observable";
|
|
3
4
|
import { memoGeneric } from "@noya-app/react-utils";
|
|
4
5
|
import {
|
|
5
6
|
ConnectedUsersManager,
|
|
6
7
|
EphemeralUserDataManager,
|
|
7
8
|
MultiplayerUser,
|
|
8
9
|
} from "@noya-app/state-manager";
|
|
9
|
-
import React, { useEffect, useState } from "react";
|
|
10
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
10
11
|
import { useObservable } from "../useObservable";
|
|
11
12
|
type Point = { x: number; y: number };
|
|
12
13
|
|
|
@@ -41,12 +42,20 @@ const UserPointerInternal = memoGeneric(function UserPointerInternal<
|
|
|
41
42
|
hideAfter = 5000,
|
|
42
43
|
renderUserPointer,
|
|
43
44
|
}: InternalUserPointerProps<E>) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const observable = useMemo(() => {
|
|
46
|
+
const metadata$ = ephemeralUserDataManager.metadata$
|
|
47
|
+
.observePath([user.id] as const)
|
|
48
|
+
.throttle(50);
|
|
49
|
+
const data$ = ephemeralUserDataManager.data$
|
|
50
|
+
.observePath([user.id] as const)
|
|
51
|
+
.throttle(50);
|
|
52
|
+
|
|
53
|
+
return Observable.combine([metadata$, data$], ([metadata, data]) => {
|
|
54
|
+
return { metadata, data };
|
|
55
|
+
});
|
|
56
|
+
}, [ephemeralUserDataManager, user.id]);
|
|
57
|
+
|
|
58
|
+
const { metadata, data } = useObservable(observable);
|
|
50
59
|
|
|
51
60
|
const [, setForceUpdate] = useState(0);
|
|
52
61
|
|
package/src/hooks.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { GetAtPath } from "@noya-app/observable";
|
|
4
4
|
import {
|
|
5
5
|
ActionHandler,
|
|
6
|
-
MultiplayerStateManagerOptions,
|
|
7
6
|
NoyaManager,
|
|
7
|
+
NoyaManagerOptions,
|
|
8
8
|
StateManager,
|
|
9
9
|
StateManagerOptions,
|
|
10
10
|
stubSync,
|
|
@@ -125,13 +125,11 @@ export type UseMultiplayerStateOptions<
|
|
|
125
125
|
M extends object = object,
|
|
126
126
|
E extends object = object,
|
|
127
127
|
MenuT extends string = string,
|
|
128
|
-
> =
|
|
128
|
+
> = NoyaManagerOptions<S, M> & {
|
|
129
129
|
sync?: SyncAdapter<S, M, E, MenuT>;
|
|
130
130
|
inspector?: boolean | StateInspectorOptions;
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
-
const defaultStubSync = stubSync<unknown, object, object, string>();
|
|
134
|
-
|
|
135
133
|
export function useMultiplayerState<
|
|
136
134
|
S,
|
|
137
135
|
M extends object = object,
|
|
@@ -142,7 +140,12 @@ export function useMultiplayerState<
|
|
|
142
140
|
options?: UseMultiplayerStateOptions<S, M, E, MenuT>
|
|
143
141
|
) {
|
|
144
142
|
const {
|
|
145
|
-
sync =
|
|
143
|
+
sync = stubSync<
|
|
144
|
+
unknown,
|
|
145
|
+
object,
|
|
146
|
+
object,
|
|
147
|
+
string
|
|
148
|
+
>() as unknown as SyncAdapter<S, M, E, MenuT>,
|
|
146
149
|
inspector,
|
|
147
150
|
...rest
|
|
148
151
|
} = options ?? {};
|
|
@@ -55,6 +55,42 @@ function ToggleButton({
|
|
|
55
55
|
theme: typeof chromeLight;
|
|
56
56
|
anchor: StateInspectorAnchor;
|
|
57
57
|
}) {
|
|
58
|
+
const isRightAnchor = anchor === "right";
|
|
59
|
+
|
|
60
|
+
const rightIcon = (
|
|
61
|
+
<svg
|
|
62
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
63
|
+
fill="none"
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
strokeWidth={1.5}
|
|
66
|
+
stroke="currentColor"
|
|
67
|
+
className="size-6"
|
|
68
|
+
>
|
|
69
|
+
<path
|
|
70
|
+
strokeLinecap="round"
|
|
71
|
+
strokeLinejoin="round"
|
|
72
|
+
d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
73
|
+
/>
|
|
74
|
+
</svg>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const leftIcon = (
|
|
78
|
+
<svg
|
|
79
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
80
|
+
fill="none"
|
|
81
|
+
viewBox="0 0 24 24"
|
|
82
|
+
strokeWidth={1.5}
|
|
83
|
+
stroke="currentColor"
|
|
84
|
+
className="size-6"
|
|
85
|
+
>
|
|
86
|
+
<path
|
|
87
|
+
strokeLinecap="round"
|
|
88
|
+
strokeLinejoin="round"
|
|
89
|
+
d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
|
|
90
|
+
/>
|
|
91
|
+
</svg>
|
|
92
|
+
);
|
|
93
|
+
|
|
58
94
|
return (
|
|
59
95
|
<span
|
|
60
96
|
role="button"
|
|
@@ -76,39 +112,13 @@ function ToggleButton({
|
|
|
76
112
|
setShowInspector(!showInspector);
|
|
77
113
|
}}
|
|
78
114
|
>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
stroke="currentColor"
|
|
87
|
-
className="size-6"
|
|
88
|
-
>
|
|
89
|
-
<path
|
|
90
|
-
strokeLinecap="round"
|
|
91
|
-
strokeLinejoin="round"
|
|
92
|
-
d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
93
|
-
/>
|
|
94
|
-
</svg>
|
|
95
|
-
) : (
|
|
96
|
-
<svg
|
|
97
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
98
|
-
fill="none"
|
|
99
|
-
viewBox="0 0 24 24"
|
|
100
|
-
strokeWidth={1.5}
|
|
101
|
-
stroke="currentColor"
|
|
102
|
-
className="size-6"
|
|
103
|
-
>
|
|
104
|
-
<path
|
|
105
|
-
strokeLinecap="round"
|
|
106
|
-
strokeLinejoin="round"
|
|
107
|
-
d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
|
|
108
|
-
/>
|
|
109
|
-
</svg>
|
|
110
|
-
)}
|
|
111
|
-
</span>
|
|
115
|
+
{showInspector ? (
|
|
116
|
+
"Hide Inspector"
|
|
117
|
+
) : (
|
|
118
|
+
<span style={{ width: "12px", height: "12px" }}>
|
|
119
|
+
{isRightAnchor ? rightIcon : leftIcon}
|
|
120
|
+
</span>
|
|
121
|
+
)}
|
|
112
122
|
</span>
|
|
113
123
|
);
|
|
114
124
|
}
|
|
@@ -793,7 +803,7 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
793
803
|
if (!name) return;
|
|
794
804
|
const value = prompt("Enter secret value");
|
|
795
805
|
if (!value) return;
|
|
796
|
-
secretManager.createSecret(name, value);
|
|
806
|
+
secretManager.createSecret(null, name, value);
|
|
797
807
|
}}
|
|
798
808
|
>
|
|
799
809
|
Create
|
|
@@ -806,7 +816,7 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
806
816
|
<ObjectInspector data={secret} theme={theme} />
|
|
807
817
|
<SmallButton
|
|
808
818
|
theme={theme}
|
|
809
|
-
onClick={() => secretManager.deleteSecret(secret.
|
|
819
|
+
onClick={() => secretManager.deleteSecret(secret.id)}
|
|
810
820
|
>
|
|
811
821
|
Delete
|
|
812
822
|
</SmallButton>
|