@noya-app/noya-multiplayer-react 0.1.74 → 0.1.76
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 +15 -0
- package/dist/index.bundle.js +28 -28
- package/dist/index.d.mts +7 -9
- package/dist/index.d.ts +7 -9
- package/dist/index.js +298 -207
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +242 -147
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/NoyaStateContext.tsx +26 -42
- package/src/inspector/StateInspector.tsx +123 -52
- package/src/inspector/sections/EventsSection.tsx +22 -1
- package/src/inspector/sections/ServerScriptLogsSection.tsx +18 -2
- package/src/inspector/usePausedStream.ts +33 -0
- package/src/singleton.tsx +2 -3
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.76",
|
|
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.61",
|
|
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",
|
package/src/NoyaStateContext.tsx
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
AssetTranscriptionResult,
|
|
27
27
|
CreateParams,
|
|
28
28
|
ExtractRequestBody,
|
|
29
|
+
findNoyaUser,
|
|
29
30
|
MultiplayerPatchMetadata,
|
|
30
31
|
MultiplayerStateManager,
|
|
31
32
|
NoyaManager,
|
|
@@ -318,39 +319,47 @@ export function usePipelineManager() {
|
|
|
318
319
|
return noyaManager.pipelineManager;
|
|
319
320
|
}
|
|
320
321
|
|
|
321
|
-
export function
|
|
322
|
+
export function useNoyaUserManager() {
|
|
322
323
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
323
324
|
return noyaManager.userManager;
|
|
324
325
|
}
|
|
325
326
|
|
|
326
|
-
export function
|
|
327
|
-
const userManager =
|
|
328
|
-
return useObservable(userManager?.
|
|
327
|
+
export function useNoyaUsers() {
|
|
328
|
+
const userManager = useNoyaUserManager();
|
|
329
|
+
return useObservable(userManager?.allUsers$);
|
|
329
330
|
}
|
|
330
331
|
|
|
331
|
-
export function
|
|
332
|
-
const userManager =
|
|
332
|
+
export function useNoyaUser(id?: string) {
|
|
333
|
+
const userManager = useNoyaUserManager();
|
|
334
|
+
|
|
333
335
|
return useObservable(
|
|
334
|
-
userManager?.
|
|
335
|
-
useCallback(
|
|
336
|
-
(users) => {
|
|
337
|
-
return users.find((user) => {
|
|
338
|
-
const prefix = user.connectionId.slice(0, 8);
|
|
339
|
-
return userId?.includes(prefix);
|
|
340
|
-
});
|
|
341
|
-
},
|
|
342
|
-
[userId]
|
|
343
|
-
)
|
|
336
|
+
userManager?.allUsers$,
|
|
337
|
+
useCallback((users) => findNoyaUser(users, id), [id])
|
|
344
338
|
);
|
|
345
339
|
}
|
|
346
340
|
|
|
341
|
+
export function useNoyaActiveUsers() {
|
|
342
|
+
const userManager = useNoyaUserManager();
|
|
343
|
+
return useObservable(userManager?.connectedUsers$);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function useNoyaCurrentUser() {
|
|
347
|
+
const userManager = useNoyaUserManager();
|
|
348
|
+
return useObservable(userManager?.currentUser$);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export function useNoyaCurrentUserId() {
|
|
352
|
+
const userManager = useNoyaUserManager();
|
|
353
|
+
return useObservable(userManager?.currentId$);
|
|
354
|
+
}
|
|
355
|
+
|
|
347
356
|
export function useAnySharedConnectionData() {
|
|
348
357
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
349
358
|
return noyaManager.sharedConnectionDataManager;
|
|
350
359
|
}
|
|
351
360
|
|
|
352
361
|
export function useEnqueueInput<
|
|
353
|
-
I extends Record<string, any> = Record<string, unknown
|
|
362
|
+
I extends Record<string, any> = Record<string, unknown>,
|
|
354
363
|
>() {
|
|
355
364
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
356
365
|
return noyaManager.enqueueInput as NoyaManager<
|
|
@@ -362,31 +371,6 @@ export function useEnqueueInput<
|
|
|
362
371
|
>["enqueueInput"];
|
|
363
372
|
}
|
|
364
373
|
|
|
365
|
-
export function useNoyaUser() {
|
|
366
|
-
const userManager = useUserManager();
|
|
367
|
-
return useObservable(userManager?.currentUser$);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
export function useNoyaId() {
|
|
371
|
-
const userManager = useUserManager();
|
|
372
|
-
return useObservable(userManager?.currentId$);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export function useNoyaUserId() {
|
|
376
|
-
const userManager = useUserManager();
|
|
377
|
-
return useObservable(userManager?.currentUserId$);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
export function useNoyaConnectionId() {
|
|
381
|
-
const userManager = useUserManager();
|
|
382
|
-
return useObservable(userManager?.currentConnectionId$);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
export function useNoyaClientId() {
|
|
386
|
-
const userManager = useUserManager();
|
|
387
|
-
return useObservable(userManager?.currentClientId$);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
374
|
export function useIsProcessing() {
|
|
391
375
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
392
376
|
return useObservable(noyaManager.isProcessing$);
|
|
@@ -34,6 +34,7 @@ import { StateInspectorRow } from "./StateInspectorRow";
|
|
|
34
34
|
import { StateInspectorTitleLabel } from "./StateInspectorTitleLabel";
|
|
35
35
|
import { StateInspectorToggleButton } from "./StateInspectorToggleButton";
|
|
36
36
|
import { useLocalStorageState } from "./useLocalStorageState";
|
|
37
|
+
import { usePausedStream } from "./usePausedStream";
|
|
37
38
|
import { ellipsis, uploadFile } from "./utils";
|
|
38
39
|
|
|
39
40
|
export type StateInspectorAnchor =
|
|
@@ -92,6 +93,7 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
92
93
|
const eventsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
93
94
|
const activityEventsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
94
95
|
const serverLogsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
96
|
+
const serverSimulationLogsContainerRef = React.useRef<HTMLDivElement>(null);
|
|
95
97
|
|
|
96
98
|
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
97
99
|
"noya-multiplayer-react-show-inspector",
|
|
@@ -153,34 +155,45 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
153
155
|
"noya-multiplayer-react-show-server-logs",
|
|
154
156
|
false
|
|
155
157
|
);
|
|
158
|
+
const [showServerSimulationLogs, setShowServerSimulationLogs] =
|
|
159
|
+
useLocalStorageState(
|
|
160
|
+
"noya-multiplayer-react-show-server-simulation-logs",
|
|
161
|
+
false
|
|
162
|
+
);
|
|
163
|
+
const [showSimulation, setShowSimulation] = useLocalStorageState(
|
|
164
|
+
"noya-multiplayer-react-show-simulation",
|
|
165
|
+
false
|
|
166
|
+
);
|
|
156
167
|
|
|
157
168
|
const connectionEvents = useObservable(connectionEventManager.events$);
|
|
169
|
+
const {
|
|
170
|
+
visibleItems: visibleConnectionEvents,
|
|
171
|
+
paused: connectionEventsPaused,
|
|
172
|
+
togglePaused: toggleConnectionEventsPaused,
|
|
173
|
+
} = usePausedStream(connectionEvents);
|
|
174
|
+
|
|
158
175
|
useEffect(() => {
|
|
159
176
|
if (eventsContainerRef.current) {
|
|
160
177
|
eventsContainerRef.current.scrollTop =
|
|
161
178
|
eventsContainerRef.current.scrollHeight;
|
|
162
179
|
}
|
|
163
|
-
}, [
|
|
180
|
+
}, [visibleConnectionEvents]);
|
|
181
|
+
|
|
164
182
|
const serverLogs = useObservable(logManager.logs$);
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
183
|
+
const {
|
|
184
|
+
visibleItems: visibleServerLogs,
|
|
185
|
+
paused: serverLogsPaused,
|
|
186
|
+
togglePaused: toggleServerLogsPaused,
|
|
187
|
+
} = usePausedStream(serverLogs);
|
|
188
|
+
const serverSimulationLogs = useObservable(
|
|
189
|
+
multiplayerStateManager.serverSimulationLogs$
|
|
168
190
|
);
|
|
191
|
+
const {
|
|
192
|
+
visibleItems: visibleServerSimulationLogs,
|
|
193
|
+
paused: serverSimulationLogsPaused,
|
|
194
|
+
togglePaused: toggleServerSimulationLogsPaused,
|
|
195
|
+
} = usePausedStream(serverSimulationLogs);
|
|
169
196
|
|
|
170
|
-
const toggleServerLogsPaused = useCallback(() => {
|
|
171
|
-
setServerLogsPaused((value) => {
|
|
172
|
-
if (!value) {
|
|
173
|
-
setVisibleServerLogs(serverLogs ?? []);
|
|
174
|
-
}
|
|
175
|
-
return !value;
|
|
176
|
-
});
|
|
177
|
-
}, [serverLogs]);
|
|
178
|
-
|
|
179
|
-
useEffect(() => {
|
|
180
|
-
if (serverLogsPaused) return;
|
|
181
|
-
|
|
182
|
-
setVisibleServerLogs(serverLogs ?? []);
|
|
183
|
-
}, [serverLogs, serverLogsPaused]);
|
|
184
197
|
useEffect(() => {
|
|
185
198
|
if (!showServerLogs) return;
|
|
186
199
|
if (serverLogsContainerRef.current) {
|
|
@@ -188,6 +201,13 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
188
201
|
serverLogsContainerRef.current.scrollHeight;
|
|
189
202
|
}
|
|
190
203
|
}, [showServerLogs, visibleServerLogs]);
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (!showServerSimulationLogs) return;
|
|
206
|
+
if (serverSimulationLogsContainerRef.current) {
|
|
207
|
+
serverSimulationLogsContainerRef.current.scrollTop =
|
|
208
|
+
serverSimulationLogsContainerRef.current.scrollHeight;
|
|
209
|
+
}
|
|
210
|
+
}, [showServerSimulationLogs, visibleServerSimulationLogs]);
|
|
191
211
|
|
|
192
212
|
const multipeerStateInitialized = useObservable(
|
|
193
213
|
multiplayerStateManager.isInitialized$
|
|
@@ -200,8 +220,13 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
200
220
|
const assetsInitialized = useObservable(assetManager.isInitialized$);
|
|
201
221
|
const secrets = useObservable(secretManager.secrets$);
|
|
202
222
|
const secretsInitialized = useObservable(secretManager.isInitialized$);
|
|
203
|
-
const connectedUsers = useObservable(userManager.
|
|
223
|
+
const connectedUsers = useObservable(userManager.allUsers$);
|
|
204
224
|
const connectionId = useObservable(userManager.currentConnectionId$);
|
|
225
|
+
const simulationDiagnostics =
|
|
226
|
+
multiplayerStateManager.getServerSimulationDiagnostics?.() ?? null;
|
|
227
|
+
const showSimulationLogsSection =
|
|
228
|
+
(simulationDiagnostics?.simulateLocally ?? false) ||
|
|
229
|
+
visibleServerSimulationLogs.length > 0;
|
|
205
230
|
const state = useObservable(multiplayerStateManager.optimisticState$);
|
|
206
231
|
const inputsInitialized = useObservable(ioManager.inputsInitialized$);
|
|
207
232
|
const outputTransformsInitialized = useObservable(
|
|
@@ -313,38 +338,45 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
313
338
|
}
|
|
314
339
|
>
|
|
315
340
|
<StateInspectorDisclosureRowInner style={{ flex: "0 0 auto" }}>
|
|
316
|
-
{connectedUsers
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
341
|
+
{connectedUsers
|
|
342
|
+
?.filter((user) => showUserDetails || !user.inactive)
|
|
343
|
+
.map((user, index, array) => {
|
|
344
|
+
return (
|
|
345
|
+
<StateInspectorRow
|
|
346
|
+
key={user.connectionId}
|
|
347
|
+
colorScheme={colorScheme}
|
|
348
|
+
variant={
|
|
349
|
+
user.connectionId === connectionId ? "up" : undefined
|
|
350
|
+
}
|
|
351
|
+
bordered={index !== array.length - 1}
|
|
352
|
+
style={{
|
|
353
|
+
opacity: user.inactive ? 0.5 : 1,
|
|
354
|
+
}}
|
|
355
|
+
>
|
|
356
|
+
{user.image && (
|
|
357
|
+
<img
|
|
358
|
+
src={user.image}
|
|
359
|
+
alt={user.name}
|
|
360
|
+
style={{
|
|
361
|
+
width: "13px",
|
|
362
|
+
height: "13px",
|
|
363
|
+
borderRadius: "50%",
|
|
364
|
+
marginRight: "4px",
|
|
365
|
+
display: "inline-block",
|
|
366
|
+
position: "relative",
|
|
367
|
+
background: solidBorderColor,
|
|
368
|
+
verticalAlign: "middle",
|
|
369
|
+
}}
|
|
370
|
+
/>
|
|
371
|
+
)}
|
|
372
|
+
{showUserDetails ? (
|
|
373
|
+
<ObjectInspector data={user} theme={theme} />
|
|
374
|
+
) : (
|
|
375
|
+
user.name
|
|
376
|
+
)}
|
|
377
|
+
</StateInspectorRow>
|
|
378
|
+
);
|
|
379
|
+
})}
|
|
348
380
|
{!connectedUsers && (
|
|
349
381
|
<div
|
|
350
382
|
style={{
|
|
@@ -767,6 +799,43 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
767
799
|
onTogglePaused={toggleServerLogsPaused}
|
|
768
800
|
containerRef={serverLogsContainerRef}
|
|
769
801
|
/>
|
|
802
|
+
{showSimulationLogsSection && (
|
|
803
|
+
<ServerScriptLogsSection
|
|
804
|
+
title="Server Script Simulation Logs"
|
|
805
|
+
colorScheme={colorScheme}
|
|
806
|
+
showLogs={showServerSimulationLogs}
|
|
807
|
+
setShowLogs={setShowServerSimulationLogs}
|
|
808
|
+
logs={visibleServerSimulationLogs}
|
|
809
|
+
paused={serverSimulationLogsPaused}
|
|
810
|
+
onTogglePaused={toggleServerSimulationLogsPaused}
|
|
811
|
+
containerRef={serverSimulationLogsContainerRef}
|
|
812
|
+
/>
|
|
813
|
+
)}
|
|
814
|
+
<StateInspectorDisclosureSection
|
|
815
|
+
open={showSimulation}
|
|
816
|
+
setOpen={setShowSimulation}
|
|
817
|
+
title="Server Simulation"
|
|
818
|
+
colorScheme={colorScheme}
|
|
819
|
+
>
|
|
820
|
+
<StateInspectorDisclosureRowInner>
|
|
821
|
+
<StateInspectorRow colorScheme={colorScheme}>
|
|
822
|
+
<ObjectInspector
|
|
823
|
+
name="status"
|
|
824
|
+
data={
|
|
825
|
+
simulationDiagnostics ?? {
|
|
826
|
+
simulateLocally: false,
|
|
827
|
+
simulatorActive: false,
|
|
828
|
+
clockSkewMs: 0,
|
|
829
|
+
invocations: [],
|
|
830
|
+
pendingPredictions: [],
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
theme={theme}
|
|
834
|
+
expandLevel={2}
|
|
835
|
+
/>
|
|
836
|
+
</StateInspectorRow>
|
|
837
|
+
</StateInspectorDisclosureRowInner>
|
|
838
|
+
</StateInspectorDisclosureSection>
|
|
770
839
|
{advanced && (
|
|
771
840
|
<ActivityEventsSection
|
|
772
841
|
colorScheme={colorScheme}
|
|
@@ -777,7 +846,9 @@ export const StateInspector = memoGeneric(function StateInspector<
|
|
|
777
846
|
/>
|
|
778
847
|
)}
|
|
779
848
|
<EventsSection<S>
|
|
780
|
-
connectionEvents={
|
|
849
|
+
connectionEvents={visibleConnectionEvents}
|
|
850
|
+
paused={connectionEventsPaused}
|
|
851
|
+
onTogglePaused={toggleConnectionEventsPaused}
|
|
781
852
|
colorScheme={colorScheme}
|
|
782
853
|
eventsContainerRef={eventsContainerRef}
|
|
783
854
|
showEvents={showEvents}
|
|
@@ -3,6 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { ObjectInspector, ObjectLabel } from "react-inspector";
|
|
4
4
|
import { getStateInspectorTheme } from "../inspectorTheme";
|
|
5
5
|
import { ObjectRootLabel } from "../ObjectRootLabel";
|
|
6
|
+
import { StateInspectorButton } from "../StateInspectorButton";
|
|
6
7
|
import {
|
|
7
8
|
StateInspectorDisclosureRowInner,
|
|
8
9
|
StateInspectorDisclosureSection,
|
|
@@ -15,12 +16,16 @@ export function EventsSection<S>({
|
|
|
15
16
|
colorScheme,
|
|
16
17
|
eventsContainerRef,
|
|
17
18
|
connectionEvents,
|
|
19
|
+
paused,
|
|
20
|
+
onTogglePaused,
|
|
18
21
|
}: {
|
|
19
22
|
showEvents: boolean;
|
|
20
23
|
setShowEvents: (value: boolean) => void;
|
|
21
24
|
colorScheme: "light" | "dark";
|
|
22
25
|
eventsContainerRef: React.RefObject<HTMLDivElement | null>;
|
|
23
26
|
connectionEvents: ConnectionEvent<S>[];
|
|
27
|
+
paused: boolean;
|
|
28
|
+
onTogglePaused: () => void;
|
|
24
29
|
}) {
|
|
25
30
|
const theme = getStateInspectorTheme(colorScheme);
|
|
26
31
|
|
|
@@ -30,8 +35,24 @@ export function EventsSection<S>({
|
|
|
30
35
|
setOpen={setShowEvents}
|
|
31
36
|
title="Events"
|
|
32
37
|
colorScheme={colorScheme}
|
|
38
|
+
right={
|
|
39
|
+
<StateInspectorButton theme={theme} onClick={onTogglePaused}>
|
|
40
|
+
{paused ? "Resume" : "Pause"}
|
|
41
|
+
</StateInspectorButton>
|
|
42
|
+
}
|
|
33
43
|
>
|
|
34
44
|
<StateInspectorDisclosureRowInner ref={eventsContainerRef}>
|
|
45
|
+
{paused && (
|
|
46
|
+
<div
|
|
47
|
+
style={{
|
|
48
|
+
padding: "4px 12px",
|
|
49
|
+
fontSize: "11px",
|
|
50
|
+
opacity: 0.7,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
Event streaming paused
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
35
56
|
{connectionEvents?.map((event, index) =>
|
|
36
57
|
event.type === "stateChange" ? (
|
|
37
58
|
<StateInspectorRow key={index} colorScheme={colorScheme}>
|
|
@@ -70,7 +91,7 @@ export function EventsSection<S>({
|
|
|
70
91
|
</StateInspectorRow>
|
|
71
92
|
)
|
|
72
93
|
)}
|
|
73
|
-
{!connectionEvents && (
|
|
94
|
+
{!connectionEvents?.length && (
|
|
74
95
|
<div
|
|
75
96
|
style={{
|
|
76
97
|
padding: "12px",
|
|
@@ -27,6 +27,7 @@ export function ServerScriptLogsSection({
|
|
|
27
27
|
containerRef,
|
|
28
28
|
paused,
|
|
29
29
|
onTogglePaused,
|
|
30
|
+
title = "Server Script Logs",
|
|
30
31
|
}: {
|
|
31
32
|
showLogs: boolean;
|
|
32
33
|
setShowLogs: (value: boolean) => void;
|
|
@@ -35,6 +36,7 @@ export function ServerScriptLogsSection({
|
|
|
35
36
|
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
36
37
|
paused: boolean;
|
|
37
38
|
onTogglePaused: () => void;
|
|
39
|
+
title?: string;
|
|
38
40
|
}) {
|
|
39
41
|
const theme = getStateInspectorTheme(colorScheme);
|
|
40
42
|
|
|
@@ -42,7 +44,7 @@ export function ServerScriptLogsSection({
|
|
|
42
44
|
<StateInspectorDisclosureSection
|
|
43
45
|
open={showLogs}
|
|
44
46
|
setOpen={setShowLogs}
|
|
45
|
-
title=
|
|
47
|
+
title={title}
|
|
46
48
|
colorScheme={colorScheme}
|
|
47
49
|
right={
|
|
48
50
|
<StateInspectorButton theme={theme} onClick={onTogglePaused}>
|
|
@@ -77,6 +79,20 @@ export function ServerScriptLogsSection({
|
|
|
77
79
|
>
|
|
78
80
|
<span>{formatTimestamp(log.timestamp)}</span>
|
|
79
81
|
<span style={{ color: levelColors[log.level] }}>{log.level}</span>
|
|
82
|
+
{(log.origin || log.target || log.mode) && (
|
|
83
|
+
<span
|
|
84
|
+
style={{
|
|
85
|
+
fontFamily: "monospace",
|
|
86
|
+
textTransform: "none",
|
|
87
|
+
fontSize: "10px",
|
|
88
|
+
opacity: 0.75,
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
{[log.origin ?? log.target, log.mode]
|
|
92
|
+
.filter(Boolean)
|
|
93
|
+
.join(" / ")}
|
|
94
|
+
</span>
|
|
95
|
+
)}
|
|
80
96
|
<span
|
|
81
97
|
style={{
|
|
82
98
|
fontFamily: "monospace",
|
|
@@ -100,7 +116,7 @@ export function ServerScriptLogsSection({
|
|
|
100
116
|
key={index}
|
|
101
117
|
data={value}
|
|
102
118
|
theme={theme}
|
|
103
|
-
expandLevel={3}
|
|
119
|
+
// expandLevel={3}
|
|
104
120
|
/>
|
|
105
121
|
))
|
|
106
122
|
) : (
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keeps a snapshot of items while paused, resuming updates when unpaused.
|
|
7
|
+
*/
|
|
8
|
+
export function usePausedStream<T>(items: T[] | undefined) {
|
|
9
|
+
const [paused, setPaused] = React.useState(false);
|
|
10
|
+
const [visibleItems, setVisibleItems] = React.useState(items ?? []);
|
|
11
|
+
|
|
12
|
+
const togglePaused = React.useCallback(() => {
|
|
13
|
+
setPaused((value) => {
|
|
14
|
+
if (!value) {
|
|
15
|
+
setVisibleItems(items ?? []);
|
|
16
|
+
}
|
|
17
|
+
return !value;
|
|
18
|
+
});
|
|
19
|
+
}, [items]);
|
|
20
|
+
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
if (paused) return;
|
|
23
|
+
|
|
24
|
+
setVisibleItems(items ?? []);
|
|
25
|
+
}, [items, paused]);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
paused,
|
|
29
|
+
setPaused,
|
|
30
|
+
togglePaused,
|
|
31
|
+
visibleItems,
|
|
32
|
+
};
|
|
33
|
+
}
|
package/src/singleton.tsx
CHANGED
|
@@ -67,9 +67,8 @@ export function initializeNoyaSingleton<
|
|
|
67
67
|
viewType,
|
|
68
68
|
offlineStorageKey,
|
|
69
69
|
multiplayerUrl,
|
|
70
|
-
serverScripts,
|
|
71
70
|
...managerOptions
|
|
72
|
-
} =
|
|
71
|
+
} = options ?? {};
|
|
73
72
|
|
|
74
73
|
const appData = getAppData<S>(
|
|
75
74
|
(initialState ?? null) as S | (() => S),
|
|
@@ -106,7 +105,7 @@ export function initializeNoyaSingleton<
|
|
|
106
105
|
multiplayerUrl: multiplayerUrl ?? appData.multiplayerUrl,
|
|
107
106
|
offlineStorageKey,
|
|
108
107
|
debug: managerOptions?.debug,
|
|
109
|
-
serverScripts,
|
|
108
|
+
serverScripts: managerOptions?.serverScripts,
|
|
110
109
|
policyAuthContext,
|
|
111
110
|
});
|
|
112
111
|
|