@push.rocks/smartsocket 3.0.0 → 4.0.0

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.
@@ -26,7 +26,7 @@ export interface ISocketConnectionConstructorOptions {
26
26
  authenticated: boolean;
27
27
  side: TSocketConnectionSide;
28
28
  smartsocketHost: Smartsocket | SmartsocketClient;
29
- socket: WebSocket | pluginsTyped.ws.WebSocket;
29
+ socket: pluginsTyped.TWebSocket | pluginsTyped.IWebSocketLike;
30
30
  }
31
31
 
32
32
  /**
@@ -47,7 +47,7 @@ export class SocketConnection {
47
47
  public side: TSocketConnectionSide;
48
48
  public authenticated: boolean = false;
49
49
  public smartsocketRef: Smartsocket | SmartsocketClient;
50
- public socket: WebSocket | pluginsTyped.ws.WebSocket;
50
+ public socket: pluginsTyped.TWebSocket | pluginsTyped.IWebSocketLike;
51
51
 
52
52
  public eventSubject = new plugins.smartrx.rxjs.Subject<interfaces.TConnectionStatus>();
53
53
  public eventStatus: interfaces.TConnectionStatus = 'new';
@@ -82,13 +82,13 @@ export class SocketConnection {
82
82
  public handleMessage(messageData: interfaces.ISocketMessage): void {
83
83
  switch (messageData.type) {
84
84
  case 'function':
85
- this.handleFunctionCall(messageData);
85
+ this.handleFunctionCall(messageData as interfaces.ISocketMessage<interfaces.IFunctionCallPayload>);
86
86
  break;
87
87
  case 'functionResponse':
88
- this.handleFunctionResponse(messageData);
88
+ this.handleFunctionResponse(messageData as interfaces.ISocketMessage<interfaces.IFunctionCallPayload>);
89
89
  break;
90
90
  case 'tagUpdate':
91
- this.handleTagUpdate(messageData);
91
+ this.handleTagUpdate(messageData as interfaces.ISocketMessage<interfaces.ITagUpdatePayload>);
92
92
  break;
93
93
  default:
94
94
  // Authentication messages are handled by the server/client classes
@@ -96,7 +96,7 @@ export class SocketConnection {
96
96
  }
97
97
  }
98
98
 
99
- private handleFunctionCall(messageData: interfaces.ISocketMessage): void {
99
+ private handleFunctionCall(messageData: interfaces.ISocketMessage<interfaces.IFunctionCallPayload>): void {
100
100
  const requestData: ISocketRequestDataObject<any> = {
101
101
  funcCallData: {
102
102
  funcName: messageData.payload.funcName,
@@ -123,7 +123,7 @@ export class SocketConnection {
123
123
  }
124
124
  }
125
125
 
126
- private handleFunctionResponse(messageData: interfaces.ISocketMessage): void {
126
+ private handleFunctionResponse(messageData: interfaces.ISocketMessage<interfaces.IFunctionCallPayload>): void {
127
127
  const responseData: ISocketRequestDataObject<any> = {
128
128
  funcCallData: {
129
129
  funcName: messageData.payload.funcName,
@@ -141,7 +141,7 @@ export class SocketConnection {
141
141
  }
142
142
  }
143
143
 
144
- private handleTagUpdate(messageData: interfaces.ISocketMessage): void {
144
+ private handleTagUpdate(messageData: interfaces.ISocketMessage<interfaces.ITagUpdatePayload>): void {
145
145
  const tagStoreArg = messageData.payload.tags as interfaces.TTagStore;
146
146
  if (!plugins.smartjson.deepEqualObjects(this.tagStore, tagStoreArg)) {
147
147
  this.tagStore = tagStoreArg;
@@ -181,17 +181,16 @@ export class SocketConnection {
181
181
  }
182
182
 
183
183
  /**
184
- * gets a tag by id
185
- * @param tagIdArg
184
+ * Gets a tag by id
186
185
  */
187
- public async getTagById(tagIdArg: interfaces.ITag['id']) {
186
+ public getTagById(tagIdArg: interfaces.ITag['id']): interfaces.ITag | undefined {
188
187
  return this.tagStore[tagIdArg];
189
188
  }
190
189
 
191
190
  /**
192
- * removes a tag from a connection
191
+ * Removes a tag from a connection
193
192
  */
194
- public async removeTagById(tagIdArg: interfaces.ITag['id']) {
193
+ public removeTagById(tagIdArg: interfaces.ITag['id']): void {
195
194
  delete this.tagStore[tagIdArg];
196
195
  this.tagStoreObservable.next(this.tagStore);
197
196
  this.sendMessage({
@@ -209,7 +208,7 @@ export class SocketConnection {
209
208
  const done = plugins.smartpromise.defer<SocketConnection>();
210
209
 
211
210
  // Set up message handler for authentication
212
- const messageHandler = (event: MessageEvent | { data: string }) => {
211
+ const messageHandler = (event: pluginsTyped.TMessageEvent) => {
213
212
  try {
214
213
  const data = typeof event.data === 'string' ? event.data : event.data.toString();
215
214
  const message: interfaces.ISocketMessage = JSON.parse(data);
@@ -241,11 +240,11 @@ export class SocketConnection {
241
240
  }
242
241
  }
243
242
  } catch (err) {
244
- // Not a valid message, ignore
243
+ logger.log('warn', `Failed to parse auth message: ${err instanceof Error ? err.message : String(err)}`);
245
244
  }
246
245
  };
247
246
 
248
- this.socket.addEventListener('message', messageHandler as any);
247
+ (this.socket as pluginsTyped.IWebSocketLike).addEventListener('message', messageHandler);
249
248
 
250
249
  // Request authentication
251
250
  const requestAuthPayload: interfaces.TAuthRequestMessage = {
@@ -268,17 +267,17 @@ export class SocketConnection {
268
267
  const done = plugins.smartpromise.defer();
269
268
  if (this.authenticated) {
270
269
  // Set up message handler for all messages
271
- const messageHandler = (event: MessageEvent | { data: string }) => {
270
+ const messageHandler = (event: pluginsTyped.TMessageEvent) => {
272
271
  try {
273
272
  const data = typeof event.data === 'string' ? event.data : event.data.toString();
274
273
  const message: interfaces.ISocketMessage = JSON.parse(data);
275
274
  this.handleMessage(message);
276
275
  } catch (err) {
277
- // Not a valid JSON message, ignore
276
+ logger.log('warn', `Failed to parse socket message: ${err instanceof Error ? err.message : String(err)}`);
278
277
  }
279
278
  };
280
279
 
281
- this.socket.addEventListener('message', messageHandler as any);
280
+ (this.socket as pluginsTyped.IWebSocketLike).addEventListener('message', messageHandler);
282
281
 
283
282
  logger.log(
284
283
  'info',
@@ -128,6 +128,10 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
128
128
  };
129
129
  this.originSocketConnection.sendMessage(message);
130
130
  this.smartsocketRef.socketRequests.remove(this);
131
+ })
132
+ .catch((error) => {
133
+ logger.log('error', `Function invocation failed for ${this.funcCallData.funcName}: ${error instanceof Error ? error.message : String(error)}`);
134
+ this.smartsocketRef.socketRequests.remove(this);
131
135
  });
132
136
  }
133
137
  }
@@ -114,7 +114,7 @@ export class SocketServer {
114
114
  onOpen: async (peer: pluginsTyped.ISmartserveWebSocketPeer) => {
115
115
  // Create a wrapper that adapts ISmartserveWebSocketPeer to WebSocket-like interface
116
116
  const wsLikeSocket = this.createWsLikeFromPeer(peer);
117
- await this.smartsocket.handleNewConnection(wsLikeSocket as any);
117
+ await this.smartsocket.handleNewConnection(wsLikeSocket);
118
118
  },
119
119
  onMessage: async (peer: pluginsTyped.ISmartserveWebSocketPeer, message: pluginsTyped.ISmartserveWebSocketMessage) => {
120
120
  // Dispatch message to the SocketConnection via the adapter
@@ -153,8 +153,8 @@ export class SocketServer {
153
153
  * Creates a WebSocket-like object from a smartserve peer
154
154
  * This allows our SocketConnection to work with both native WebSocket and smartserve peers
155
155
  */
156
- private createWsLikeFromPeer(peer: pluginsTyped.ISmartserveWebSocketPeer): any {
157
- const messageListeners: Array<(event: any) => void> = [];
156
+ private createWsLikeFromPeer(peer: pluginsTyped.ISmartserveWebSocketPeer): pluginsTyped.IWebSocketLike {
157
+ const messageListeners: Array<(event: pluginsTyped.TMessageEvent) => void> = [];
158
158
  const closeListeners: Array<() => void> = [];
159
159
  const errorListeners: Array<() => void> = [];
160
160
 
@@ -174,7 +174,7 @@ export class SocketServer {
174
174
  });
175
175
 
176
176
  return {
177
- readyState: peer.readyState,
177
+ get readyState() { return peer.readyState; },
178
178
  send: (data: string) => peer.send(data),
179
179
  close: (code?: number, reason?: string) => peer.close(code, reason),
180
180
  addEventListener: (event: string, listener: any) => {
@@ -13,6 +13,29 @@ export namespace ws {
13
13
  export type RawData = wsTypes.RawData;
14
14
  }
15
15
 
16
+ /**
17
+ * Unified WebSocket type supporting both browser and Node.js environments
18
+ */
19
+ export type TWebSocket = WebSocket | ws.WebSocket;
20
+
21
+ /**
22
+ * Message event type for WebSocket messages (browser and Node.js compatible)
23
+ */
24
+ export type TMessageEvent = MessageEvent | { data: string };
25
+
26
+ /**
27
+ * WebSocket-like interface for adapters (e.g., smartserve peer adapter)
28
+ */
29
+ export interface IWebSocketLike {
30
+ readyState: number;
31
+ send(data: string): void;
32
+ close(code?: number, reason?: string): void;
33
+ addEventListener(event: 'message', listener: (event: TMessageEvent) => void): void;
34
+ addEventListener(event: 'close', listener: () => void): void;
35
+ addEventListener(event: 'error', listener: () => void): void;
36
+ removeEventListener?(event: string, listener: (...args: any[]) => void): void;
37
+ }
38
+
16
39
  // smartserve compatibility interface (for setExternalServer)
17
40
  // This mirrors the IWebSocketPeer interface from smartserve
18
41
  export interface ISmartserveWebSocketPeer {