@socket-mesh/core 1.0.0 → 1.0.2

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.
@@ -1,10 +1,9 @@
1
1
  import ws from "isomorphic-ws";
2
- import { ClientRequest, IncomingMessage } from "http";
3
2
  import { MethodPacket, ServicePacket } from "./packet.js";
4
3
  import { AuthToken, SignedAuthToken } from "@socket-mesh/auth";
5
4
  import { AnyResponse } from "./response.js";
6
5
  import { SocketMap } from "./maps/socket-map.js";
7
- export type SocketEvent<T extends SocketMap> = AuthStateChangeEvent | RemoveAuthTokenEvent | AuthenticateEvent | BadAuthTokenEvent | CloseEvent | ConnectEvent | ConnectingEvent | DeauthenticateEvent | DisconnectEvent | ErrorEvent | MessageEvent | PingEvent | PongEvent | RequestEvent<T> | ResponseEvent<T> | UnexpectedResponseEvent | UpgradeEvent;
6
+ export type SocketEvent<T extends SocketMap> = AuthStateChangeEvent | RemoveAuthTokenEvent | AuthenticateEvent | BadAuthTokenEvent | CloseEvent | ConnectEvent | ConnectingEvent | DeauthenticateEvent | DisconnectEvent | ErrorEvent | MessageEvent | PingEvent | PongEvent | RequestEvent<T> | ResponseEvent<T>;
8
7
  export type AuthStateChangeEvent = AuthenticatedChangeEvent | DeauthenticatedChangeEvent;
9
8
  export interface AuthenticatedChangeEvent {
10
9
  isAuthenticated: true;
@@ -53,10 +52,8 @@ export interface MessageEvent {
53
52
  isBinary: boolean;
54
53
  }
55
54
  export interface PingEvent {
56
- data: Buffer;
57
55
  }
58
56
  export interface PongEvent {
59
- data: Buffer;
60
57
  }
61
58
  export interface RemoveAuthTokenEvent {
62
59
  oldAuthToken: SignedAuthToken;
@@ -67,10 +64,3 @@ export interface RequestEvent<T extends SocketMap> {
67
64
  export interface ResponseEvent<T extends SocketMap> {
68
65
  response: AnyResponse<T>;
69
66
  }
70
- export interface UnexpectedResponseEvent {
71
- request: ClientRequest;
72
- response: IncomingMessage;
73
- }
74
- export interface UpgradeEvent {
75
- request: IncomingMessage;
76
- }
@@ -3,7 +3,6 @@ import ws from "isomorphic-ws";
3
3
  import { Plugin } from "./plugins/plugin.js";
4
4
  import { AnyRequest, InvokeMethodRequest, InvokeServiceRequest, TransmitMethodRequest, TransmitServiceRequest } from "./request.js";
5
5
  import { AnyPacket } from "./packet.js";
6
- import { ClientRequest, IncomingMessage } from "http";
7
6
  import { FunctionReturnType, MethodMap, ServiceMap } from "./maps/method-map.js";
8
7
  import { AnyResponse } from "./response.js";
9
8
  import { AuthToken, SignedAuthToken } from "@socket-mesh/auth";
@@ -19,6 +18,10 @@ export interface InvokeServiceOptions<TServiceMap extends ServiceMap, TService e
19
18
  method: TMethod;
20
19
  ackTimeoutMs?: number | false;
21
20
  }
21
+ export interface InboundMessage<T extends SocketMap> {
22
+ timestamp: Date;
23
+ packet: (AnyPacket<T> | AnyResponse<T>) | (AnyPacket<T> | AnyResponse<T>)[];
24
+ }
22
25
  export declare class SocketTransport<T extends SocketMap> {
23
26
  private _socket;
24
27
  private _webSocket;
@@ -48,22 +51,21 @@ export declare class SocketTransport<T extends SocketMap> {
48
51
  getBackpressure(): number;
49
52
  getInboundBackpressure(): number;
50
53
  getOutboundBackpressure(): number;
51
- private handleInboudMessage;
54
+ protected handleInboudMessage({ packet, timestamp }: InboundMessage<T>): Promise<void>;
52
55
  protected onClose(code: number, reason?: Buffer | string): void;
53
56
  protected onDisconnect(status: SocketStatus, code: number, reason?: string): void;
54
57
  onError(error: Error): void;
55
58
  protected onInvoke<TService extends keyof T['Service'], TServiceMethod extends keyof T['Service'][TService], TMethod extends keyof T['Outgoing'], TPrivateMethod extends keyof T['PrivateOutgoing']>(request: InvokeMethodRequest<T["Outgoing"], TMethod> | InvokeMethodRequest<T["PrivateOutgoing"], TPrivateMethod> | InvokeServiceRequest<T["Service"], TService, TServiceMethod>): void;
56
- protected onMessage(data: ws.RawData, isBinary: boolean): void;
59
+ protected onMessage(data: ws.Data, isBinary: boolean): void;
57
60
  protected onOpen(): void;
58
- protected onPing(data: Buffer): void;
59
- protected onPong(data: Buffer): void;
61
+ protected onPingPong(): void;
60
62
  protected onRequest(packet: AnyPacket<T>, timestamp: Date, pluginError?: Error): Promise<boolean>;
61
63
  protected onResponse(response: AnyResponse<T>, pluginError?: Error): void;
64
+ private onSocketClose;
65
+ private onSocketError;
66
+ private onSocketMessage;
62
67
  protected onTransmit<TService extends keyof T['Service'], TServiceMethod extends keyof T['Service'][TService], TMethod extends keyof T['Outgoing']>(request: TransmitMethodRequest<T['Outgoing'], TMethod> | TransmitServiceRequest<T['Service'], TService, TServiceMethod>): void;
63
- protected onUnexpectedResponse(request: ClientRequest, response: IncomingMessage): void;
64
68
  protected onUnhandledRequest(packet: AnyPacket<T>): boolean;
65
- protected onUpgrade(request: IncomingMessage): void;
66
- ping(): Promise<void>;
67
69
  protected resetPingTimeout(timeoutMs: number | false, code: number): void;
68
70
  send(data: Buffer | string): Promise<void>;
69
71
  protected sendRequest(requests: (AnyRequest<T>)[]): void;
@@ -82,8 +82,7 @@ export class SocketTransport {
82
82
  getOutboundBackpressure() {
83
83
  return this._outboundPreparedMessageCount - this._outboundSentMessageCount;
84
84
  }
85
- async handleInboudMessage({ data, timestamp }) {
86
- let packet = this.decode(data);
85
+ async handleInboudMessage({ packet, timestamp }) {
87
86
  if (packet === null) {
88
87
  return;
89
88
  }
@@ -157,8 +156,13 @@ export class SocketTransport {
157
156
  this.sendRequest([request]);
158
157
  }
159
158
  onMessage(data, isBinary) {
159
+ data = isBinary ? data : data.toString();
160
+ if (data === '') {
161
+ this.onPingPong();
162
+ return;
163
+ }
160
164
  const timestamp = new Date();
161
- let p = Promise.resolve(isBinary ? data : data.toString());
165
+ let p = Promise.resolve(data);
162
166
  let resolve;
163
167
  let reject;
164
168
  const promise = new Promise((res, rej) => {
@@ -175,8 +179,9 @@ export class SocketTransport {
175
179
  }
176
180
  }
177
181
  p.then(data => {
182
+ const packet = this.decode(data);
178
183
  this._socket.emit('message', { data, isBinary });
179
- return this.handleInboudMessage({ data, timestamp });
184
+ return this.handleInboudMessage({ packet, timestamp });
180
185
  })
181
186
  .then(resolve)
182
187
  .catch(err => {
@@ -196,12 +201,7 @@ export class SocketTransport {
196
201
  }
197
202
  }
198
203
  }
199
- onPing(data) {
200
- this._socket.emit('ping', { data });
201
- }
202
- onPong(data) {
203
- this._socket.emit('pong', { data });
204
- }
204
+ onPingPong() { }
205
205
  async onRequest(packet, timestamp, pluginError) {
206
206
  this._socket.emit('request', { request: packet });
207
207
  const timeoutAt = typeof packet.ackTimeoutMs === 'number' ? new Date(timestamp.valueOf() + packet.ackTimeoutMs) : null;
@@ -273,33 +273,24 @@ export class SocketTransport {
273
273
  this._socket.emit('response', { response });
274
274
  }
275
275
  }
276
+ onSocketClose(event) {
277
+ this.onClose(event.code, event.reason);
278
+ }
279
+ onSocketError(event) {
280
+ this.onError(event.error);
281
+ }
282
+ onSocketMessage(event) {
283
+ this.onMessage(event.data, false);
284
+ }
276
285
  onTransmit(request) {
277
286
  this.sendRequest([request]);
278
287
  }
279
- onUnexpectedResponse(request, response) {
280
- this._socket.emit('unexpectedResponse', { request, response });
281
- }
282
288
  onUnhandledRequest(packet) {
283
289
  if (this._onUnhandledRequest) {
284
290
  return this._onUnhandledRequest(this, packet);
285
291
  }
286
292
  return false;
287
293
  }
288
- onUpgrade(request) {
289
- this._socket.emit('upgrade', { request });
290
- }
291
- ping() {
292
- return new Promise((resolve, reject) => {
293
- this.webSocket.ping(undefined, undefined, (err) => {
294
- if (err) {
295
- reject(err);
296
- }
297
- else {
298
- resolve();
299
- }
300
- });
301
- });
302
- }
303
294
  resetPingTimeout(timeoutMs, code) {
304
295
  if (this._pingTimeoutRef) {
305
296
  clearTimeout(this._pingTimeoutRef);
@@ -385,18 +376,24 @@ export class SocketTransport {
385
376
  const { promise, ...rest } = req;
386
377
  return rest;
387
378
  });
388
- this._webSocket.send(this.codecEngine.encode(encode.length === 1 ? encode[0] : encode), (err) => {
379
+ let sendErr;
380
+ this.send(this.codecEngine.encode(encode.length === 1 ? encode[0] : encode)).catch(err => {
381
+ sendErr = err;
382
+ }).then(() => {
383
+ const errCode = sendErr?.code;
389
384
  for (const req of requests) {
390
- if (err?.code === 'ECONNRESET') {
391
- err = new BadConnectionError(`Socket ${'callback' in req ? 'invoke' : 'transmit'} ${String(req.method)} event was aborted due to a bad connection`, 'connectAbort');
385
+ if (errCode === 'ECONNRESET') {
386
+ sendErr = new BadConnectionError(`Socket ${'callback' in req ? 'invoke' : 'transmit'} ${String(req.method)} event was aborted due to a bad connection`, 'connectAbort');
392
387
  }
393
388
  if (req.sentCallback) {
394
- req.sentCallback(err);
389
+ req.sentCallback(sendErr);
395
390
  }
396
- if (err && 'callback' in req) {
397
- req.callback(err);
391
+ if (sendErr && 'callback' in req) {
392
+ req.callback(sendErr);
398
393
  }
399
394
  }
395
+ }).catch(err => {
396
+ this.onError(err);
400
397
  });
401
398
  }
402
399
  sendResponse(index, responses) {
@@ -441,10 +438,8 @@ export class SocketTransport {
441
438
  }
442
439
  //timeoutId?: NodeJS.Timeout;
443
440
  //callback: (err: Error, result?: U) => void | null
444
- this._webSocket.send(this.codecEngine.encode(responses.length === 1 ? responses[0] : responses), (err) => {
445
- if (err) {
446
- this.onError(err);
447
- }
441
+ this.send(this.codecEngine.encode(responses.length === 1 ? responses[0] : responses)).catch(err => {
442
+ this.onError(err);
448
443
  });
449
444
  }
450
445
  async setAuthorization(signedAuthToken, authToken) {
@@ -639,33 +634,21 @@ export class SocketTransport {
639
634
  }
640
635
  set webSocket(value) {
641
636
  if (this._webSocket) {
642
- this._webSocket.off('open', this.onOpen);
643
- this._webSocket.off('close', this.onClose);
644
- this._webSocket.off('error', this.onError);
645
- this._webSocket.off('upgrade', this.onUpgrade);
646
- this._webSocket.off('message', this.onMessage);
647
- this._webSocket.off('ping', this.onPing);
648
- this._webSocket.off('pong', this.onPong);
649
- this._webSocket.off('unexpectedResponse', this.onUnexpectedResponse);
637
+ this._webSocket.onclose = null;
638
+ this._webSocket.onerror = null;
639
+ this._webSocket.onmessage = null;
640
+ this._webSocket.onopen = null;
641
+ delete this.onSocketClose;
642
+ delete this.onSocketError;
643
+ delete this.onSocketMessage;
650
644
  delete this.onOpen;
651
- delete this.onClose;
652
- delete this.onError;
653
- delete this.onUpgrade;
654
- delete this.onMessage;
655
- delete this.onPing;
656
- delete this.onPong;
657
- delete this.onUnexpectedResponse;
658
645
  }
659
646
  this._webSocket = value;
660
647
  if (value) {
661
- this._webSocket.on('open', this.onOpen = this.onOpen.bind(this));
662
- this._webSocket.on('close', this.onClose = this.onClose.bind(this));
663
- this._webSocket.on('error', this.onError = this.onError.bind(this));
664
- this._webSocket.on('upgrade', this.onUpgrade = this.onUpgrade.bind(this));
665
- this._webSocket.on('message', this.onMessage = this.onMessage.bind(this));
666
- this._webSocket.on('ping', this.onPing = this.onPing.bind(this));
667
- this._webSocket.on('pong', this.onPong = this.onPong.bind(this));
668
- this._webSocket.on('unexpectedResponse', this.onUnexpectedResponse = this.onUnexpectedResponse.bind(this));
648
+ this._webSocket.onclose = this.onSocketClose = this.onSocketClose.bind(this);
649
+ this._webSocket.onopen = this.onOpen = this.onOpen.bind(this);
650
+ this._webSocket.onerror = this.onSocketError = this.onSocketError.bind(this);
651
+ this._webSocket.onmessage = this.onSocketMessage = this.onSocketMessage.bind(this);
669
652
  }
670
653
  }
671
654
  }
package/dist/socket.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CodecEngine } from "@socket-mesh/formatter";
2
2
  import { AnyPacket } from "./packet.js";
3
3
  import { AsyncStreamEmitter } from "@socket-mesh/async-stream-emitter";
4
- import { SocketEvent, AuthenticateEvent, BadAuthTokenEvent, CloseEvent, ConnectEvent, DisconnectEvent, ErrorEvent, MessageEvent, PingEvent, PongEvent, RequestEvent, UnexpectedResponseEvent, UpgradeEvent, ResponseEvent, AuthStateChangeEvent, RemoveAuthTokenEvent, ConnectingEvent, DeauthenticateEvent } from "./socket-event.js";
4
+ import { SocketEvent, AuthenticateEvent, BadAuthTokenEvent, CloseEvent, ConnectEvent, DisconnectEvent, ErrorEvent, MessageEvent, PingEvent, PongEvent, RequestEvent, ResponseEvent, AuthStateChangeEvent, RemoveAuthTokenEvent, ConnectingEvent, DeauthenticateEvent } from "./socket-event.js";
5
5
  import { FunctionReturnType } from "./maps/method-map.js";
6
6
  import { HandlerMap } from "./maps/handler-map.js";
7
7
  import { CallIdGenerator, InvokeMethodOptions, InvokeServiceOptions, SocketTransport } from "./socket-transport.js";
@@ -51,8 +51,6 @@ export declare class Socket<T extends SocketMap> extends AsyncStreamEmitter<Sock
51
51
  emit(event: 'removeAuthToken', data: RemoveAuthTokenEvent): void;
52
52
  emit(event: 'request', data: RequestEvent<T>): void;
53
53
  emit(event: 'response', data: ResponseEvent<T>): void;
54
- emit(event: 'unexpectedResponse', data: UnexpectedResponseEvent): void;
55
- emit(event: 'upgrade', data: UpgradeEvent): void;
56
54
  listen(): DemuxedConsumableStream<StreamEvent<SocketEvent<T>>>;
57
55
  listen(event: 'authStateChange'): DemuxedConsumableStream<AuthStateChangeEvent>;
58
56
  listen(event: 'authenticate'): DemuxedConsumableStream<AuthenticateEvent>;
@@ -71,10 +69,7 @@ export declare class Socket<T extends SocketMap> extends AsyncStreamEmitter<Sock
71
69
  listen(event: 'removeAuthToken'): DemuxedConsumableStream<RemoveAuthTokenEvent>;
72
70
  listen(event: 'request'): DemuxedConsumableStream<RequestEvent<T>>;
73
71
  listen(event: 'response'): DemuxedConsumableStream<ResponseEvent<T>>;
74
- listen(event: 'unexpectedResponse'): DemuxedConsumableStream<UnexpectedResponseEvent>;
75
- listen(event: 'upgrade'): DemuxedConsumableStream<UpgradeEvent>;
76
72
  listen<U extends SocketEvent<T>, V = U>(event: string): DemuxedConsumableStream<V>;
77
- ping(): Promise<void>;
78
73
  get status(): SocketStatus;
79
74
  get url(): string;
80
75
  transmit<TMethod extends keyof T['Outgoing']>(method: TMethod, arg?: Parameters<T['Outgoing'][TMethod]>[0]): Promise<void>;
package/dist/socket.js CHANGED
@@ -36,9 +36,6 @@ export class Socket extends AsyncStreamEmitter {
36
36
  listen(event) {
37
37
  return super.listen(event);
38
38
  }
39
- ping() {
40
- return this._transport.ping();
41
- }
42
39
  get status() {
43
40
  return this._transport.status;
44
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socket-mesh/core",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Core module for SocketMesh Server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,10 +21,10 @@
21
21
  "homepage": "https://github.com/socket-mesh/main/tree/main/packages/core#README.md",
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "git+https://github.com/socket-mesh/auth.git"
24
+ "url": "git+https://github.com/socket-mesh/client-server.git"
25
25
  },
26
26
  "bugs": {
27
- "url": "https://github.com/socket-mesh/auth/issues"
27
+ "url": "https://github.com/socket-mesh/client-server/labels/core"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/base64id": "^2.0.2",