@nxtedition/deepstream.io-client-js 23.3.6 → 23.4.1

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": "@nxtedition/deepstream.io-client-js",
3
- "version": "23.3.6",
3
+ "version": "23.4.1",
4
4
  "description": "the javascript client for deepstream.io",
5
5
  "homepage": "http://deepstream.io",
6
6
  "bugs": {
@@ -1,11 +1,9 @@
1
1
  module.exports = {
2
- heartbeatInterval: 60e3,
3
2
  reconnectIntervalIncrement: 1e3,
4
3
  maxReconnectInterval: 6e3,
5
4
  maxReconnectAttempts: Infinity,
6
5
  maxPacketSize: 512 * 1024,
7
6
  batchSize: 4096,
8
- cacheSize: 4096,
9
7
  schedule: null,
10
8
  logger: null,
11
9
  }
@@ -32,8 +32,6 @@ const Connection = function (client, url, options) {
32
32
  this._reconnectTimeout = null
33
33
  this._reconnectionAttempt = 0
34
34
  this._endpoint = null
35
- this._lastHeartBeat = null
36
- this._heartbeatInterval = null
37
35
 
38
36
  this._processingRecv = false
39
37
  this._recvMessages = this._recvMessages.bind(this)
@@ -96,7 +94,7 @@ Connection.prototype.sendMsg2 = function (topic, action, p0, p1) {
96
94
  }
97
95
 
98
96
  Connection.prototype.close = function () {
99
- while (this._sendQueue.length) {
97
+ while (!this._sendQueue.isEmpty()) {
100
98
  this._submit(this._sendQueue.shift())
101
99
  }
102
100
  this._reset()
@@ -199,27 +197,8 @@ Connection.prototype._sendAuthParams = function () {
199
197
  this._submit(authMessage)
200
198
  }
201
199
 
202
- Connection.prototype._checkHeartBeat = function () {
203
- const heartBeatTolerance = this._options.heartbeatInterval * 3
204
-
205
- if (Date.now() - this._lastHeartBeat > heartBeatTolerance) {
206
- clearInterval(this._heartbeatInterval)
207
- this._endpoint.close()
208
- const err = new Error(`heartbeat not received in the last ${heartBeatTolerance} milliseconds`)
209
- this._client._$onError(C.TOPIC.CONNECTION, C.EVENT.CONNECTION_ERROR, err)
210
- } else {
211
- this._submit(messageBuilder.getMsg(C.TOPIC.CONNECTION, C.ACTIONS.PING))
212
- }
213
- }
214
-
215
200
  Connection.prototype._onOpen = function () {
216
201
  this._clearReconnect()
217
- this._lastHeartBeat = Date.now()
218
- this._heartbeatInterval = setInterval(
219
- this._checkHeartBeat.bind(this),
220
- this._options.heartbeatInterval
221
- )
222
- this._heartbeatInterval.unref?.()
223
202
  this._setState(C.CONNECTION_STATE.AWAITING_CONNECTION)
224
203
  }
225
204
 
@@ -306,20 +285,13 @@ Connection.prototype._recvMessages = function (deadline) {
306
285
  }
307
286
 
308
287
  Connection.prototype._reset = function () {
309
- clearInterval(this._heartbeatInterval)
310
- this._heartbeatInterval = null
311
- this._lastHeartBeat = null
312
-
313
288
  this._recvQueue = new FixedQueue()
314
289
  this._sendQueue = new FixedQueue()
315
290
  }
316
291
 
317
292
  Connection.prototype._handleConnectionResponse = function (message) {
318
293
  if (message.action === C.ACTIONS.PING) {
319
- this._lastHeartBeat = Date.now()
320
294
  this._submit(messageBuilder.getMsg(C.TOPIC.CONNECTION, C.ACTIONS.PONG))
321
- } else if (message.action === C.ACTIONS.PONG) {
322
- this._lastHeartBeat = Date.now()
323
295
  } else if (message.action === C.ACTIONS.ACK) {
324
296
  this._setState(C.CONNECTION_STATE.AWAITING_AUTHENTICATION)
325
297
  if (this._authParams) {
@@ -394,13 +366,10 @@ Connection.prototype._tryReconnect = function () {
394
366
 
395
367
  if (this._reconnectionAttempt < this._options.maxReconnectAttempts) {
396
368
  this._setState(C.CONNECTION_STATE.RECONNECTING)
397
- this._reconnectTimeout = setTimeout(
398
- this._tryOpen.bind(this),
399
- Math.min(
400
- this._options.maxReconnectInterval,
401
- this._options.reconnectIntervalIncrement * this._reconnectionAttempt
402
- )
403
- )
369
+ this._reconnectTimeout = setTimeout(() => {
370
+ this._reconnectTimeout = null
371
+ this._createEndpoint()
372
+ }, Math.min(this._options.maxReconnectInterval, this._options.reconnectIntervalIncrement * this._reconnectionAttempt))
404
373
  this._reconnectionAttempt++
405
374
  } else {
406
375
  this._clearReconnect()
@@ -409,14 +378,11 @@ Connection.prototype._tryReconnect = function () {
409
378
  }
410
379
  }
411
380
 
412
- Connection.prototype._tryOpen = function () {
413
- this._createEndpoint()
414
- this._reconnectTimeout = null
415
- }
416
-
417
381
  Connection.prototype._clearReconnect = function () {
418
- clearTimeout(this._reconnectTimeout)
419
- this._reconnectTimeout = null
382
+ if (this._reconnectTimeout) {
383
+ clearTimeout(this._reconnectTimeout)
384
+ this._reconnectTimeout = null
385
+ }
420
386
  this._reconnectionAttempt = 0
421
387
  }
422
388
 
@@ -24,7 +24,6 @@ class RecordHandler {
24
24
  this._records = new Map()
25
25
  this._listeners = new Map()
26
26
  this._prune = new Map()
27
- this._purge = new Set()
28
27
  this._patch = new Set()
29
28
  this._now = Date.now()
30
29
  this._pruning = false
@@ -34,8 +33,6 @@ class RecordHandler {
34
33
  updating: 0,
35
34
  }
36
35
 
37
- this._purgeCapacity = options.cacheSize
38
-
39
36
  this._syncEmitter = new EventEmitter()
40
37
 
41
38
  this.set = this.set.bind(this)
@@ -52,8 +49,6 @@ class RecordHandler {
52
49
  this._client.on(C.EVENT.CONNECTED, this._onConnectionStateChange.bind(this))
53
50
 
54
51
  const prune = () => {
55
- this._pruning = false
56
-
57
52
  let counter = 0
58
53
  for (const [rec, timestamp] of this._prune) {
59
54
  if (this._now - timestamp < 1e3) {
@@ -64,59 +59,26 @@ class RecordHandler {
64
59
  continue
65
60
  }
66
61
 
67
- invariant(rec._refs === 0, 'record must have no refs')
68
-
69
62
  rec._unsubscribe()
70
63
 
71
- this._purge.add(rec)
64
+ this._records.delete(rec.name)
72
65
  this._prune.delete(rec)
73
66
 
74
67
  if (counter++ > 1024) {
75
- this._pruning = true
76
68
  this._schedule(prune)
77
69
  return
78
70
  }
79
71
  }
80
- }
81
-
82
- const purge = () => {
83
- this._purging = false
84
72
 
85
- if (!this._connected) {
86
- return
87
- }
88
-
89
- let counter = 0
90
- for (const rec of this._purge) {
91
- if (this._purge.size < this._purgeCapacity) {
92
- return
93
- }
94
-
95
- invariant(rec._refs === 0, 'record must have no refs')
96
-
97
- this._records.delete(rec.name)
98
- this._purge.delete(rec)
99
-
100
- if (counter++ > 1024) {
101
- this._purging = true
102
- this._schedule(purge)
103
- return
104
- }
105
- }
73
+ this._pruning = false
106
74
  }
107
75
 
108
76
  const pruneInterval = setInterval(() => {
109
77
  this._now = Date.now()
110
-
111
78
  if (!this._pruning) {
112
79
  this._pruning = true
113
80
  this._schedule(prune)
114
81
  }
115
-
116
- if (!this._purging) {
117
- this._purging = true
118
- this._schedule(purge)
119
- }
120
82
  }, 1e3)
121
83
  pruneInterval.unref?.()
122
84
  }
@@ -125,7 +87,6 @@ class RecordHandler {
125
87
  if (rec.refs === 0) {
126
88
  this._prune.set(rec, this._now)
127
89
  } else if (rec.refs === 1) {
128
- this._purge.delete(rec)
129
90
  this._prune.delete(rec)
130
91
  }
131
92
  }
@@ -140,7 +101,6 @@ class RecordHandler {
140
101
  listeners: this._listeners.size,
141
102
  records: this._records.size,
142
103
  pruning: this._prune.size,
143
- purging: this._purge.size,
144
104
  }
145
105
  }
146
106
 
@@ -194,13 +154,19 @@ class RecordHandler {
194
154
  }
195
155
 
196
156
  sync(options) {
197
- return new Promise((resolve) => {
157
+ return new Promise((resolve, reject) => {
158
+ const timeoutValue = options?.timeout ?? 2 * 60e3
159
+ const signal = options?.signal
160
+
161
+ if (signal?.aborted) {
162
+ reject(new utils.AbortError())
163
+ return
164
+ }
165
+
198
166
  let done = false
199
167
  let token
200
- let timeout
168
+ let timeoutHandle
201
169
 
202
- const timeoutValue = 2 * 60e3
203
- const signal = options?.signal
204
170
  const records = [...this._patch]
205
171
 
206
172
  const onDone = (val) => {
@@ -212,9 +178,9 @@ class RecordHandler {
212
178
 
213
179
  signal?.removeEventListener('abort', onAbort)
214
180
 
215
- if (timeout) {
216
- clearTimeout(timeout)
217
- timeout = null
181
+ if (timeoutHandle) {
182
+ clearTimeout(timeoutHandle)
183
+ timeoutHandle = null
218
184
  }
219
185
 
220
186
  if (token) {
@@ -240,8 +206,8 @@ class RecordHandler {
240
206
  const onTimeout = () => {
241
207
  const elapsed = Date.now() - this._connected
242
208
  if (elapsed < timeoutValue) {
243
- timeout = setTimeout(onTimeout, timeoutValue - elapsed)
244
- timeout.unref?.()
209
+ timeoutHandle = setTimeout(onTimeout, timeoutValue - elapsed)
210
+ timeoutHandle.unref?.()
245
211
  } else {
246
212
  for (const rec of records.filter((rec) => !rec.isReady)) {
247
213
  this._client._$onError(C.TOPIC.RECORD, C.EVENT.TIMEOUT, 'record timeout', [
@@ -262,8 +228,10 @@ class RecordHandler {
262
228
  rec.ref()
263
229
  }
264
230
 
265
- timeout = setTimeout(onTimeout, 2 * 60e3)
266
- timeout.unref?.()
231
+ if (timeoutValue) {
232
+ timeoutHandle = setTimeout(onTimeout, timeoutValue)
233
+ timeoutHandle.unref?.()
234
+ }
267
235
 
268
236
  signal?.addEventListener('abort', onAbort)
269
237
 
@@ -337,7 +305,7 @@ class RecordHandler {
337
305
  let path
338
306
  let state = defaults ? defaults.state : undefined
339
307
  let signal
340
- let timeout = defaults ? defaults.timeout : undefined
308
+ let timeoutValue = defaults ? defaults.timeout : undefined
341
309
  let dataOnly = defaults ? defaults.dataOnly : undefined
342
310
 
343
311
  let idx = 0
@@ -356,7 +324,7 @@ class RecordHandler {
356
324
  signal = options.signal
357
325
 
358
326
  if (options.timeout != null) {
359
- timeout = options.timeout
327
+ timeoutValue = options.timeout
360
328
  }
361
329
 
362
330
  if (options.path != null) {
@@ -390,7 +358,11 @@ class RecordHandler {
390
358
  )
391
359
  }
392
360
 
393
- let x$ = new rxjs.Observable((o) => {
361
+ if (signal?.aborted) {
362
+ return rxjs.throwError(() => new utils.AbortError())
363
+ }
364
+
365
+ return new rxjs.Observable((o) => {
394
366
  let timeoutHandle
395
367
  let prevData = kEmpty
396
368
 
@@ -404,8 +376,9 @@ class RecordHandler {
404
376
  timeoutHandle = null
405
377
  }
406
378
 
379
+ const nextData = path ? record.get(path) : record.data
380
+
407
381
  if (dataOnly) {
408
- const nextData = record.get(path)
409
382
  if (nextData !== prevData) {
410
383
  prevData = nextData
411
384
  o.next(nextData)
@@ -414,27 +387,25 @@ class RecordHandler {
414
387
  o.next({
415
388
  name: record.name,
416
389
  version: record.version,
417
- data: record.get(path),
390
+ data: nextData,
418
391
  state: record.state,
419
392
  })
420
393
  }
421
394
  }
422
395
 
423
- const record = this.getRecord(name)
424
-
425
- record.subscribe(onUpdate)
396
+ const record = this.getRecord(name).subscribe(onUpdate)
426
397
 
427
- if (timeout && state && record.state < state) {
398
+ if (timeoutValue && state && record.state < state) {
428
399
  timeoutHandle = setTimeout(() => {
429
400
  const expected = C.RECORD_STATE_NAME[state]
430
401
  const current = C.RECORD_STATE_NAME[record.state]
431
402
  o.error(
432
403
  Object.assign(
433
- new Error(`timeout after ${timeout / 1e3}s: ${name} [${current}<${expected}]`),
404
+ new Error(`timeout after ${timeoutValue / 1e3}s: ${name} [${current}<${expected}]`),
434
405
  { code: 'ETIMEDOUT' }
435
406
  )
436
407
  )
437
- }, timeout)
408
+ }, timeoutValue)
438
409
  timeoutHandle.unref?.()
439
410
  }
440
411
 
@@ -442,19 +413,17 @@ class RecordHandler {
442
413
  onUpdate(record)
443
414
  }
444
415
 
445
- return () => {
446
- record.unsubscribe(onUpdate)
447
- record.unref()
416
+ const abort = () => {
417
+ o.error(new utils.AbortError())
448
418
  }
449
- })
450
419
 
451
- if (signal != null) {
452
- // TODO (perf): This a slow way to implement.
453
- x$ = signal.aborted ? rxjs.EMPTY : x$.pipe(rx.takeUntil(rxjs.fromEvent(signal, 'abort')))
454
- x$ = x$.pipe(rx.throwIfEmpty(() => new utils.AbortError()))
455
- }
420
+ signal?.addEventListener('abort', abort)
456
421
 
457
- return x$
422
+ return () => {
423
+ record.unsubscribe(onUpdate).unref()
424
+ signal?.removeEventListener('abort', abort)
425
+ }
426
+ })
458
427
  }
459
428
 
460
429
  _$handle(message) {
@@ -46,21 +46,29 @@ class Record {
46
46
 
47
47
  ref() {
48
48
  this._refs += 1
49
- this._handler._onRef(this)
50
49
  if (this._refs === 1) {
51
50
  this._subscribe()
52
51
  }
52
+
53
+ this._handler._onRef(this)
54
+
55
+ return this
53
56
  }
54
57
 
55
58
  unref() {
56
59
  invariant(this._refs > 0, this._name + ' missing refs')
57
60
 
58
61
  this._refs -= 1
62
+
59
63
  this._handler._onRef(this)
64
+
65
+ return this
60
66
  }
61
67
 
62
68
  subscribe(fn) {
63
69
  this._subscriptions.push(fn)
70
+
71
+ return this
64
72
  }
65
73
 
66
74
  unsubscribe(fn) {
@@ -68,10 +76,12 @@ class Record {
68
76
  if (idx !== -1) {
69
77
  this._subscriptions.splice(idx, 1)
70
78
  }
79
+
80
+ return this
71
81
  }
72
82
 
73
83
  get(path) {
74
- return jsonPath.get(this._data, path)
84
+ return path ? jsonPath.get(this._data, path) : this._data
75
85
  }
76
86
 
77
87
  set(pathOrData, dataOrNil) {
@@ -110,6 +120,7 @@ class Record {
110
120
  }
111
121
  }
112
122
 
123
+ // TODO (fix): timeout + signal
113
124
  when(stateOrNull) {
114
125
  invariant(this._refs > 0, this._name + ' missing refs')
115
126
 
@@ -130,8 +141,8 @@ class Record {
130
141
  return
131
142
  }
132
143
 
133
- this.unsubscribe(onUpdate)
134
144
  this.unref()
145
+ this.unsubscribe(onUpdate)
135
146
 
136
147
  resolve(null)
137
148
  }