@sogni-ai/sogni-client 4.0.0-alpha.12 → 4.0.0-alpha.13

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/Account/index.d.ts +1 -0
  3. package/dist/Account/index.js +11 -2
  4. package/dist/Account/index.js.map +1 -1
  5. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/BrowserWebSocketClient.d.ts +34 -0
  6. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/BrowserWebSocketClient.js +195 -0
  7. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/BrowserWebSocketClient.js.map +1 -0
  8. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/WSCoordinator.d.ts +101 -0
  9. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/WSCoordinator.js +359 -0
  10. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/WSCoordinator.js.map +1 -0
  11. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/types.d.ts +101 -0
  12. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/types.js +3 -0
  13. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/types.js.map +1 -0
  14. package/dist/ApiClient/WebSocketClient/events.d.ts +1 -0
  15. package/dist/ApiClient/WebSocketClient/index.d.ts +2 -2
  16. package/dist/ApiClient/WebSocketClient/types.d.ts +13 -0
  17. package/dist/ApiClient/index.d.ts +2 -3
  18. package/dist/ApiClient/index.js +20 -2
  19. package/dist/ApiClient/index.js.map +1 -1
  20. package/dist/Projects/Job.d.ts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +6 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/DataEntity.js +4 -2
  25. package/dist/lib/DataEntity.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/Account/index.ts +11 -2
  28. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/BrowserWebSocketClient.ts +206 -0
  29. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/WSCoordinator.ts +425 -0
  30. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/types.ts +107 -0
  31. package/src/ApiClient/WebSocketClient/events.ts +2 -0
  32. package/src/ApiClient/WebSocketClient/index.ts +2 -2
  33. package/src/ApiClient/WebSocketClient/types.ts +16 -0
  34. package/src/ApiClient/index.ts +25 -6
  35. package/src/index.ts +7 -3
  36. package/src/lib/DataEntity.ts +4 -2
@@ -18,9 +18,11 @@ class DataEntity extends TypedEventEmitter_1.default {
18
18
  _update(delta) {
19
19
  //@ts-ignore
20
20
  const changedKeys = Object.keys(delta).filter((key) => this.data[key] !== delta[key]);
21
- this.data = Object.assign(Object.assign({}, this.data), delta);
22
21
  this.lastUpdated = new Date();
23
- this.emit('updated', changedKeys);
22
+ if (changedKeys.length > 0) {
23
+ this.data = Object.assign(Object.assign({}, this.data), delta);
24
+ this.emit('updated', changedKeys);
25
+ }
24
26
  }
25
27
  /**
26
28
  * Get a copy of the entity's data
@@ -1 +1 @@
1
- {"version":3,"file":"DataEntity.js","sourceRoot":"","sources":["../../src/lib/DataEntity.ts"],"names":[],"mappings":";;;;;AAAA,mCAAmC;AACnC,4EAAoD;AASpD,MAAe,UAAqD,SAAQ,2BAAoB;IAK9F,YAAY,IAAO;QACjB,KAAK,EAAE,CAAC;QAHA,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAIvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAiB;QACvB,YAAY;QACZ,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,mCAAQ,IAAI,CAAC,IAAI,GAAK,KAAK,CAAE,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAA,kBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,kBAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"DataEntity.js","sourceRoot":"","sources":["../../src/lib/DataEntity.ts"],"names":[],"mappings":";;;;;AAAA,mCAAmC;AACnC,4EAAoD;AASpD,MAAe,UAAqD,SAAQ,2BAAoB;IAK9F,YAAY,IAAO;QACjB,KAAK,EAAE,CAAC;QAHA,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAIvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAiB;QACvB,YAAY;QACZ,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,mCAAQ,IAAI,CAAC,IAAI,GAAK,KAAK,CAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAA,kBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,kBAAe,UAAU,CAAC"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "4.0.0-alpha.12",
6
+ "version": "4.0.0-alpha.13",
7
7
  "description": "Sogni Supernet Client",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -43,7 +43,12 @@ class AccountApi extends ApiGroup {
43
43
 
44
44
  constructor(config: ApiConfig) {
45
45
  super(config);
46
+ this.currentAccount._update({
47
+ networkStatus: this.client.socket.isConnected ? 'connected' : 'disconnected',
48
+ network: this.client.socket.supernetType
49
+ });
46
50
  this.client.socket.on('balanceUpdate', this.handleBalanceUpdate.bind(this));
51
+ this.client.socket.on('changeNetwork', this.handleChangeNetwork.bind(this));
47
52
  this.client.on('connected', this.handleServerConnected.bind(this));
48
53
  this.client.on('disconnected', this.handleServerDisconnected.bind(this));
49
54
  this.client.auth.on('updated', this.handleAuthUpdated.bind(this));
@@ -53,6 +58,10 @@ class AccountApi extends ApiGroup {
53
58
  this.currentAccount._update({ balance: data });
54
59
  }
55
60
 
61
+ private handleChangeNetwork({ network }: { network: SupernetType }) {
62
+ this.currentAccount._update({ network, networkStatus: 'connected' });
63
+ }
64
+
56
65
  private handleServerConnected({ network }: { network: SupernetType }) {
57
66
  this.currentAccount._update({
58
67
  networkStatus: 'connected',
@@ -70,6 +79,8 @@ class AccountApi extends ApiGroup {
70
79
  private handleAuthUpdated(isAuthenticated: boolean) {
71
80
  if (!isAuthenticated) {
72
81
  this.currentAccount._clear();
82
+ } else {
83
+ this.me();
73
84
  }
74
85
  }
75
86
 
@@ -137,7 +148,6 @@ class AccountApi extends ApiGroup {
137
148
  } else {
138
149
  await auth.authenticate();
139
150
  }
140
- await this.me();
141
151
  return res.data;
142
152
  }
143
153
 
@@ -173,7 +183,6 @@ class AccountApi extends ApiGroup {
173
183
  } else {
174
184
  await auth.authenticate();
175
185
  }
176
- await this.me();
177
186
  return res.data;
178
187
  }
179
188
 
@@ -0,0 +1,206 @@
1
+ import { IWebSocketClient, SupernetType } from '../types';
2
+ import { AuthManager, TokenAuthManager } from '../../../lib/AuthManager';
3
+ import { Logger } from '../../../lib/DefaultLogger';
4
+ import WebSocketClient from '../index';
5
+ import RestClient from '../../../lib/RestClient';
6
+ import { ServerDisconnectData, SocketEventMap } from '../events';
7
+ import WSCoordinator from './WSCoordinator';
8
+ import { MessageType, SocketMessageMap } from '../messages';
9
+ import { Heartbeat, SocketEventReceived, SendSocketMessage } from './types';
10
+
11
+ type EventInterceptor<T extends keyof SocketEventMap = keyof SocketEventMap> = (
12
+ eventType: T,
13
+ payload: SocketEventMap[T]
14
+ ) => void;
15
+
16
+ class WrappedClient extends WebSocketClient {
17
+ private interceptor: EventInterceptor | undefined = undefined;
18
+ intercept(interceptor: EventInterceptor) {
19
+ this.interceptor = interceptor;
20
+ }
21
+ protected emit<T extends keyof SocketEventMap>(event: T, data: SocketEventMap[T]) {
22
+ super.emit(event, data);
23
+ if (this.interceptor) {
24
+ this.interceptor(event, data);
25
+ }
26
+ }
27
+ }
28
+
29
+ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebSocketClient {
30
+ appId: string;
31
+ baseUrl: string;
32
+ private socketClient: WrappedClient;
33
+ private coordinator: WSCoordinator;
34
+ private isPrimary = false;
35
+ private _isConnected = false;
36
+ private _supernetType: SupernetType;
37
+
38
+ constructor(
39
+ baseUrl: string,
40
+ auth: AuthManager,
41
+ appId: string,
42
+ supernetType: SupernetType,
43
+ logger: Logger
44
+ ) {
45
+ const socketClient = new WrappedClient(baseUrl, auth, appId, supernetType, logger);
46
+ super(socketClient.baseUrl, auth, logger);
47
+ this.socketClient = socketClient;
48
+ this.appId = appId;
49
+ this.baseUrl = socketClient.baseUrl;
50
+ this._supernetType = supernetType;
51
+ this.coordinator = new WSCoordinator(
52
+ {
53
+ onAuthChanged: this.handleAuthChanged.bind(this),
54
+ onRoleChange: this.handleRoleChange.bind(this),
55
+ onConnectionToggle: this.handleConnectionToggle.bind(this),
56
+ onMessageFromPrimary: this.handleMessageFromPrimary.bind(this),
57
+ onSendRequest: this.handleSendRequest.bind(this)
58
+ },
59
+ logger
60
+ );
61
+ this.auth.on('updated', this.handleAuthUpdated.bind(this));
62
+ this.socketClient.intercept(this.handleSocketEvent.bind(this));
63
+ }
64
+
65
+ get isConnected() {
66
+ return this.isPrimary ? this.socketClient.isConnected : this._isConnected;
67
+ }
68
+
69
+ get supernetType() {
70
+ return this.isPrimary ? this.socketClient.supernetType : this._supernetType;
71
+ }
72
+
73
+ async connect(): Promise<void> {
74
+ const isPrimary = await this.coordinator.initialize();
75
+ this.isPrimary = isPrimary;
76
+ if (isPrimary) {
77
+ await this.socketClient.connect();
78
+ } else {
79
+ this.coordinator.connect();
80
+ }
81
+ }
82
+
83
+ disconnect() {
84
+ if (this.isPrimary) {
85
+ this.socketClient.disconnect();
86
+ } else {
87
+ this.coordinator.disconnect();
88
+ }
89
+ }
90
+
91
+ async switchNetwork(supernetType: SupernetType): Promise<SupernetType> {
92
+ if (this.isPrimary) {
93
+ return this.socketClient.switchNetwork(supernetType);
94
+ }
95
+ return new Promise<SupernetType>(async (resolve) => {
96
+ this.once('changeNetwork', ({ network }) => {
97
+ this._supernetType = network;
98
+ resolve(network);
99
+ });
100
+ await this.send('changeNetwork', supernetType);
101
+ });
102
+ }
103
+
104
+ async send<T extends MessageType>(messageType: T, data: SocketMessageMap[T]): Promise<void> {
105
+ if (this.isPrimary) {
106
+ return this.socketClient.send(messageType, data);
107
+ }
108
+ return this.coordinator.sendToSocket(messageType, data);
109
+ }
110
+
111
+ private handleAuthChanged(isAuthenticated: boolean) {
112
+ if (this.auth instanceof TokenAuthManager) {
113
+ throw new Error('TokenAuthManager is not supported in multi client mode');
114
+ }
115
+ if (this.auth.isAuthenticated !== isAuthenticated) {
116
+ if (isAuthenticated) {
117
+ this.auth.authenticate();
118
+ } else {
119
+ this.auth.clear();
120
+ }
121
+ }
122
+ }
123
+
124
+ private handleSocketEvent(eventType: keyof SocketEventMap, payload: any) {
125
+ if (this.isPrimary) {
126
+ this.coordinator.broadcastSocketEvent(eventType, payload);
127
+ this.emit(eventType, payload);
128
+ }
129
+ }
130
+
131
+ private handleAuthUpdated(isAuthenticated: boolean) {
132
+ this.coordinator.changeAuthState(isAuthenticated);
133
+ }
134
+
135
+ private handleRoleChange(isPrimary: boolean) {
136
+ this.isPrimary = isPrimary;
137
+ if (isPrimary && !this.socketClient.isConnected && this.isConnected) {
138
+ this.socketClient.connect();
139
+ } else if (!isPrimary && this.socketClient.isConnected) {
140
+ this.socketClient.disconnect();
141
+ }
142
+ }
143
+
144
+ private handleConnectionToggle(isConnected: boolean) {
145
+ if (this.isPrimary) {
146
+ if (isConnected && !this.socketClient.isConnected) {
147
+ this.socketClient.connect();
148
+ } else if (!isConnected && this.socketClient.isConnected) {
149
+ this.socketClient.disconnect();
150
+ }
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Emit events from socket to listeners
156
+ * @param message
157
+ */
158
+ private handleMessageFromPrimary(message: SocketEventReceived | Heartbeat) {
159
+ if (this.isPrimary) {
160
+ throw new Error('Received message from primary socket, but it is primary');
161
+ }
162
+ this._logger.debug('Received message from primary client:', message.type, message.payload);
163
+ if (message.type === 'primary-present') {
164
+ const shouldUpdateStatus = message.payload.connected !== this._isConnected;
165
+ if (shouldUpdateStatus) {
166
+ this._isConnected = message.payload.connected;
167
+ if (message.payload.connected) {
168
+ this._logger.debug('Primary socket is active emitting connected event');
169
+ this.emit('connected', { network: this._supernetType });
170
+ } else {
171
+ this._logger.debug('Primary socket is inactive emitting disconnected event');
172
+ this.emit('disconnected', { code: 5000, reason: 'Primary socket disconnected' });
173
+ }
174
+ }
175
+ return;
176
+ }
177
+ const event = message.payload;
178
+ switch (event.eventType) {
179
+ case 'connected': {
180
+ if (!this._isConnected) {
181
+ this._isConnected = true;
182
+ this.emit('connected', { network: this._supernetType });
183
+ }
184
+ return;
185
+ }
186
+ case 'disconnected': {
187
+ this._isConnected = false;
188
+ this.emit('disconnected', event.payload as ServerDisconnectData);
189
+ return;
190
+ }
191
+ default: {
192
+ this.emit(event.eventType, event.payload as any);
193
+ }
194
+ }
195
+ }
196
+
197
+ private handleSendRequest(message: SendSocketMessage) {
198
+ if (!this.isPrimary) {
199
+ // Should never happen, but just in case
200
+ return Promise.resolve();
201
+ }
202
+ return this.socketClient.send(message.payload.messageType, message.payload.data);
203
+ }
204
+ }
205
+
206
+ export default BrowserWebSocketClient;