@noya-app/noya-multiplayer-react 0.1.50 → 0.1.52

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.50",
3
+ "version": "0.1.52",
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.39",
15
+ "@noya-app/state-manager": "0.1.41",
16
16
  "@noya-app/emitter": "0.1.0",
17
17
  "@noya-app/observable": "0.1.5",
18
18
  "@noya-app/task-runner": "0.1.5",
19
- "@noya-app/react-utils": "0.1.15",
19
+ "@noya-app/react-utils": "0.1.16",
20
20
  "react-inspector": "6.0.2"
21
21
  },
22
22
  "peerDependencies": {
@@ -46,13 +46,14 @@ interface NoyaStateProviderProps<
46
46
  fallback?: React.ReactNode;
47
47
  }
48
48
 
49
- const AnyNoyaStateContext = createContext<
50
- | {
51
- noyaManager: NoyaManager<any, any, any, any>;
52
- theme: AppTheme;
53
- viewType: AppViewType;
54
- }
55
- | undefined
49
+ export type AnyNoyaStateContextValue = {
50
+ noyaManager: NoyaManager<any, any, any, any>;
51
+ theme: AppTheme;
52
+ viewType: AppViewType;
53
+ };
54
+
55
+ export const AnyNoyaStateContext = createContext<
56
+ AnyNoyaStateContextValue | undefined
56
57
  >(undefined);
57
58
 
58
59
  export function useAnyNoyaStateContext() {
@@ -172,9 +173,9 @@ export function useIsInitialized() {
172
173
  return useObservable(isInitializedObservable);
173
174
  }
174
175
 
175
- export function useWorkflowManager() {
176
+ export function usePipelineManager() {
176
177
  const { noyaManager } = useAnyNoyaStateContext();
177
- return noyaManager.workflowManager;
178
+ return noyaManager.pipelineManager;
178
179
  }
179
180
 
180
181
  export const ConnectedUsersContext = createContext<
@@ -32,9 +32,7 @@ export type ConnectionOptions<State> = {
32
32
 
33
33
  export class WebSocketConnection<State> {
34
34
  private ws: ReconnectingWebSocket;
35
- private pingCount = 0;
36
- private pendingPingId?: string;
37
- private intervalId?: NodeJS.Timer;
35
+ private closedForever = false;
38
36
 
39
37
  constructor(
40
38
  private url: URL,
@@ -50,38 +48,13 @@ export class WebSocketConnection<State> {
50
48
  }
51
49
 
52
50
  async connect() {
53
- this.ws.connect(this.url.toString());
54
-
55
- // Start ping interval
56
- this.intervalId = setInterval(() => {
57
- if (this.ws.state !== "OPEN") return;
58
-
59
- // A response to a previous ping hasn't been received, so we'll reset the connection
60
- if (this.pendingPingId) {
61
- this.ws.close();
62
- return;
63
- }
64
-
65
- const pingId = (this.pingCount++).toString();
51
+ if (this.closedForever) return;
66
52
 
67
- const message: ClientToServerMessage<State> = {
68
- type: "ping",
69
- id: pingId,
70
- };
71
-
72
- this.pendingPingId = message.id;
73
-
74
- this.options.onConnectionEvent?.({
75
- type: "send",
76
- message,
77
- });
78
-
79
- this.ws.send(JSON.stringify(message));
80
- }, 10000);
53
+ this.ws.connect(this.url.toString());
81
54
  }
82
55
 
83
56
  private handleOpen = () => {
84
- this.pendingPingId = undefined;
57
+ if (this.closedForever) return;
85
58
 
86
59
  if (this.options.debug) {
87
60
  console.info("ws connected");
@@ -94,6 +67,8 @@ export class WebSocketConnection<State> {
94
67
  };
95
68
 
96
69
  private handleMessage = (event: MessageEvent) => {
70
+ if (this.closedForever) return;
71
+
97
72
  if (this.options.debug) {
98
73
  console.info("ws receiving message ", event.data);
99
74
  }
@@ -104,14 +79,10 @@ export class WebSocketConnection<State> {
104
79
  type: "receive",
105
80
  message: parsed,
106
81
  });
107
-
108
- if (parsed.type === "pong" && parsed.id === this.pendingPingId) {
109
- this.pendingPingId = undefined;
110
- }
111
82
  };
112
83
 
113
84
  private handleClose = () => {
114
- this.pendingPingId = undefined;
85
+ if (this.closedForever) return;
115
86
 
116
87
  if (this.options.debug) {
117
88
  console.info("ws disconnected");
@@ -124,6 +95,8 @@ export class WebSocketConnection<State> {
124
95
  };
125
96
 
126
97
  send(message: ClientToServerMessage<State>) {
98
+ if (this.closedForever) return;
99
+
127
100
  if (this.options.debug) {
128
101
  console.info("ws sending message", message);
129
102
  }
@@ -137,10 +110,15 @@ export class WebSocketConnection<State> {
137
110
  }
138
111
 
139
112
  close() {
140
- if (this.intervalId) {
141
- clearInterval(this.intervalId);
142
- }
113
+ if (this.closedForever) return;
114
+
115
+ this.closedForever = true;
143
116
  this.ws.shutdown();
117
+
118
+ // remove all listeners
119
+ this.ws.listeners.forEach((listener) => {
120
+ this.ws.removeListener(listener);
121
+ });
144
122
  }
145
123
 
146
124
  addListener(listener: (state: ReconnectingWebSocketState) => void) {
package/src/ai.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { AIToolDefinition } from "@noya-app/state-manager";
2
+ import { useEffect } from "react";
3
+ import { useAIManager } from "./NoyaStateContext";
4
+ import { useObservable } from "./useObservable";
5
+
6
+ export function useRegisterAITool(tool: AIToolDefinition) {
7
+ const aiManager = useAIManager();
8
+
9
+ useEffect(() => {
10
+ return aiManager.registerTool(tool);
11
+ }, [aiManager, tool]);
12
+ }
13
+
14
+ export function useCallableAITools() {
15
+ const aiManager = useAIManager();
16
+ return useObservable(aiManager.callableTools$);
17
+ }
package/src/hooks.ts CHANGED
@@ -166,7 +166,7 @@ export function useMultiplayerState<
166
166
  assetManager: typeof noyaManager.assetManager;
167
167
  aiManager: typeof noyaManager.aiManager;
168
168
  rpcManager: typeof noyaManager.rpcManager;
169
- workflowManager: typeof noyaManager.workflowManager;
169
+ pipelineManager: typeof noyaManager.pipelineManager;
170
170
  secretManager: typeof noyaManager.secretManager;
171
171
  menuItemsManager: typeof noyaManager.menuManager;
172
172
  createAsset: typeof noyaManager.assetManager.create;
@@ -185,7 +185,7 @@ export function useMultiplayerState<
185
185
  assetManager: noyaManager.assetManager,
186
186
  aiManager: noyaManager.aiManager,
187
187
  rpcManager: noyaManager.rpcManager,
188
- workflowManager: noyaManager.workflowManager,
188
+ pipelineManager: noyaManager.pipelineManager,
189
189
  secretManager: noyaManager.secretManager,
190
190
  menuItemsManager: noyaManager.menuManager,
191
191
  createAsset: noyaManager.assetManager.create,
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "@noya-app/state-manager";
2
+ export * from "./ai";
2
3
  export * from "./components/UserPointersOverlay";
3
4
  export * from "./hooks";
4
5
  export * from "./inspector/StateInspector";