@nxtedition/deepstream.io-client-js 24.1.19 → 24.1.21

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": "24.1.19",
3
+ "version": "24.1.21",
4
4
  "description": "the javascript client for deepstream.io",
5
5
  "homepage": "http://deepstream.io",
6
6
  "bugs": {
@@ -52,9 +52,9 @@ function onTimeout(subscription) {
52
52
  }
53
53
 
54
54
  function onUpdateFast(rec, opaque) {
55
- const { timeout, resolve } = opaque
55
+ const { timeout, resolve, synced, state } = opaque
56
56
 
57
- if (rec.state >= opaque.state) {
57
+ if (rec.state >= state && synced) {
58
58
  timers.clearTimeout(timeout)
59
59
  rec.unsubscribe(onUpdateFast, opaque)
60
60
  rec.unref()
@@ -62,6 +62,11 @@ function onUpdateFast(rec, opaque) {
62
62
  }
63
63
  }
64
64
 
65
+ function onSyncFast(opaque) {
66
+ opaque.synced = true
67
+ onUpdateFast(opaque.rec, opaque)
68
+ }
69
+
65
70
  function onTimeoutFast(opaque) {
66
71
  const { rec, resolve } = opaque
67
72
  rec.unsubscribe(onUpdateFast, opaque)
@@ -100,6 +105,7 @@ class RecordHandler {
100
105
  patching: 0,
101
106
  }
102
107
 
108
+ this._syncQueue = []
103
109
  this._syncEmitter = new EventEmitter()
104
110
  this._readyEmitter = new EventEmitter()
105
111
 
@@ -343,6 +349,27 @@ class RecordHandler {
343
349
  }
344
350
  }
345
351
 
352
+ _sync(callback, opaque) {
353
+ this._syncQueue.push(callback, opaque)
354
+
355
+ if (this._syncQueue.length > 2) {
356
+ return
357
+ }
358
+
359
+ setImmediate(() => {
360
+ // Token must be universally unique until deepstream properly separates
361
+ // sync requests from different sockets.
362
+ const token = xuid()
363
+ const queue = this._syncQueue.splice(0)
364
+ this._syncEmitter.once(token, () => {
365
+ for (let n = 0; n < queue.length; n += 2) {
366
+ queue[n](queue[n + 1])
367
+ }
368
+ })
369
+ this._connection.sendMsg2(C.TOPIC.RECORD, C.ACTIONS.SYNC, token, 'WEAK')
370
+ })
371
+ }
372
+
346
373
  set(name, ...args) {
347
374
  const record = this.getRecord(name)
348
375
  try {
@@ -395,8 +422,13 @@ class RecordHandler {
395
422
  return new Promise((resolve) => {
396
423
  const rec = this.getRecord(args[0])
397
424
  const state = args.length === 2 ? args[1] : C.RECORD_STATE.SERVER
425
+ // TODO (perf): We could also skip sync if state is less than SERVER. However,
426
+ // there is a potential race where we receive an UPDATE for a previous SUBSCRIBE.
427
+ // Unsure how to avoid that. Keep it simple for now and always sync regardless of
428
+ // current state.
429
+ const synced = state < C.RECORD_STATE.SERVER
398
430
 
399
- if (rec.state >= state) {
431
+ if (rec.state >= state && synced) {
400
432
  rec.unref()
401
433
  resolve(rec.data)
402
434
  } else {
@@ -405,12 +437,19 @@ class RecordHandler {
405
437
  state,
406
438
  resolve,
407
439
  timeout: null,
440
+ synced,
408
441
  }
409
442
  opaque.timeout = timers.setTimeout(onTimeoutFast, 2 * 60e3, opaque)
410
443
  rec.subscribe(onUpdateFast, opaque)
444
+
445
+ if (!opaque.synced) {
446
+ this._sync(onSyncFast, 'WEAK', opaque)
447
+ }
411
448
  }
412
449
  })
413
450
  } else {
451
+ // Slow path...
452
+ // TODO (fix): Missing sync..
414
453
  return new Promise((resolve, reject) => {
415
454
  this.observe(...args)
416
455
  .pipe(rx.first())
@@ -228,8 +228,8 @@ class Record {
228
228
  }
229
229
 
230
230
  const onAbort = signal
231
- ? (abort) => {
232
- onDone(abort ?? new utils.AbortError())
231
+ ? () => {
232
+ onDone(signal.reason ?? new utils.AbortError())
233
233
  }
234
234
  : null
235
235