@nxtedition/deepstream.io-client-js 28.1.15 → 28.1.17

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": "28.1.15",
3
+ "version": "28.1.17",
4
4
  "description": "the javascript client for deepstream.io",
5
5
  "homepage": "http://deepstream.io",
6
6
  "type": "module",
@@ -265,96 +265,116 @@ class RecordHandler {
265
265
 
266
266
  async sync(opts) {
267
267
  // TODO (fix): Sync pending? What about VOID state?
268
-
269
- let onAbort
268
+ // TODO (perf): Slow implementation...
270
269
 
271
270
  const signal = opts?.signal
272
- const timeout = opts?.timeout || 2 * 60e3
273
-
274
- const signalPromise = signal
275
- ? new Promise((resolve, reject) => {
276
- onAbort = () => {
277
- reject(signal.reason ?? new utils.AbortError())
278
- }
279
- signal.addEventListener('abort', onAbort)
280
- })
281
- : Promise.resolve()
282
- signalPromise?.catch(() => {})
271
+ const timeout = opts?.timeout ?? 2 * 60e3
283
272
 
273
+ const disposers = []
284
274
  try {
275
+ const signalPromise = signal
276
+ ? new Promise((resolve, reject) => {
277
+ const onAbort = () => reject(signal.reason ?? new utils.AbortError())
278
+ signal.addEventListener('abort', onAbort)
279
+ disposers.push(() => signal.removeEventListener('abort', onAbort))
280
+ })
281
+ : null
282
+
285
283
  if (this._patching.size) {
286
- let patchingTimeout
287
- const patching = [...this._patching.values()]
284
+ const promises = []
288
285
 
289
- await Promise.race([
290
- Promise.all(
291
- patching.map((callbacks) => new Promise((resolve) => callbacks.push(resolve))),
292
- ),
293
- new Promise((resolve) => {
294
- patchingTimeout = timers.setTimeout(() => {
295
- this._client._$onError(
296
- C.TOPIC.RECORD,
297
- C.EVENT.TIMEOUT,
298
- new Error('sync patching timeout'),
299
- )
300
- resolve(null)
301
- }, timeout)
302
- }),
303
- signalPromise,
304
- ]).finally(() => {
305
- timers.clearTimeout(patchingTimeout)
306
- })
286
+ {
287
+ const patchingPromises = []
288
+ for (const callbacks of this._patching.values()) {
289
+ patchingPromises.push(new Promise((resolve) => callbacks.push(resolve)))
290
+ }
291
+ promises.push(patchingPromises)
292
+ }
293
+
294
+ if (timeout) {
295
+ promises.push(
296
+ new Promise((resolve) => {
297
+ const patchingTimeout = timers.setTimeout(() => {
298
+ this._client._$onError(
299
+ C.TOPIC.RECORD,
300
+ C.EVENT.TIMEOUT,
301
+ new Error('sync patching timeout'),
302
+ )
303
+ resolve(null)
304
+ }, timeout)
305
+ disposers.push(() => timers.clearTimeout(patchingTimeout))
306
+ }),
307
+ )
308
+ }
309
+
310
+ if (signalPromise) {
311
+ promises.push(signalPromise)
312
+ }
313
+
314
+ await Promise.race(promises)
307
315
  }
308
316
 
309
317
  if (this._updating.size) {
310
- let updatingTimeout
311
- const updating = [...this._updating.values()]
318
+ const promises = []
312
319
 
313
- await Promise.race([
314
- Promise.all(
315
- updating.map((callbacks) => new Promise((resolve) => callbacks.push(resolve))),
316
- ),
320
+ {
321
+ const updatingPromises = []
322
+ for (const callbacks of this._updating.values()) {
323
+ updatingPromises.push(new Promise((resolve) => callbacks.push(resolve)))
324
+ }
325
+ promises.push(updatingPromises)
326
+ }
327
+
328
+ if (timeout) {
329
+ promises.push(
330
+ new Promise((resolve) => {
331
+ const updatingTimeout = timers.setTimeout(() => {
332
+ this._client._$onError(
333
+ C.TOPIC.RECORD,
334
+ C.EVENT.TIMEOUT,
335
+ new Error('sync updating timeout'),
336
+ )
337
+ resolve(null)
338
+ }, timeout)
339
+ disposers.push(() => timers.clearTimeout(updatingTimeout))
340
+ }),
341
+ )
342
+ }
343
+
344
+ await Promise.race(promises)
345
+ }
346
+
347
+ {
348
+ const promises = []
349
+
350
+ promises.push(
317
351
  new Promise((resolve) => {
318
- updatingTimeout = timers.setTimeout(() => {
319
- this._client._$onError(
320
- C.TOPIC.RECORD,
321
- C.EVENT.TIMEOUT,
322
- new Error('sync updating timeout'),
323
- )
324
- resolve(null)
325
- }, timeout)
352
+ const token = xuid()
353
+ this._syncEmitter.once(token, resolve)
354
+ this._connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SYNC, [token])
326
355
  }),
327
- signalPromise,
328
- ]).finally(() => {
329
- timers.clearTimeout(updatingTimeout)
330
- })
331
- }
356
+ )
357
+
358
+ if (timeout) {
359
+ promises.push(
360
+ new Promise((resolve, reject) => {
361
+ const serverTimeout = timers.setTimeout(() => {
362
+ reject(new Error('sync server timeout'))
363
+ }, timeout)
364
+ disposers.push(() => timers.clearTimeout(serverTimeout))
365
+ }),
366
+ )
367
+ }
332
368
 
333
- let serverTimeout
334
- const token = xuid()
369
+ if (signalPromise) {
370
+ promises.push(signalPromise)
371
+ }
335
372
 
336
- return await Promise.race([
337
- new Promise((resolve) => {
338
- this._syncEmitter.once(token, resolve)
339
- this._connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SYNC, [token])
340
- }),
341
- new Promise((resolve) => {
342
- serverTimeout = timers.setTimeout(() => {
343
- this._client._$onError(
344
- C.TOPIC.RECORD,
345
- C.EVENT.TIMEOUT,
346
- new Error('sync server timeout'),
347
- )
348
- resolve(null)
349
- }, timeout)
350
- }),
351
- signalPromise,
352
- ]).finally(() => {
353
- timers.clearTimeout(serverTimeout)
354
- })
373
+ await Promise.race(promises)
374
+ }
355
375
  } finally {
356
- if (onAbort) {
357
- signal?.removeEventListener('abort', onAbort)
376
+ for (const disposer of disposers) {
377
+ disposer()
358
378
  }
359
379
  }
360
380
  }
@@ -14,12 +14,23 @@ export default class RpcHandler<Methods extends Record<string, RpcMethodDef>> {
14
14
  unprovide: <Name extends keyof Methods>(name: Name) => void
15
15
 
16
16
  make: {
17
- <Name extends keyof Methods>(
17
+ <
18
+ Name extends keyof Methods | string,
19
+ Args extends Name extends keyof Methods ? Methods[Name][0] : unknown,
20
+ ReturnValue extends Name extends keyof Methods ? Methods[Name][1] : unknown,
21
+ >(
18
22
  name: Name,
19
- args: Methods[Name][0],
20
- callback: (error: unknown, response: Methods[Name][1]) => void,
23
+ args: Args,
24
+ ): Promise<ReturnValue>
25
+ <
26
+ Name extends keyof Methods | string,
27
+ Args extends Name extends keyof Methods ? Methods[Name][0] : unknown,
28
+ ReturnValue extends Name extends keyof Methods ? Methods[Name][1] : unknown,
29
+ >(
30
+ name: Name,
31
+ args: Args,
32
+ callback: (error: unknown, response: ReturnValue) => void,
21
33
  ): void
22
- <Name extends keyof Methods>(name: Name, args: Methods[Name][0]): Promise<Methods[Name][1]>
23
34
  }
24
35
  }
25
36
 
@@ -78,6 +78,10 @@ class Timeout {
78
78
  clear() {
79
79
  this.state = -1
80
80
  }
81
+
82
+ [Symbol.dispose]() {
83
+ this.state = -1
84
+ }
81
85
  }
82
86
 
83
87
  export function setTimeout(callback, delay, opaque) {
@@ -4,14 +4,12 @@ import { h64ToString, findBigIntPaths } from '../utils/utils.js'
4
4
 
5
5
  const PIPE = rxjs.pipe(
6
6
  rxjs.map((value) => {
7
- if (value == null) {
8
- return null
9
- } else if (typeof value === 'string') {
7
+ if (typeof value === 'string') {
10
8
  if (value.charAt(0) !== '{' && value.charAt(0) !== '[') {
11
9
  throw new Error(`invalid value: ${value}`)
12
10
  }
13
11
  return value
14
- } else if (typeof value === 'object') {
12
+ } else if (value != null && typeof value === 'object') {
15
13
  try {
16
14
  return JSON.stringify(value)
17
15
  } catch (err) {
@@ -78,24 +76,18 @@ export default class Listener {
78
76
  if (value$) {
79
77
  const subscription = value$.pipe(PIPE).subscribe({
80
78
  next: (data) => {
81
- if (data != null) {
82
- const version = `INF-${h64ToString(data)}`
83
- this._connection.sendMsg(this._topic, C.ACTIONS.UPDATE, [name, version, data])
84
- } else {
85
- this._connection.sendMsg(this._topic, C.ACTIONS.LISTEN_REJECT, [this._pattern, name])
86
- }
79
+ const version = `INF-${h64ToString(data)}`
80
+ this._connection.sendMsg(this._topic, C.ACTIONS.UPDATE, [name, version, data])
87
81
  },
88
82
  error: (err) => {
89
83
  this._error(name, err)
84
+
85
+ this._subscriptions.delete(name)
90
86
  this._connection.sendMsg(this._topic, C.ACTIONS.LISTEN_REJECT, [this._pattern, name])
91
87
  },
92
88
  })
93
89
 
94
90
  this._subscriptions.set(name, subscription)
95
-
96
- subscription.add(() => {
97
- this._subscriptions.delete(name)
98
- })
99
91
  } else {
100
92
  this._connection.sendMsg(this._topic, C.ACTIONS.LISTEN_REJECT, [this._pattern, name])
101
93
  }