@nxtedition/deepstream.io-client-js 31.2.3 → 31.2.5
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 +1 -1
- package/src/record/record-handler.js +94 -57
- package/src/utils/timers.js +22 -4
- package/.claude/settings.local.json +0 -9
- package/nxtedition-deepstream.io-client-js-31.0.18-b1.tgz +0 -0
- package/nxtedition-deepstream.io-client-js-31.0.18-b2.tgz +0 -0
- package/nxtedition-deepstream.io-client-js-31.0.18-b3.tgz +0 -0
package/package.json
CHANGED
|
@@ -9,6 +9,8 @@ import * as utils from '../utils/utils.js'
|
|
|
9
9
|
import xuid from 'xuid'
|
|
10
10
|
import * as timers from '../utils/timers.js'
|
|
11
11
|
|
|
12
|
+
/** @import {Timeout} from '../utils/timers.js' */
|
|
13
|
+
|
|
12
14
|
function noop() {}
|
|
13
15
|
|
|
14
16
|
const kEmpty = Symbol('kEmpty')
|
|
@@ -41,17 +43,24 @@ function onUpdate(record, subscription) {
|
|
|
41
43
|
return
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
if (!subscription.synced) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
if (!subscription.synced || subscription.record.state < subscription.state) {
|
|
47
|
+
if (subscription.timeoutValue > 0) {
|
|
48
|
+
if (!subscription.timeoutHandle) {
|
|
49
|
+
subscription.timeoutHandle = timers.setTimeout(
|
|
50
|
+
onTimeout,
|
|
51
|
+
subscription.timeoutValue,
|
|
52
|
+
subscription,
|
|
53
|
+
)
|
|
54
|
+
} else {
|
|
55
|
+
subscription.timeoutHandle.refresh()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
49
58
|
return
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
if (subscription.
|
|
53
|
-
timers.clearTimeout(subscription.
|
|
54
|
-
subscription.
|
|
61
|
+
if (subscription.timeoutHandle) {
|
|
62
|
+
timers.clearTimeout(subscription.timeoutHandle)
|
|
63
|
+
subscription.timeoutHandle = null
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
const data = subscription.path
|
|
@@ -463,30 +472,31 @@ class RecordHandler {
|
|
|
463
472
|
}
|
|
464
473
|
|
|
465
474
|
/**
|
|
475
|
+
* @param {string} name
|
|
466
476
|
* @param {...any} args
|
|
467
477
|
* @returns {rxjs.Observable}
|
|
468
478
|
*/
|
|
469
|
-
observe(...args) {
|
|
470
|
-
return this._observe(OBSERVE_DEFAULTS, ...args)
|
|
479
|
+
observe(name, ...args) {
|
|
480
|
+
return this._observe(OBSERVE_DEFAULTS, name, ...args)
|
|
471
481
|
}
|
|
472
482
|
|
|
473
483
|
/**
|
|
484
|
+
* @param {string} name
|
|
474
485
|
* @param {...any} args
|
|
475
486
|
* @returns {rxjs.Observable<{ name: string, version: string, state: Number, data: any}>}
|
|
476
487
|
*/
|
|
477
|
-
observe2(...args) {
|
|
478
|
-
return this._observe(OBSERVE2_DEFAULTS, ...args)
|
|
488
|
+
observe2(name, ...args) {
|
|
489
|
+
return this._observe(OBSERVE2_DEFAULTS, name, ...args)
|
|
479
490
|
}
|
|
480
491
|
|
|
481
492
|
/**
|
|
482
|
-
*
|
|
483
|
-
* @param {*} name
|
|
493
|
+
* @param {string} name
|
|
484
494
|
* @param {...any} args
|
|
485
495
|
* @returns { { value: object, async: false } | { value: Promise<object>, async: true } }
|
|
486
496
|
*/
|
|
487
497
|
getAsync(name, ...args) {
|
|
488
498
|
let path
|
|
489
|
-
let state = GET_DEFAULTS.state
|
|
499
|
+
let state = GET_DEFAULTS.state ?? C.RECORD_STATE.CLIENT
|
|
490
500
|
|
|
491
501
|
let idx = 0
|
|
492
502
|
|
|
@@ -508,32 +518,40 @@ class RecordHandler {
|
|
|
508
518
|
return { value: this.get(name, ...args), async: true }
|
|
509
519
|
}
|
|
510
520
|
|
|
521
|
+
if (typeof state === 'string') {
|
|
522
|
+
state = C.RECORD_STATE[state.toUpperCase()]
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (!Number.isInteger(state) || state < 0) {
|
|
526
|
+
throw new Error('invalid argument: state')
|
|
527
|
+
}
|
|
528
|
+
|
|
511
529
|
const rec = this.getRecord(name)
|
|
512
530
|
try {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
531
|
+
return rec.state >= state
|
|
532
|
+
? { value: rec.get(path), async: false }
|
|
533
|
+
: { value: this.get(name, ...args), async: true }
|
|
516
534
|
} finally {
|
|
517
535
|
rec.unref()
|
|
518
536
|
}
|
|
519
|
-
|
|
520
|
-
return { value: this.get(name, ...args), async: true }
|
|
521
537
|
}
|
|
522
538
|
|
|
523
539
|
/**
|
|
540
|
+
* @param {string} name
|
|
524
541
|
* @param {...any} args
|
|
525
542
|
* @returns {Promise<object>}
|
|
526
543
|
*/
|
|
527
|
-
get(...args) {
|
|
528
|
-
return rxjs.firstValueFrom(this._observe(GET_DEFAULTS, ...args))
|
|
544
|
+
get(name, ...args) {
|
|
545
|
+
return rxjs.firstValueFrom(this._observe(GET_DEFAULTS, name, ...args))
|
|
529
546
|
}
|
|
530
547
|
|
|
531
548
|
/**
|
|
549
|
+
* @param {string} name
|
|
532
550
|
* @param {...any} args
|
|
533
551
|
* @returns {Promise<object>}
|
|
534
552
|
*/
|
|
535
|
-
get2(...args) {
|
|
536
|
-
return rxjs.firstValueFrom(this._observe(GET2_DEFAULTS, ...args))
|
|
553
|
+
get2(name, ...args) {
|
|
554
|
+
return rxjs.firstValueFrom(this._observe(GET2_DEFAULTS, name, ...args))
|
|
537
555
|
}
|
|
538
556
|
|
|
539
557
|
/**
|
|
@@ -542,11 +560,11 @@ class RecordHandler {
|
|
|
542
560
|
_observe(defaults, name, ...args) {
|
|
543
561
|
return new rxjs.Observable((subscriber) => {
|
|
544
562
|
let path
|
|
545
|
-
let state = defaults?.state
|
|
546
|
-
let signal
|
|
547
|
-
let timeout = defaults?.timeout
|
|
548
|
-
let dataOnly = defaults?.dataOnly
|
|
549
|
-
let sync = defaults?.sync
|
|
563
|
+
let state = defaults?.state ?? C.RECORD_STATE.CLIENT
|
|
564
|
+
let signal = null
|
|
565
|
+
let timeout = defaults?.timeout ?? 0
|
|
566
|
+
let dataOnly = defaults?.dataOnly ?? false
|
|
567
|
+
let sync = defaults?.sync ?? false
|
|
550
568
|
|
|
551
569
|
let idx = 0
|
|
552
570
|
|
|
@@ -596,31 +614,58 @@ class RecordHandler {
|
|
|
596
614
|
state = C.RECORD_STATE[state.toUpperCase()]
|
|
597
615
|
}
|
|
598
616
|
|
|
617
|
+
if (!Number.isInteger(state) || state < 0) {
|
|
618
|
+
throw new Error('invalid argument: state')
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (!Number.isInteger(timeout) || timeout < 0) {
|
|
622
|
+
throw new Error('invalid argument: timeout')
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (typeof dataOnly !== 'boolean') {
|
|
626
|
+
throw new Error('invalid argument: dataOnly')
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (typeof sync !== 'boolean') {
|
|
630
|
+
throw new Error('invalid argument: sync')
|
|
631
|
+
}
|
|
632
|
+
|
|
599
633
|
// TODO (perf): Make a class
|
|
600
634
|
const subscription = {
|
|
635
|
+
/** @readonly @type {unknown} */
|
|
601
636
|
subscriber,
|
|
637
|
+
/** @type {Record|null} */
|
|
638
|
+
record: this.getRecord(name),
|
|
639
|
+
/** @readonly @type {unknown} */
|
|
602
640
|
path,
|
|
641
|
+
/** @readonly @type {number} */
|
|
603
642
|
state,
|
|
604
|
-
|
|
643
|
+
/** @type {AbortSignal|null} */
|
|
605
644
|
signal,
|
|
645
|
+
/** @readonly @type {boolean} */
|
|
606
646
|
dataOnly,
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
/** @type {
|
|
611
|
-
|
|
647
|
+
/** @readonly @type {number} */
|
|
648
|
+
timeoutValue: timeout,
|
|
649
|
+
|
|
650
|
+
/** @type {Timeout|null} */
|
|
651
|
+
timeoutHandle: null,
|
|
612
652
|
/** @type {Function?} */
|
|
613
653
|
abort: null,
|
|
654
|
+
/** @type {object|Array} */
|
|
655
|
+
data: kEmpty,
|
|
656
|
+
/** @type {boolean} */
|
|
657
|
+
synced: false,
|
|
658
|
+
|
|
614
659
|
unsubscribe() {
|
|
615
|
-
if (this.
|
|
616
|
-
timers.clearTimeout(this.
|
|
617
|
-
this.
|
|
660
|
+
if (this.timeoutHandle) {
|
|
661
|
+
timers.clearTimeout(this.timeoutHandle)
|
|
662
|
+
this.timeoutHandle = null
|
|
618
663
|
}
|
|
619
664
|
|
|
620
665
|
if (this.signal) {
|
|
621
666
|
utils.removeAbortListener(this.signal, this.abort)
|
|
622
|
-
this.signal = null
|
|
623
667
|
this.abort = null
|
|
668
|
+
this.signal = null
|
|
624
669
|
}
|
|
625
670
|
|
|
626
671
|
if (this.record) {
|
|
@@ -631,30 +676,22 @@ class RecordHandler {
|
|
|
631
676
|
},
|
|
632
677
|
}
|
|
633
678
|
|
|
634
|
-
subscription.record
|
|
635
|
-
|
|
636
|
-
const record = subscription.record
|
|
679
|
+
if (subscription.record) {
|
|
680
|
+
subscription.record.subscribe(onUpdate, subscription)
|
|
637
681
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
if (timeout > 0 && state && record.state < state) {
|
|
645
|
-
// TODO (perf): Avoid Timer allocation.
|
|
646
|
-
subscription.timeout = timers.setTimeout(onTimeout, timeout, subscription)
|
|
682
|
+
if (sync && subscription.record.state >= C.RECORD_STATE.SERVER) {
|
|
683
|
+
this._sync(onSync, sync === true ? 'WEAK' : sync, subscription)
|
|
684
|
+
} else {
|
|
685
|
+
subscription.synced = true
|
|
686
|
+
}
|
|
647
687
|
}
|
|
648
688
|
|
|
649
|
-
if (signal) {
|
|
650
|
-
// TODO (perf): Avoid abort closure allocation.
|
|
689
|
+
if (subscription.signal) {
|
|
651
690
|
subscription.abort = () => subscriber.error(new utils.AbortError())
|
|
652
|
-
utils.addAbortListener(signal, subscription.abort)
|
|
691
|
+
utils.addAbortListener(subscription.signal, subscription.abort)
|
|
653
692
|
}
|
|
654
693
|
|
|
655
|
-
|
|
656
|
-
onUpdate(null, subscription)
|
|
657
|
-
}
|
|
694
|
+
onUpdate(subscription.record, subscription)
|
|
658
695
|
|
|
659
696
|
return subscription
|
|
660
697
|
})
|
package/src/utils/timers.js
CHANGED
|
@@ -49,7 +49,7 @@ function refreshTimeout() {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
class
|
|
52
|
+
class FastTimeout {
|
|
53
53
|
constructor(callback, delay, opaque) {
|
|
54
54
|
this.callback = callback
|
|
55
55
|
this.delay = delay
|
|
@@ -84,14 +84,32 @@ class Timeout {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* @typedef {{
|
|
89
|
+
* refresh: () => void,
|
|
90
|
+
* [Symbol.dispose]: () => void,
|
|
91
|
+
* }} Timeout
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param {(opaque?: any) => void} callback
|
|
96
|
+
* @param {number} delay
|
|
97
|
+
* @param {any} [opaque]
|
|
98
|
+
* @returns {Timeout}
|
|
99
|
+
*/
|
|
87
100
|
export function setTimeout(callback, delay, opaque) {
|
|
88
101
|
return delay < fastNowInterval
|
|
89
|
-
?
|
|
90
|
-
|
|
102
|
+
? opaque
|
|
103
|
+
? globalThis.setTimeout(() => callback(opaque), delay)
|
|
104
|
+
: globalThis.setTimeout(callback, delay)
|
|
105
|
+
: new FastTimeout(callback, delay, opaque)
|
|
91
106
|
}
|
|
92
107
|
|
|
108
|
+
/**
|
|
109
|
+
* @param {Timeout} timeout
|
|
110
|
+
*/
|
|
93
111
|
export function clearTimeout(timeout) {
|
|
94
|
-
if (timeout instanceof
|
|
112
|
+
if (timeout instanceof FastTimeout) {
|
|
95
113
|
timeout.clear()
|
|
96
114
|
} else {
|
|
97
115
|
globalThis.clearTimeout(timeout)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|