@noya-app/noya-multiplayer-react 0.1.73 → 0.1.74
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 -11
- package/CHANGELOG.md +8 -0
- package/dist/index.bundle.js +21 -21
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +28 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/noyaApp.test.ts +40 -0
- package/src/inspector/StateInspector.tsx +25 -10
- package/src/noyaApp.ts +28 -0
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.74",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dev": "npm run build -- --watch"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@noya-app/state-manager": "0.1.
|
|
14
|
+
"@noya-app/state-manager": "0.1.59",
|
|
15
15
|
"@noya-app/emitter": "0.1.0",
|
|
16
16
|
"@noya-app/observable": "0.1.12",
|
|
17
17
|
"@noya-app/task-runner": "0.1.6",
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { expect, it } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
clientId$,
|
|
4
|
+
clientImage$,
|
|
5
|
+
clientName$,
|
|
6
|
+
setClientId,
|
|
7
|
+
setClientImage,
|
|
8
|
+
setClientName,
|
|
9
|
+
} from "@noya-app/state-manager";
|
|
2
10
|
import { Type } from "..";
|
|
3
11
|
import { createDefaultAppData, getAppData } from "../noyaApp";
|
|
4
12
|
|
|
@@ -100,6 +108,38 @@ it("preserves userId from data param", () => {
|
|
|
100
108
|
expect(data.isDemo).toBe(true);
|
|
101
109
|
});
|
|
102
110
|
|
|
111
|
+
it("applies client identity from data param", () => {
|
|
112
|
+
setClientId(undefined);
|
|
113
|
+
setClientName(undefined);
|
|
114
|
+
setClientImage(undefined);
|
|
115
|
+
|
|
116
|
+
const existing = {
|
|
117
|
+
theme: "light",
|
|
118
|
+
viewType: "editable",
|
|
119
|
+
initialState: { foo: "bar" },
|
|
120
|
+
inspector: false,
|
|
121
|
+
clientId: "parent-client-id",
|
|
122
|
+
clientName: "Parent Name",
|
|
123
|
+
clientImage: "https://example.com/avatar.svg",
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
getAppData(null as unknown, undefined, {
|
|
127
|
+
window: {
|
|
128
|
+
location: {
|
|
129
|
+
hash: `#data=${encodeURIComponent(JSON.stringify(existing))}`,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(clientId$.get()).toBe("parent-client-id");
|
|
135
|
+
expect(clientName$.get()).toBe("Parent Name");
|
|
136
|
+
expect(clientImage$.get()).toBe("https://example.com/avatar.svg");
|
|
137
|
+
|
|
138
|
+
setClientId(undefined);
|
|
139
|
+
setClientName(undefined);
|
|
140
|
+
setClientImage(undefined);
|
|
141
|
+
});
|
|
142
|
+
|
|
103
143
|
// it("enforces schema on data param", () => {
|
|
104
144
|
// const schema = Type.Object({
|
|
105
145
|
// foo: Type.String({ default: "bar" }),
|
|
@@ -109,6 +109,10 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
109
109
|
"noya-multiplayer-react-show-users",
|
|
110
110
|
true
|
|
111
111
|
);
|
|
112
|
+
const [showUserDetails, setShowUserDetails] = useLocalStorageState(
|
|
113
|
+
"noya-multiplayer-react-show-user-details",
|
|
114
|
+
false
|
|
115
|
+
);
|
|
112
116
|
const [showData, setShowData] = useLocalStorageState(
|
|
113
117
|
"noya-multiplayer-react-show-data",
|
|
114
118
|
true
|
|
@@ -288,21 +292,28 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
288
292
|
colorScheme={colorScheme}
|
|
289
293
|
style={{
|
|
290
294
|
flex: "0 0 auto",
|
|
291
|
-
maxHeight: "
|
|
295
|
+
maxHeight: "50%",
|
|
296
|
+
overflowY: "auto",
|
|
292
297
|
}}
|
|
293
298
|
right={
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
<span style={{ display: "flex", gap: "10px" }}>
|
|
300
|
+
<StateInspectorButton
|
|
301
|
+
theme={theme}
|
|
302
|
+
onClick={() => setShowUserDetails(!showUserDetails)}
|
|
303
|
+
>
|
|
304
|
+
Toggle details
|
|
305
|
+
</StateInspectorButton>
|
|
306
|
+
<StateInspectorToggleButton
|
|
307
|
+
showInspector={showInspector}
|
|
308
|
+
setShowInspector={setShowInspector}
|
|
309
|
+
theme={theme}
|
|
310
|
+
anchor={anchor}
|
|
311
|
+
/>
|
|
312
|
+
</span>
|
|
300
313
|
}
|
|
301
314
|
>
|
|
302
315
|
<StateInspectorDisclosureRowInner style={{ flex: "0 0 auto" }}>
|
|
303
316
|
{connectedUsers?.map((user, index, array) => {
|
|
304
|
-
const identifier = user.userId ?? user.connectionId;
|
|
305
|
-
|
|
306
317
|
return (
|
|
307
318
|
<StateInspectorRow
|
|
308
319
|
key={user.connectionId}
|
|
@@ -326,7 +337,11 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
326
337
|
}}
|
|
327
338
|
/>
|
|
328
339
|
)}
|
|
329
|
-
{
|
|
340
|
+
{showUserDetails ? (
|
|
341
|
+
<ObjectInspector data={user} theme={theme} />
|
|
342
|
+
) : (
|
|
343
|
+
user.name
|
|
344
|
+
)}
|
|
330
345
|
</StateInspectorRow>
|
|
331
346
|
);
|
|
332
347
|
})}
|
package/src/noyaApp.ts
CHANGED
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
NoyaManager,
|
|
11
11
|
parentFrameSync,
|
|
12
12
|
PolicyAuthContext,
|
|
13
|
+
setClientId,
|
|
14
|
+
setClientImage,
|
|
15
|
+
setClientName,
|
|
13
16
|
Static,
|
|
14
17
|
stubSync,
|
|
15
18
|
SyncAdapter,
|
|
@@ -34,6 +37,9 @@ export type AppData<State> = {
|
|
|
34
37
|
userId?: string;
|
|
35
38
|
isDemo: boolean;
|
|
36
39
|
access?: AccessType;
|
|
40
|
+
clientId?: string;
|
|
41
|
+
clientName?: string;
|
|
42
|
+
clientImage?: string;
|
|
37
43
|
};
|
|
38
44
|
|
|
39
45
|
export function createDefaultAppData<State>(
|
|
@@ -84,6 +90,24 @@ export function parseAppDataParameter(
|
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
92
|
|
|
93
|
+
function applyClientIdentityFromAppData(appData: {
|
|
94
|
+
clientId?: string;
|
|
95
|
+
clientName?: string;
|
|
96
|
+
clientImage?: string;
|
|
97
|
+
}) {
|
|
98
|
+
if (appData.clientId !== undefined) {
|
|
99
|
+
setClientId(appData.clientId);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (appData.clientName !== undefined) {
|
|
103
|
+
setClientName(appData.clientName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (appData.clientImage !== undefined) {
|
|
107
|
+
setClientImage(appData.clientImage);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
87
111
|
export function getAppData<State>(
|
|
88
112
|
initialState: State | (() => State),
|
|
89
113
|
schema?: TSchema,
|
|
@@ -106,6 +130,10 @@ export function getAppData<State>(
|
|
|
106
130
|
appData.viewType === "editable" ? "write" : "read";
|
|
107
131
|
appData.access = appData.access ?? fallbackAccess;
|
|
108
132
|
|
|
133
|
+
// If the parent frame provided a client identity (embedded mode), make sure
|
|
134
|
+
// this frame adopts it so the clientId/name/image observables stay in sync.
|
|
135
|
+
applyClientIdentityFromAppData(appData);
|
|
136
|
+
|
|
109
137
|
return appData as AppData<State>;
|
|
110
138
|
}
|
|
111
139
|
|