@nxtedition/deepstream.io-client-js 24.2.9 → 24.3.0

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.2.9",
3
+ "version": "24.3.0",
4
4
  "description": "the javascript client for deepstream.io",
5
5
  "homepage": "http://deepstream.io",
6
6
  "bugs": {
@@ -82,14 +82,6 @@ Connection.prototype.sendMsg = function (topic, action, data) {
82
82
  return this.send(messageBuilder.getMsg(topic, action, data))
83
83
  }
84
84
 
85
- Connection.prototype.sendMsg1 = function (topic, action, p0) {
86
- return this.send(messageBuilder.getMsg1(topic, action, p0))
87
- }
88
-
89
- Connection.prototype.sendMsg2 = function (topic, action, p0, p1) {
90
- return this.send(messageBuilder.getMsg2(topic, action, p0, p1))
91
- }
92
-
93
85
  Connection.prototype.close = function () {
94
86
  this._deliberateClose = true
95
87
  this._endpoint?.close()
@@ -101,8 +93,7 @@ Connection.prototype.close = function () {
101
93
  }
102
94
 
103
95
  Connection.prototype._createEndpoint = function () {
104
- const decoder = new TextDecoder()
105
- if (NodeWebSocket) {
96
+ if (utils.isNode) {
106
97
  this._endpoint = new NodeWebSocket(this._url, {
107
98
  generateMask() {},
108
99
  })
@@ -110,16 +101,16 @@ Connection.prototype._createEndpoint = function () {
110
101
  this._endpoint = new BrowserWebSocket(this._url)
111
102
  this._endpoint.binaryType = 'arraybuffer'
112
103
  }
113
-
114
- this._endpoint.onmessage = ({ data }) => {
115
- this._onMessage(typeof data === 'string' ? data : decoder.decode(data))
116
- }
117
-
118
104
  this._corked = false
119
105
 
120
106
  this._endpoint.onopen = this._onOpen.bind(this)
121
107
  this._endpoint.onerror = this._onError.bind(this)
122
108
  this._endpoint.onclose = this._onClose.bind(this)
109
+
110
+ const decoder = new TextDecoder()
111
+ this._endpoint.onmessage = ({ data }) => {
112
+ this._onMessage(typeof data === 'string' ? data : decoder.decode(data))
113
+ }
123
114
  }
124
115
 
125
116
  Connection.prototype.send = function (message) {
@@ -255,20 +246,20 @@ Connection.prototype._recvMessages = function (deadline) {
255
246
  continue
256
247
  }
257
248
 
258
- try {
259
- messageParser.parseMessage(message, this._client, this._message)
249
+ if (this._logger) {
250
+ this._logger.trace(message, 'receive')
251
+ }
252
+
253
+ messageParser.parseMessage(message, this._client, this._message)
260
254
 
261
- this.emit('recv', this._message)
255
+ this.emit('recv', this._message)
262
256
 
263
- if (this._message.topic === C.TOPIC.CONNECTION) {
264
- this._handleConnectionResponse(this._message)
265
- } else if (this._message.topic === C.TOPIC.AUTH) {
266
- this._handleAuthResponse(this._message)
267
- } else {
268
- this._client._$onMessage(this._message)
269
- }
270
- } catch (err) {
271
- this._onError(err)
257
+ if (this._message.topic === C.TOPIC.CONNECTION) {
258
+ this._handleConnectionResponse(this._message)
259
+ } else if (this._message.topic === C.TOPIC.AUTH) {
260
+ this._handleAuthResponse(this._message)
261
+ } else {
262
+ this._client._$onMessage(this._message)
272
263
  }
273
264
  }
274
265
 
@@ -1,33 +1,79 @@
1
1
  const C = require('../constants/constants')
2
2
 
3
- const SEP = C.MESSAGE_PART_SEPERATOR
3
+ const poolEncoder = new TextEncoder()
4
+
5
+ let poolSize
6
+ let poolBuffer
7
+ let poolView
8
+ let poolOffset
9
+
10
+ function reallocPool(size) {
11
+ poolSize = size ?? poolSize ?? 1024 * 1024
12
+ poolBuffer = new Uint8Array(new ArrayBuffer(poolSize))
13
+ poolView = new DataView(poolBuffer.buffer)
14
+ poolOffset = 0
15
+ }
16
+
17
+ function alignPool() {
18
+ // Ensure aligned slices
19
+ if (poolOffset & 0x7) {
20
+ poolOffset |= 0x7
21
+ poolOffset++
22
+ }
23
+ }
24
+
25
+ reallocPool()
4
26
 
5
27
  module.exports.getMsg = function (topic, action, data) {
6
28
  if (data && !(data instanceof Array)) {
7
29
  throw new Error('data must be an array')
8
30
  }
9
31
 
10
- const sendData = [topic, action]
32
+ if (poolOffset + poolSize / 16 >= poolSize) {
33
+ reallocPool()
34
+ } else {
35
+ alignPool()
36
+ }
37
+
38
+ const start = poolOffset
39
+
40
+ poolBuffer[poolOffset++] = topic.charCodeAt(0)
41
+ poolBuffer[poolOffset++] = 31
42
+ for (let n = 0; n < action.length; n++) {
43
+ poolBuffer[poolOffset++] = action.charCodeAt(n)
44
+ }
11
45
 
12
46
  if (data) {
13
47
  for (let i = 0; i < data.length; i++) {
14
- if (typeof data[i] === 'object') {
15
- sendData.push(JSON.stringify(data[i]))
48
+ const type = typeof data[i]
49
+ if (data[i] == null) {
50
+ poolBuffer[poolOffset++] = 31
51
+ } else if (type === 'object') {
52
+ poolBuffer[poolOffset++] = 31
53
+ const res = poolEncoder.encodeInto(
54
+ JSON.stringify(data[i]),
55
+ new Uint8Array(poolBuffer.buffer, poolOffset)
56
+ )
57
+ poolOffset += res.written
58
+ } else if (type === 'bigint') {
59
+ poolBuffer[poolOffset++] = 31
60
+ poolView.setBigUint64(poolOffset, data[i], false)
61
+ poolOffset += 8
62
+ } else if (type === 'string') {
63
+ poolBuffer[poolOffset++] = 31
64
+ const res = poolEncoder.encodeInto(data[i], new Uint8Array(poolBuffer.buffer, poolOffset))
65
+ poolOffset += res.written
16
66
  } else {
17
- sendData.push(data[i])
67
+ throw new Error('invalid data')
68
+ }
69
+
70
+ if (poolOffset >= poolBuffer.length) {
71
+ reallocPool(start === 0 ? poolSize * 2 : poolSize)
72
+ return this.getMsg(topic, action, data)
18
73
  }
19
74
  }
20
75
  }
21
-
22
- return sendData.join(SEP)
23
- }
24
-
25
- module.exports.getMsg1 = function (topic, action, p0) {
26
- return `${topic}${SEP}${action}${SEP}${p0}`
27
- }
28
-
29
- module.exports.getMsg2 = function (topic, action, p0, p1) {
30
- return `${topic}${SEP}${action}${SEP}${p0}${SEP}${p1}`
76
+ return new Uint8Array(poolBuffer.buffer, start, poolOffset - start)
31
77
  }
32
78
 
33
79
  module.exports.typed = function (value) {
@@ -97,19 +97,11 @@ class RecordHandler {
97
97
  this._connection = connection
98
98
  this._client = client
99
99
  this._records = new Map()
100
- this._cache = new Map()
101
100
  this._listeners = new Map()
102
101
  this._pruning = new Set()
103
102
  this._patching = new Map()
104
103
  this._updating = new Map()
105
104
 
106
- this._registry = new FinalizationRegistry((name) => {
107
- const entry = this._cache.get(name)
108
- if (entry && entry.deref && entry.deref() === undefined) {
109
- this._cache.delete(name)
110
- }
111
- })
112
-
113
105
  this._connected = 0
114
106
  this._stats = {
115
107
  updating: 0,
@@ -142,11 +134,6 @@ class RecordHandler {
142
134
  for (const rec of pruning) {
143
135
  rec._$dispose()
144
136
  this._records.delete(rec.name)
145
-
146
- if (!this._cache.has(rec.name)) {
147
- this._cache.set(rec.name, new WeakRef(rec))
148
- this._registry.register(rec, rec.name)
149
- }
150
137
  }
151
138
 
152
139
  this._stats.pruning -= pruning.size
@@ -232,7 +219,7 @@ class RecordHandler {
232
219
  let record = this._records.get(name)
233
220
 
234
221
  if (!record) {
235
- record = this._cache.get(name)?.deref() ?? new Record(name, this)
222
+ record = new Record(name, this)
236
223
  this._stats.records += 1
237
224
  this._stats.created += 1
238
225
  this._records.set(name, record)
@@ -386,7 +373,7 @@ class RecordHandler {
386
373
  queue[n](queue[n + 1])
387
374
  }
388
375
  })
389
- this._connection.sendMsg2(C.TOPIC.RECORD, C.ACTIONS.SYNC, token, 'WEAK')
376
+ this._connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SYNC, [token, 'WEAK'])
390
377
  }, 1)
391
378
  }
392
379
 
@@ -11,8 +11,12 @@ class Record {
11
11
  static STATE = C.RECORD_STATE
12
12
 
13
13
  constructor(name, handler) {
14
+ const connection = handler._connection
15
+
14
16
  this._handler = handler
17
+
15
18
  this._name = name
19
+ this._key = connection.hasher?.h64(name) ?? name
16
20
  this._version = ''
17
21
  this._data = jsonPath.EMPTY
18
22
  this._state = C.RECORD_STATE.VOID
@@ -21,7 +25,10 @@ class Record {
21
25
  this._emitting = false
22
26
  /** @type Map? */ this._updating = null
23
27
  /** @type Array? */ this._patching = null
24
- this._subscribed = false
28
+ this._subscribed = connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, [
29
+ this._name,
30
+ this._key,
31
+ ])
25
32
  }
26
33
 
27
34
  /** @type {string} */
@@ -59,7 +66,8 @@ class Record {
59
66
  if (this._refs === 1) {
60
67
  this._handler._onPruning(this, false)
61
68
  this._subscribed =
62
- this._subscribed || connection.sendMsg1(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, this._name)
69
+ this._subscribed ||
70
+ connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, [this._name, this._key])
63
71
  }
64
72
  return this
65
73
  }
@@ -320,8 +328,10 @@ class Record {
320
328
  const connection = this._handler._connection
321
329
 
322
330
  if (connected) {
331
+ this._key = typeof this._key === 'bigint' ? this._key : connection.hasher?.h64(this._name)
323
332
  this._subscribed =
324
- this._refs > 0 && connection.sendMsg1(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, this._name)
333
+ this._refs > 0 &&
334
+ connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, [this._name, this._key])
325
335
 
326
336
  if (this._updating) {
327
337
  for (const update of this._updating.values()) {
@@ -346,7 +356,7 @@ class Record {
346
356
  invariant(!this._updating, 'must not have updates')
347
357
 
348
358
  if (this._subscribed) {
349
- connection.sendMsg1(C.TOPIC.RECORD, C.ACTIONS.UNSUBSCRIBE, this._name)
359
+ connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.UNSUBSCRIBE, [this._key])
350
360
  this._subscribed = false
351
361
  }
352
362
 
@@ -368,7 +378,7 @@ class Record {
368
378
  const prevVersion = this._version
369
379
  const nextVersion = this._makeVersion(parseInt(prevVersion) + 1)
370
380
 
371
- const update = [this._name, nextVersion, jsonPath.stringify(nextData), prevVersion]
381
+ const update = [this._key, nextVersion, jsonPath.stringify(nextData), prevVersion]
372
382
 
373
383
  if (!this._updating) {
374
384
  this._onUpdating(true)