@noya-app/noya-multiplayer-react 0.1.53 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noya-app/noya-multiplayer-react",
3
- "version": "0.1.53",
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.42",
15
+ "@noya-app/state-manager": "0.1.44",
16
16
  "@noya-app/emitter": "0.1.0",
17
- "@noya-app/observable": "0.1.5",
18
- "@noya-app/task-runner": "0.1.5",
19
- "@noya-app/react-utils": "0.1.17",
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": {
@@ -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,
@@ -32,7 +33,7 @@ import {
32
33
  } from "./noyaApp";
33
34
  import { useObservable } from "./useObservable";
34
35
 
35
- interface NoyaStateProviderProps<
36
+ export interface NoyaStateProviderProps<
36
37
  S,
37
38
  M extends object,
38
39
  E extends object,
@@ -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 metadata = useObservable(ephemeralUserDataManager.metadata$, [
45
- user.id,
46
- ] as const);
47
- const data = useObservable(ephemeralUserDataManager.data$, [
48
- user.id,
49
- ] as const);
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
- > = MultiplayerStateManagerOptions<S, M> & {
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 = defaultStubSync as unknown as SyncAdapter<S, M, E, MenuT>,
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 ?? {};
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./ai";
3
3
  export * from "./components/UserPointersOverlay";
4
4
  export * from "./hooks";
5
5
  export * from "./inspector/StateInspector";
6
+ export * from "./inspector/useStateInspector";
6
7
  export * from "./noyaApp";
7
8
  export * from "./NoyaStateContext";
8
9
  export * from "./useObservable";
@@ -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
- <span style={{ width: "12px", height: "12px" }}>
80
- {showInspector === (anchor === "right") ? (
81
- <svg
82
- xmlns="http://www.w3.org/2000/svg"
83
- fill="none"
84
- viewBox="0 0 24 24"
85
- strokeWidth={1.5}
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.name)}
819
+ onClick={() => secretManager.deleteSecret(secret.id)}
810
820
  >
811
821
  Delete
812
822
  </SmallButton>