@nxtedition/deepstream.io-client-js 32.0.13 → 32.0.15

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": "32.0.13",
3
+ "version": "32.0.15",
4
4
  "description": "the javascript client for deepstream.io",
5
5
  "homepage": "http://deepstream.io",
6
6
  "type": "module",
@@ -41,31 +41,32 @@
41
41
  "component-emitter2": "^1.3.5",
42
42
  "invariant": "^2.2.4",
43
43
  "lodash.clonedeep": "^4.5.0",
44
- "type-fest": "^5.4.1",
44
+ "type-fest": "^5.5.0",
45
45
  "utf-8-validate": "^6.0.6",
46
46
  "varint": "^6.0.0",
47
- "ws": "^8.19.0",
47
+ "ws": "^8.20.0",
48
48
  "xuid": "^4.1.3",
49
49
  "xxhash-wasm": "^1.0.2"
50
50
  },
51
51
  "devDependencies": {
52
- "@types/node": "^25.0.10",
53
- "eslint": "^9.39.2",
52
+ "@eslint/js": "^10.0.1",
53
+ "@types/node": "^25.5.0",
54
+ "eslint": "^10.1.0",
54
55
  "eslint-config-prettier": "^10.1.8",
55
56
  "eslint-config-standard": "^17.1.0",
56
57
  "eslint-plugin-import": "^2.31.0",
57
- "eslint-plugin-n": "^17.23.2",
58
+ "eslint-plugin-n": "^17.24.0",
58
59
  "eslint-plugin-node": "^11.1.0",
59
60
  "eslint-plugin-promise": "^7.1.0",
60
61
  "husky": "^9.1.6",
61
- "lint-staged": "^16.2.7",
62
+ "lint-staged": "^16.4.0",
62
63
  "mitata": "^1.0.10",
63
64
  "pinst": "^3.0.0",
64
65
  "prettier": "^3.8.1",
65
66
  "rxjs": "^7.8.1",
66
67
  "tsd": "^0.33.0",
67
- "typescript": "^5.6.3",
68
- "typescript-eslint": "^8.53.1"
68
+ "typescript": "^6.0.2",
69
+ "typescript-eslint": "^8.57.2"
69
70
  },
70
71
  "peerDependencies": {
71
72
  "rxjs": ">=6.x"
@@ -44,10 +44,17 @@ function onUpdate(record, subscription) {
44
44
  }
45
45
 
46
46
  if (!subscription.synced || subscription.record.state < subscription.state) {
47
+ if (subscription.timeoutValue > 0) {
48
+ if (!subscription.timeout) {
49
+ subscription.timeout = timers.setTimeout(onTimeout, subscription.timeoutValue, subscription)
50
+ } else {
51
+ subscription.timeout.refresh()
52
+ }
53
+ }
47
54
  return
48
55
  }
49
56
 
50
- if (subscription.timeout != null) {
57
+ if (subscription.timeout) {
51
58
  timers.clearTimeout(subscription.timeout)
52
59
  subscription.timeout = null
53
60
  }
@@ -94,36 +101,6 @@ function onTimeout(subscription) {
94
101
  )
95
102
  }
96
103
 
97
- class Subscription {
98
- /** @type {unknown} */
99
- key = null
100
- /** @type {unknown} */
101
- subscriber = null
102
- /** @type {unknown} */
103
- path = null
104
- /** @type {number} */
105
- state = 0
106
- /** @type {AbortSignal|null} */
107
- signal = null
108
- /** @type {boolean} */
109
- dataOnly = false
110
-
111
- /** @type {Record|null} */
112
- record = null
113
- /** @type {Timeout|null} */
114
- timeout = null
115
- /** @type {Function?} */
116
- abort = null
117
- /** @type {object|Array} */
118
- data = kEmpty
119
- /** @type {boolean} */
120
- synced = false
121
-
122
- index = -1
123
-
124
- onUpdate = onUpdate
125
- }
126
-
127
104
  class RecordHandler {
128
105
  constructor(options, connection, client) {
129
106
  this.JSON = jsonPath
@@ -142,12 +119,8 @@ class RecordHandler {
142
119
 
143
120
  this._connected = 0
144
121
  this._stats = {
145
- updating: 0,
146
122
  created: 0,
147
123
  destroyed: 0,
148
- records: 0,
149
- pruning: 0,
150
- patching: 0,
151
124
  }
152
125
 
153
126
  this._syncQueue = []
@@ -169,23 +142,11 @@ class RecordHandler {
169
142
  this._pruning = new Set()
170
143
 
171
144
  for (const rec of pruning) {
172
- try {
173
- rec._$dispose()
174
- if (!this._records.delete(rec.name)) {
175
- this._client._$onError(
176
- C.TOPIC.RECORD,
177
- C.EVENT.INTERNAL_ERROR,
178
- `failed to delete pruned record: ${rec.name}`,
179
- )
180
- }
181
- } catch (err) {
182
- this._client._$onError(C.TOPIC.RECORD, C.EVENT.INTERNAL_ERROR, err)
183
- }
145
+ rec._$dispose()
146
+ this._records.delete(rec.name)
184
147
  }
185
148
 
186
149
  this._stats.destroyed += pruning.size
187
- this._stats.pruning = this._pruning.size
188
- this._stats.records = this._records.size
189
150
 
190
151
  this._pruningTimeout.refresh()
191
152
  }
@@ -199,7 +160,6 @@ class RecordHandler {
199
160
  } else {
200
161
  this._pruning.delete(rec)
201
162
  }
202
- this._stats.pruning = this._pruning.size
203
163
  }
204
164
 
205
165
  _onUpdating(rec, value) {
@@ -207,12 +167,9 @@ class RecordHandler {
207
167
 
208
168
  if (value) {
209
169
  invariant(!callbacks, 'updating callbacks must not exist')
210
- this._stats.updating += 1
211
170
  this._updating.set(rec, [])
212
171
  } else {
213
172
  invariant(callbacks, 'updating callbacks must exist')
214
-
215
- this._stats.updating -= 1
216
173
  this._updating.delete(rec)
217
174
  for (const callback of callbacks) {
218
175
  callback()
@@ -230,7 +187,6 @@ class RecordHandler {
230
187
  callback()
231
188
  }
232
189
  }
233
- this._stats.patching = this._patching.size
234
190
  }
235
191
 
236
192
  get connected() {
@@ -246,6 +202,10 @@ class RecordHandler {
246
202
  return {
247
203
  ...this._stats,
248
204
  subscriptions,
205
+ updating: this._updating.size,
206
+ patching: this._patching.size,
207
+ putting: this._putting.size,
208
+ pruning: this._pruning.size,
249
209
  }
250
210
  }
251
211
 
@@ -268,16 +228,14 @@ class RecordHandler {
268
228
  }
269
229
 
270
230
  let record = this._records.get(name)
231
+
271
232
  if (!record) {
272
233
  record = new Record(name, this)
273
- this._records.set(name, record)
274
234
  this._stats.created += 1
275
- this._stats.records = this._records.size
276
- } else {
277
- record.ref()
235
+ this._records.set(name, record)
278
236
  }
279
237
 
280
- return record
238
+ return record.ref()
281
239
  }
282
240
 
283
241
  provide(pattern, callback, options) {
@@ -599,7 +557,6 @@ class RecordHandler {
599
557
  let timeout = defaults?.timeout ?? 0
600
558
  let dataOnly = defaults?.dataOnly ?? false
601
559
  let sync = defaults?.sync ?? false
602
- let key
603
560
 
604
561
  let idx = 0
605
562
 
@@ -618,7 +575,7 @@ class RecordHandler {
618
575
  }
619
576
 
620
577
  if (idx < args.length && (args[idx] == null || typeof args[idx] === 'object')) {
621
- const options = args[idx++] || {}
578
+ const options = args[idx] ?? {}
622
579
 
623
580
  if (options.signal !== undefined) {
624
581
  signal = options.signal
@@ -643,10 +600,6 @@ class RecordHandler {
643
600
  if (options.sync !== undefined) {
644
601
  sync = options.sync
645
602
  }
646
-
647
- if (options.key !== undefined) {
648
- key = options.key
649
- }
650
603
  }
651
604
 
652
605
  if (typeof state === 'string') {
@@ -675,14 +628,35 @@ class RecordHandler {
675
628
  return
676
629
  }
677
630
 
678
- const subscription = new Subscription()
679
-
680
- subscription.key = key
681
- subscription.subscriber = subscriber
682
- subscription.path = path
683
- subscription.state = state
684
- subscription.signal = signal
685
- subscription.dataOnly = dataOnly
631
+ // TODO (perf): Make a class
632
+ const subscription = {
633
+ /** @readonly @type {unknown} */
634
+ subscriber,
635
+ /** @readonly @type {unknown} */
636
+ path,
637
+ /** @readonly @type {number} */
638
+ state,
639
+ /** @type {AbortSignal|null} */
640
+ signal,
641
+ /** @readonly @type {boolean} */
642
+ dataOnly,
643
+ /** @readonly @type {number} */
644
+ timeoutValue: timeout,
645
+
646
+ /** @type {Record|null} */
647
+ record: null,
648
+ /** @type {Timeout|null} */
649
+ timeout: null,
650
+ /** @type {Function?} */
651
+ abort: null,
652
+ /** @type {object|Array} */
653
+ data: kEmpty,
654
+ /** @type {boolean} */
655
+ synced: false,
656
+
657
+ index: -1,
658
+ onUpdate,
659
+ }
686
660
 
687
661
  subscriber.add(() => {
688
662
  if (subscription.timeout) {
@@ -716,10 +690,6 @@ class RecordHandler {
716
690
  } else {
717
691
  onSync(subscription)
718
692
  }
719
-
720
- if (timeout > 0 && (!subscription.synced || subscription.record.state < subscription.state)) {
721
- subscription.timeout = timers.setTimeout(onTimeout, timeout, subscription)
722
- }
723
693
  })
724
694
  }
725
695
 
@@ -18,18 +18,15 @@ class Record {
18
18
  this._version = ''
19
19
  this._data = jsonPath.EMPTY_OBJ
20
20
  this._state = C.RECORD_STATE.VOID
21
- this._refs = 1
22
-
23
- /** @type {Array|null} */
24
- this._subscriptions = null
21
+ this._refs = 0
22
+ this._subscriptions = []
25
23
 
26
24
  /** @type {Array|null} */
27
25
  this._emittingArr = null
28
26
  /** @type {number} */
29
27
  this._emittingIndex = -1
30
28
 
31
- /** @type {Array|null} */
32
- this._observers = null
29
+ this._observers = []
33
30
 
34
31
  /** @type Map? */ this._updating = null
35
32
  /** @type Array? */ this._patching = null
@@ -97,8 +94,6 @@ class Record {
97
94
  * @returns {Record}
98
95
  */
99
96
  subscribe(fn, opaque = null) {
100
- this._subscriptions ??= []
101
-
102
97
  if (this._emittingArr == this._subscriptions) {
103
98
  this._subscriptions = this._subscriptions.slice()
104
99
  }
@@ -115,10 +110,6 @@ class Record {
115
110
  * @returns {Record}
116
111
  */
117
112
  unsubscribe(fn, opaque = null) {
118
- if (!this._subscriptions) {
119
- return this
120
- }
121
-
122
113
  if (this._emittingArr == this._subscriptions) {
123
114
  this._subscriptions = this._subscriptions.slice()
124
115
  }
@@ -146,17 +137,10 @@ class Record {
146
137
  * @param {{ index: number, onUpdate: (Record) => void}} subscription
147
138
  */
148
139
  _observe(subscription) {
149
- this._observers ??= []
150
-
151
140
  if (subscription.index != null && subscription.index !== -1) {
152
141
  throw new Error('already observing')
153
142
  }
154
143
 
155
- if (this._emittingArr === this._observers) {
156
- // TODO (perf): Shift from start if emitting?
157
- this._observers = this._observers.slice()
158
- }
159
-
160
144
  subscription.index = this._observers.push(subscription) - 1
161
145
  }
162
146
 
@@ -164,10 +148,6 @@ class Record {
164
148
  * @param {{ index: number, onUpdate: (Record) => void}} subscription
165
149
  */
166
150
  _unobserve(subscription) {
167
- if (!this._observers) {
168
- return this
169
- }
170
-
171
151
  if (subscription.index == null || subscription.index === -1) {
172
152
  throw new Error('not observing')
173
153
  }
@@ -257,7 +237,6 @@ class Record {
257
237
  const signal = optionsOrNil?.signal
258
238
  const state = stateOrNil ?? C.RECORD_STATE.SERVER
259
239
  const timeout = optionsOrNil?.timeout ?? 2 * 60e3
260
- const key = optionsOrNil?.key ?? 'when'
261
240
 
262
241
  if (signal?.aborted) {
263
242
  return Promise.reject(signal.reason || new utils.AbortError())
@@ -273,33 +252,14 @@ class Record {
273
252
  return
274
253
  }
275
254
 
276
- const subscription = {
277
- key,
278
- /** @type {timers.Timeout|NodeJS.Timeout|null} */
279
- timeout: null,
280
- /** @type {AbortSignal|null} */
281
- signal: null,
282
- done: false,
283
-
284
- state,
285
- index: -1,
286
- onUpdate(record, subscription) {
287
- if (record._state >= subscription.state) {
288
- onDone(null)
289
- }
290
- },
291
- }
292
-
293
- const onAbort = (e) => {
294
- onDone(signal.reason ?? new utils.AbortError())
295
- }
255
+ let timeoutHandle
256
+ let done = false
296
257
 
297
258
  const onDone = (err) => {
298
- if (subscription.done) {
259
+ if (done) {
299
260
  return
300
261
  }
301
-
302
- subscription.done = true
262
+ done = true
303
263
 
304
264
  if (err) {
305
265
  reject(err)
@@ -308,21 +268,30 @@ class Record {
308
268
  }
309
269
 
310
270
  this.unref()
311
- this._unobserve(subscription)
271
+ this.unsubscribe(onUpdate)
312
272
 
313
- if (subscription.timeout != null) {
314
- timers.clearTimeout(subscription.timeout)
315
- subscription.timeout = null
273
+ if (timeoutHandle) {
274
+ timers.clearTimeout(timeoutHandle)
275
+ timeoutHandle = null
316
276
  }
317
277
 
318
- if (subscription.signal != null) {
319
- subscription.signal.removeEventListener('abort', onAbort)
320
- subscription.signal = null
278
+ signal?.removeEventListener('abort', onAbort)
279
+ }
280
+
281
+ const onUpdate = () => {
282
+ if (this._state >= state) {
283
+ onDone(null)
321
284
  }
322
285
  }
323
286
 
287
+ const onAbort = signal
288
+ ? () => {
289
+ onDone(signal.reason ?? new utils.AbortError())
290
+ }
291
+ : null
292
+
324
293
  if (timeout > 0) {
325
- subscription.timeout = timers.setTimeout(() => {
294
+ timeoutHandle = timers.setTimeout(() => {
326
295
  const expected = C.RECORD_STATE_NAME[state]
327
296
  const current = C.RECORD_STATE_NAME[this._state]
328
297
 
@@ -334,13 +303,10 @@ class Record {
334
303
  }, timeout)
335
304
  }
336
305
 
337
- if (signal) {
338
- subscription.signal = signal
339
- signal?.addEventListener('abort', onAbort)
340
- }
306
+ signal?.addEventListener('abort', onAbort)
341
307
 
342
308
  this.ref()
343
- this._observe(subscription)
309
+ this.subscribe(onUpdate)
344
310
  })
345
311
  }
346
312
 
@@ -598,38 +564,34 @@ class Record {
598
564
  throw new Error('cannot reenter emitUpdate')
599
565
  }
600
566
 
601
- if (this._subscriptions != null) {
602
- try {
603
- const arr = this._subscriptions
604
- const len = arr.length
605
-
606
- this._emittingArr = arr
607
- for (let n = 0; n < len; n += 2) {
608
- this._emittingIndex = n
609
- // TODO (fix): What if this throws?
610
- arr[n + 0](this, arr[n + 1])
611
- }
612
- } finally {
613
- this._emittingArr = null
614
- this._emittingIndex = -1
567
+ try {
568
+ const arr = this._subscriptions
569
+ const len = arr.length
570
+
571
+ this._emittingArr = arr
572
+ for (let n = 0; n < len; n += 2) {
573
+ this._emittingIndex = n
574
+ // TODO (fix): What if this throws?
575
+ arr[n + 0](this, arr[n + 1])
615
576
  }
577
+ } finally {
578
+ this._emittingArr = null
579
+ this._emittingIndex = -1
616
580
  }
617
581
 
618
- if (this._observers != null) {
619
- try {
620
- const arr = this._observers
621
- const len = arr.length
622
-
623
- this._emittingArr = arr
624
- for (let n = 0; n < len; n++) {
625
- this._emittingIndex = n
626
- // TODO (fix): What if this throws?
627
- arr[n].onUpdate(this, arr[n])
628
- }
629
- } finally {
630
- this._emittingArr = null
631
- this._emittingIndex = -1
582
+ try {
583
+ const arr = this._observers
584
+ const len = arr.length
585
+
586
+ this._emittingArr = arr
587
+ for (let n = 0; n < len; n++) {
588
+ this._emittingIndex = n
589
+ // TODO (fix): What if this throws?
590
+ arr[n].onUpdate(this, arr[n])
632
591
  }
592
+ } finally {
593
+ this._emittingArr = null
594
+ this._emittingIndex = -1
633
595
  }
634
596
 
635
597
  this._handler._client.emit('recordUpdated', this)
@@ -6,7 +6,6 @@ export default class Listener {
6
6
  constructor(topic, pattern, callback, handler, { recursive = false, stringify = null } = {}) {
7
7
  this._topic = topic
8
8
  this._pattern = pattern
9
- this._expr = new RegExp(pattern)
10
9
  this._callback = callback
11
10
  this._handler = handler
12
11
  this._client = this._handler._client
@@ -55,11 +54,6 @@ export default class Listener {
55
54
  return
56
55
  }
57
56
 
58
- if (!this._expr.test(name)) {
59
- this._error(name, 'invalid add: name does not match pattern')
60
- return
61
- }
62
-
63
57
  // TODO (refactor): Move to class
64
58
  const provider = {
65
59
  name,
@@ -37,7 +37,6 @@ export default class Listener {
37
37
 
38
38
  this._topic = topic
39
39
  this._pattern = pattern
40
- this._expr = new RegExp(pattern)
41
40
  this._callback = callback
42
41
  this._handler = handler
43
42
  this._client = this._handler._client
@@ -70,11 +69,6 @@ export default class Listener {
70
69
  return
71
70
  }
72
71
 
73
- if (!this._expr.test(name)) {
74
- this._error(name, 'invalid accept: name does not match pattern')
75
- return
76
- }
77
-
78
72
  let value$
79
73
  try {
80
74
  value$ = this._callback(name)