@brokerize/client 1.3.6 → 1.3.7

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.
@@ -53,6 +53,9 @@ export class AuthorizedApiContext {
53
53
  }
54
54
  this._abortController = cfg.createAbortController();
55
55
  this._wsClient = wsClient || this._initInternalWebSocketClient();
56
+ if (this._wsClient._setAuthorizedApiContext) {
57
+ this._wsClient._setAuthorizedApiContext(this);
58
+ }
56
59
  this._cache = {};
57
60
  }
58
61
  createChildContext() {
@@ -1,4 +1,5 @@
1
1
  import { Auth } from "./apiCtx";
2
+ import { AuthorizedApiContext } from "./authorizedApiContext";
2
3
  import { WebSocket } from "./dependencyDefinitions/webSocket";
3
4
  import type { SubscribeDecoupledOperation, SubscribeInvalidateDetails } from "./websocketTypes";
4
5
  export declare class BrokerizeWebSocketClientImpl implements BrokerizeWebSocketClient {
@@ -16,6 +17,7 @@ export declare class BrokerizeWebSocketClientImpl implements BrokerizeWebSocketC
16
17
  private _fatalError;
17
18
  private _lastNonFatalError;
18
19
  private _errorCount;
20
+ private _apiCtx;
19
21
  constructor(websocketUrl: string, auth: Auth, createWebSocket: (url: string) => WebSocket);
20
22
  private _updateReconnectInterval;
21
23
  /**
@@ -27,7 +29,13 @@ export declare class BrokerizeWebSocketClientImpl implements BrokerizeWebSocketC
27
29
  subscribeInvalidate(subscribe: SubscribeInvalidateDetails, callback: Callback): Subscription;
28
30
  subscribeDecoupledOperation(subscribe: Pick<SubscribeDecoupledOperation, "sessionId" | "decoupledOperationId">, callback: Callback): Subscription;
29
31
  private _startSubscription;
32
+ private _fillInMessagesAfterConnectionInterruption;
30
33
  private _endSubscription;
34
+ /**
35
+ * Internal method for setting a related AuthorizedApiContext. This is used to retrieve
36
+ * decoupled operation status on interrupted connections.
37
+ */
38
+ _setAuthorizedApiContext(ctx: AuthorizedApiContext): void;
31
39
  _startOrStopDisconnectTimeout(): void;
32
40
  private _sendWs;
33
41
  private _connect;
@@ -8,6 +8,7 @@ export class BrokerizeWebSocketClientImpl {
8
8
  this._fatalError = null;
9
9
  this._lastNonFatalError = null;
10
10
  this._errorCount = 0;
11
+ this._apiCtx = null;
11
12
  this._url = websocketUrl;
12
13
  this._id = 0;
13
14
  this._socket = null;
@@ -26,7 +27,6 @@ export class BrokerizeWebSocketClientImpl {
26
27
  this._reconnectIntvl = setInterval(() => {
27
28
  if (!this._socket && this._shouldConnect()) {
28
29
  if (this._errorCount > 0) {
29
- // eslint-disable-next-line no-console
30
30
  console.warn(LOG_PREFIX +
31
31
  "reconnecting. current error count is " +
32
32
  this._errorCount +
@@ -76,6 +76,7 @@ export class BrokerizeWebSocketClientImpl {
76
76
  this._map[key] = {
77
77
  callbacks: [wrappedCb],
78
78
  idOnSocket: null,
79
+ interrupted: false,
79
80
  };
80
81
  }
81
82
  else {
@@ -121,11 +122,47 @@ export class BrokerizeWebSocketClientImpl {
121
122
  const cmd = JSON.parse(key);
122
123
  cmd.subscriptionId = this._id;
123
124
  this._sendWs(cmd, true);
125
+ if (this._map[key].interrupted) {
126
+ this._map[key].interrupted = false;
127
+ this._fillInMessagesAfterConnectionInterruption(cmd, this._map[key].callbacks);
128
+ }
124
129
  }
125
130
  else if (!this._socket) {
126
131
  this._connect();
127
132
  }
128
133
  }
134
+ _fillInMessagesAfterConnectionInterruption(cmd, callbacks) {
135
+ if (cmd.type == "invalidate") {
136
+ const assumedInvalidate = {
137
+ cmd: "invalidate",
138
+ subscriptionId: cmd.subscriptionId,
139
+ }; // minimal invalidate
140
+ console.log(LOG_PREFIX +
141
+ "connection was interrupted. filling in assumed invalidates that may have happened while socket was not available.");
142
+ callbacks.forEach((cb) => cb(null, assumedInvalidate));
143
+ }
144
+ else if (cmd.type == "decoupledOperationStatus") {
145
+ if (this._apiCtx) {
146
+ this._apiCtx
147
+ .getDecoupledOperationStatus({
148
+ decoupledOperationId: cmd.decoupledOperationId,
149
+ })
150
+ .then((status) => {
151
+ const invMsg = {
152
+ cmd: "updateDecoupledOperationStatus",
153
+ status: status,
154
+ subscriptionId: cmd.subscriptionId,
155
+ };
156
+ console.log(LOG_PREFIX +
157
+ "sending virtual decoupled operation status updates to subscribers due to connection interruption.");
158
+ callbacks.forEach((cb) => cb(null, invMsg));
159
+ }, (err) => {
160
+ console.log(err, LOG_PREFIX +
161
+ "could not retrieve status of decoupledOperation. ignoring it.");
162
+ });
163
+ }
164
+ }
165
+ }
129
166
  _endSubscription(key) {
130
167
  if (this._map[key].idOnSocket != null) {
131
168
  this._sendWs({
@@ -135,6 +172,13 @@ export class BrokerizeWebSocketClientImpl {
135
172
  this._map[key].idOnSocket = null;
136
173
  }
137
174
  }
175
+ /**
176
+ * Internal method for setting a related AuthorizedApiContext. This is used to retrieve
177
+ * decoupled operation status on interrupted connections.
178
+ */
179
+ _setAuthorizedApiContext(ctx) {
180
+ this._apiCtx = ctx;
181
+ }
138
182
  _startOrStopDisconnectTimeout() {
139
183
  if (this._shouldConnect()) {
140
184
  if (this._disconnectTimeout) {
@@ -163,7 +207,6 @@ export class BrokerizeWebSocketClientImpl {
163
207
  (_b = this._socket) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify(data));
164
208
  }
165
209
  else {
166
- // eslint-disable-next-line no-console
167
210
  console.log(LOG_PREFIX + "socket not ready, not sending message.", this._lastNonFatalError, this._fatalError);
168
211
  }
169
212
  }
@@ -237,15 +280,16 @@ export class BrokerizeWebSocketClientImpl {
237
280
  _authCb();
238
281
  }
239
282
  }, (err) => {
240
- // eslint-disable-next-line no-console
241
283
  console.error(LOG_PREFIX + " connection failed", err);
242
284
  });
243
285
  };
244
286
  this._socket.onclose = () => {
245
- this._socket = null;
287
+ // mark all subscriptions interrupted so they can issue synthetic messages on reconnect
246
288
  for (const k in this._map) {
289
+ this._map[k].interrupted = true;
247
290
  this._endSubscription(k);
248
291
  }
292
+ this._socket = null;
249
293
  };
250
294
  this._pingIntvl && clearInterval(this._pingIntvl);
251
295
  this._pingIntvl = setInterval(() => {
@@ -292,7 +336,6 @@ export class BrokerizeWebSocketClientImpl {
292
336
  cb(this._fatalError, null);
293
337
  }
294
338
  catch (err) {
295
- // eslint-disable-next-line no-console
296
339
  console.warn(LOG_PREFIX + "error in callback", err);
297
340
  }
298
341
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brokerize/client",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "description": "Client for the brokerize.com API",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/brokerize/client-js#readme",