@nxtedition/deepstream.io-client-js 23.4.46 → 23.4.47
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/constants/constants.js +1 -0
- package/src/message/connection.js +1 -0
- package/src/record/record-handler.js +12 -13
- package/src/record/record.js +93 -81
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ module.exports.CONNECTION_STATE.ERROR = 'ERROR'
|
|
|
10
10
|
module.exports.CONNECTION_STATE.RECONNECTING = 'RECONNECTING'
|
|
11
11
|
|
|
12
12
|
module.exports.RECORD_STATE = {}
|
|
13
|
+
module.exports.RECORD_STATE.INIT = -1
|
|
13
14
|
module.exports.RECORD_STATE.VOID = 0
|
|
14
15
|
module.exports.RECORD_STATE.CLIENT = 1
|
|
15
16
|
module.exports.RECORD_STATE.PENDING = 2
|
|
@@ -363,6 +363,7 @@ Connection.prototype._setState = function (state) {
|
|
|
363
363
|
this._client.emit(C.EVENT.CONNECTED, true)
|
|
364
364
|
} else if (state === C.CONNECTION_STATE.RECONNECTING || state === C.CONNECTION_STATE.CLOSED) {
|
|
365
365
|
this._client.emit(C.EVENT.CONNECTED, false)
|
|
366
|
+
this._reset()
|
|
366
367
|
}
|
|
367
368
|
}
|
|
368
369
|
|
|
@@ -76,26 +76,20 @@ class RecordHandler {
|
|
|
76
76
|
_prune()
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
_onRef(rec
|
|
80
|
-
|
|
81
|
-
const prev = prevRefs === 0
|
|
82
|
-
|
|
83
|
-
if (curr && !prev) {
|
|
79
|
+
_onRef(rec) {
|
|
80
|
+
if (rec.refs === 0) {
|
|
84
81
|
this._pruning.add(rec)
|
|
85
|
-
} else if (
|
|
82
|
+
} else if (rec.refs === 1) {
|
|
86
83
|
this._pruning.delete(rec)
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
_onState(rec, prevState) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (curr && !prev) {
|
|
88
|
+
// TODO (perf): avoid pending.has
|
|
89
|
+
if (rec.state < Record.STATE.SERVER && !this._pending.has(rec)) {
|
|
95
90
|
this._pending.add(rec)
|
|
96
91
|
rec.ref()
|
|
97
|
-
} else if (
|
|
98
|
-
this._pending.delete(rec)
|
|
92
|
+
} else if (this._pending.delete(rec)) {
|
|
99
93
|
rec.unref()
|
|
100
94
|
}
|
|
101
95
|
}
|
|
@@ -181,11 +175,15 @@ class RecordHandler {
|
|
|
181
175
|
}
|
|
182
176
|
}
|
|
183
177
|
|
|
178
|
+
const xs = new Set()
|
|
179
|
+
|
|
184
180
|
const onUpdate = (rec) => {
|
|
185
181
|
if (rec.state < C.RECORD_STATE.SERVER) {
|
|
186
182
|
return
|
|
187
183
|
}
|
|
188
184
|
|
|
185
|
+
xs.delete(rec.name)
|
|
186
|
+
|
|
189
187
|
rec.unsubscribe(onUpdate)
|
|
190
188
|
rec.unref()
|
|
191
189
|
counter -= 1
|
|
@@ -195,8 +193,9 @@ class RecordHandler {
|
|
|
195
193
|
|
|
196
194
|
for (const rec of this._pending) {
|
|
197
195
|
if (rec.state < C.RECORD_STATE.SERVER) {
|
|
198
|
-
rec.
|
|
196
|
+
xs.add(rec.name)
|
|
199
197
|
rec.subscribe(onUpdate)
|
|
198
|
+
rec.ref()
|
|
200
199
|
counter += 1
|
|
201
200
|
}
|
|
202
201
|
}
|
package/src/record/record.js
CHANGED
|
@@ -23,7 +23,9 @@ class Record {
|
|
|
23
23
|
this._updating = null
|
|
24
24
|
this._patches = null
|
|
25
25
|
|
|
26
|
-
this.
|
|
26
|
+
this._handler._onState(this, Record.STATE.INIT)
|
|
27
|
+
|
|
28
|
+
this._subscribe()
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
get name() {
|
|
@@ -50,8 +52,8 @@ class Record {
|
|
|
50
52
|
const prevRefs = this._refs
|
|
51
53
|
|
|
52
54
|
this._refs += 1
|
|
53
|
-
if (this._refs === 1) {
|
|
54
|
-
this.
|
|
55
|
+
if (this._refs === 1 && !this._subscribed) {
|
|
56
|
+
this._subscribe()
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
this._handler._onRef(this, prevRefs)
|
|
@@ -60,7 +62,7 @@ class Record {
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
unref() {
|
|
63
|
-
invariant(this._refs > 0,
|
|
65
|
+
invariant(this._refs > 0, 'missing refs')
|
|
64
66
|
|
|
65
67
|
const prevRefs = this._refs
|
|
66
68
|
|
|
@@ -101,44 +103,50 @@ class Record {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
set(pathOrData, dataOrNil) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
const prevState = this._state
|
|
107
|
+
const prevData = this._data
|
|
108
|
+
const prevVersion = this._version
|
|
106
109
|
|
|
107
|
-
|
|
108
|
-
this._error(C.EVENT.USER_ERROR, 'cannot set')
|
|
109
|
-
return
|
|
110
|
-
}
|
|
110
|
+
invariant(this._refs > 0, 'missing refs')
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
if (this._version.charAt(0) === 'I' || this._name.startsWith('_')) {
|
|
113
|
+
this._error(C.EVENT.USER_ERROR, 'cannot set')
|
|
114
|
+
return
|
|
115
|
+
}
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
if (path === undefined && Object.keys(data).some((prop) => prop.startsWith('_'))) {
|
|
119
|
-
throw new Error('invalid argument: data')
|
|
120
|
-
}
|
|
121
|
-
if (
|
|
122
|
-
path !== undefined &&
|
|
123
|
-
(typeof path !== 'string' || path.length === 0 || path.startsWith('_')) &&
|
|
124
|
-
(!Array.isArray(path) || path.length === 0 || path[0].startsWith('_'))
|
|
125
|
-
) {
|
|
126
|
-
throw new Error('invalid argument: path')
|
|
127
|
-
}
|
|
117
|
+
const path = arguments.length === 1 ? undefined : pathOrData
|
|
118
|
+
const data = arguments.length === 1 ? pathOrData : dataOrNil
|
|
128
119
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
120
|
+
if (path === undefined && !utils.isPlainObject(data)) {
|
|
121
|
+
throw new Error('invalid argument: data')
|
|
122
|
+
}
|
|
123
|
+
if (path === undefined && Object.keys(data).some((prop) => prop.startsWith('_'))) {
|
|
124
|
+
throw new Error('invalid argument: data')
|
|
125
|
+
}
|
|
126
|
+
if (
|
|
127
|
+
path !== undefined &&
|
|
128
|
+
(typeof path !== 'string' || path.length === 0 || path.startsWith('_')) &&
|
|
129
|
+
(!Array.isArray(path) || path.length === 0 || path[0].startsWith('_'))
|
|
130
|
+
) {
|
|
131
|
+
throw new Error('invalid argument: path')
|
|
132
|
+
}
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
this._update(jsonPath.set(this._data, path, data, false))
|
|
135
|
+
|
|
136
|
+
if (this._state < Record.STATE.SERVER) {
|
|
137
|
+
this._patches = path && this._patches ? this._patches : []
|
|
138
|
+
this._patches.push(path, cloneDeep(data))
|
|
139
|
+
this._state = Record.STATE.PENDING
|
|
140
|
+
this._handler._onState(this, prevState)
|
|
141
|
+
this._emitUpdate()
|
|
142
|
+
} else if (this._data !== prevData || this._version !== prevVersion) {
|
|
143
|
+
this._emitUpdate()
|
|
144
|
+
}
|
|
137
145
|
}
|
|
138
146
|
|
|
139
147
|
// TODO (fix): timeout + signal
|
|
140
148
|
when(stateOrNull) {
|
|
141
|
-
invariant(this._refs > 0,
|
|
149
|
+
invariant(this._refs > 0, 'missing refs')
|
|
142
150
|
|
|
143
151
|
const state = stateOrNull == null ? Record.STATE.SERVER : stateOrNull
|
|
144
152
|
|
|
@@ -169,7 +177,7 @@ class Record {
|
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
update(pathOrUpdater, updaterOrNil) {
|
|
172
|
-
invariant(this._refs > 0,
|
|
180
|
+
invariant(this._refs > 0, 'missing refs')
|
|
173
181
|
|
|
174
182
|
if (this._version.charAt(0) === 'I') {
|
|
175
183
|
this._handler._client._$onError(C.TOPIC.RECORD, C.EVENT.UPDATE_ERROR, 'cannot update', [
|
|
@@ -209,9 +217,9 @@ class Record {
|
|
|
209
217
|
|
|
210
218
|
_$onMessage(message) {
|
|
211
219
|
if (message.action === C.ACTIONS.UPDATE) {
|
|
212
|
-
this.
|
|
220
|
+
this._onUpdate(message.data)
|
|
213
221
|
} else if (message.action === C.ACTIONS.SUBSCRIPTION_HAS_PROVIDER) {
|
|
214
|
-
this.
|
|
222
|
+
this._onSubscriptionHasProvider(message.data)
|
|
215
223
|
} else {
|
|
216
224
|
return false
|
|
217
225
|
}
|
|
@@ -220,35 +228,34 @@ class Record {
|
|
|
220
228
|
}
|
|
221
229
|
|
|
222
230
|
_$onConnectionStateChange() {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (this._refs > 0) {
|
|
227
|
-
this._subscribe()
|
|
228
|
-
}
|
|
231
|
+
const connection = this._handler._connection
|
|
232
|
+
if (connection.connected) {
|
|
233
|
+
invariant(!this._subscribed, 'must not be subscribed')
|
|
229
234
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (this._state > Record.STATE.CLIENT) {
|
|
238
|
-
this._state = Record.STATE.CLIENT
|
|
235
|
+
if (this._refs > 0) {
|
|
236
|
+
this._subscribe()
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (this._updating) {
|
|
240
|
+
for (const update of this._updating.values()) {
|
|
241
|
+
connection.sendMsg(C.TOPIC.RECORD, C.ACTIONS.UPDATE, update)
|
|
239
242
|
}
|
|
240
243
|
}
|
|
241
|
-
}
|
|
244
|
+
} else {
|
|
245
|
+
this._unsubscribe()
|
|
246
|
+
}
|
|
242
247
|
}
|
|
243
248
|
|
|
244
249
|
_$dispose() {
|
|
245
|
-
this.
|
|
250
|
+
this._unsubscribe()
|
|
246
251
|
}
|
|
247
252
|
|
|
248
253
|
_subscribe() {
|
|
249
|
-
invariant(this._refs, this._name + ' missing refs')
|
|
250
|
-
|
|
251
254
|
const connection = this._handler._connection
|
|
255
|
+
|
|
256
|
+
invariant(this._refs, 'missing refs')
|
|
257
|
+
invariant(!this._subscribed, 'must not be subscribed')
|
|
258
|
+
|
|
252
259
|
if (!this._subscribed && connection.connected) {
|
|
253
260
|
connection.sendMsg1(C.TOPIC.RECORD, C.ACTIONS.SUBSCRIBE, this._name)
|
|
254
261
|
this._subscribed = true
|
|
@@ -256,17 +263,22 @@ class Record {
|
|
|
256
263
|
}
|
|
257
264
|
|
|
258
265
|
_unsubscribe() {
|
|
259
|
-
|
|
260
|
-
invariant(!this._patches, this._name + ' must not have patches')
|
|
261
|
-
|
|
266
|
+
const prevState = this._state
|
|
262
267
|
const connection = this._handler._connection
|
|
268
|
+
|
|
269
|
+
invariant(!connection.connected || !this._refs, 'must not have refs')
|
|
270
|
+
invariant(!connection.connected || !this._patches, 'must not have patches')
|
|
271
|
+
invariant(!connection.connected || this._subscribed, 'must be subscribed')
|
|
272
|
+
|
|
263
273
|
if (this._subscribed && connection.connected) {
|
|
264
274
|
connection.sendMsg1(C.TOPIC.RECORD, C.ACTIONS.UNSUBSCRIBE, this._name)
|
|
275
|
+
this._subscribed = false
|
|
265
276
|
}
|
|
266
277
|
|
|
267
|
-
this._subscribed = false
|
|
268
278
|
if (this._state > Record.STATE.CLIENT) {
|
|
269
279
|
this._state = Record.STATE.CLIENT
|
|
280
|
+
this._handler._onState(this, prevState)
|
|
281
|
+
this._emitUpdate()
|
|
270
282
|
}
|
|
271
283
|
}
|
|
272
284
|
|
|
@@ -297,6 +309,10 @@ class Record {
|
|
|
297
309
|
}
|
|
298
310
|
|
|
299
311
|
_onUpdate([, version, data]) {
|
|
312
|
+
const prevState = this._state
|
|
313
|
+
const prevData = this._data
|
|
314
|
+
const prevVersion = this._version
|
|
315
|
+
|
|
300
316
|
if (this._updating?.delete(version)) {
|
|
301
317
|
this._handler._stats.updating -= 1
|
|
302
318
|
}
|
|
@@ -324,10 +340,16 @@ class Record {
|
|
|
324
340
|
|
|
325
341
|
if (this._state < Record.STATE.SERVER) {
|
|
326
342
|
this._state = this._version.charAt(0) === 'I' ? Record.STATE.STALE : Record.STATE.SERVER
|
|
343
|
+
this._handler._onState(this, prevState)
|
|
344
|
+
this._emitUpdate()
|
|
345
|
+
} else if (this._data !== prevData || this._version !== prevVersion) {
|
|
346
|
+
this._emitUpdate()
|
|
327
347
|
}
|
|
328
348
|
}
|
|
329
349
|
|
|
330
350
|
_onSubscriptionHasProvider([, hasProvider]) {
|
|
351
|
+
const prevState = this._state
|
|
352
|
+
|
|
331
353
|
this._state =
|
|
332
354
|
hasProvider &&
|
|
333
355
|
messageParser.convertTyped(hasProvider, this._handler._client) &&
|
|
@@ -336,6 +358,11 @@ class Record {
|
|
|
336
358
|
: this._version.charAt(0) === 'I'
|
|
337
359
|
? Record.STATE.STALE
|
|
338
360
|
: Record.STATE.SERVER
|
|
361
|
+
|
|
362
|
+
if (this._state !== prevState) {
|
|
363
|
+
this._handler._onState(this, prevState)
|
|
364
|
+
this._emitUpdate()
|
|
365
|
+
}
|
|
339
366
|
}
|
|
340
367
|
|
|
341
368
|
_error(event, msgOrError, data) {
|
|
@@ -356,30 +383,15 @@ class Record {
|
|
|
356
383
|
return `${start}-${revid}`
|
|
357
384
|
}
|
|
358
385
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const ret = fn()
|
|
365
|
-
|
|
366
|
-
if (this._state !== prevState || this._data !== prevData || this._version !== prevVersion) {
|
|
367
|
-
try {
|
|
368
|
-
this._subscriptionsEmitting = true
|
|
369
|
-
|
|
370
|
-
if (this._state !== prevState) {
|
|
371
|
-
this._handler.onState(this, prevState)
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
for (const fn of this._subscriptions) {
|
|
375
|
-
fn(this)
|
|
376
|
-
}
|
|
377
|
-
} finally {
|
|
378
|
-
this._subscriptionsEmitting = false
|
|
386
|
+
_emitUpdate() {
|
|
387
|
+
this._subscriptionsEmitting = true
|
|
388
|
+
try {
|
|
389
|
+
for (const fn of this._subscriptions) {
|
|
390
|
+
fn(this)
|
|
379
391
|
}
|
|
392
|
+
} finally {
|
|
393
|
+
this._subscriptionsEmitting = false
|
|
380
394
|
}
|
|
381
|
-
|
|
382
|
-
return ret
|
|
383
395
|
}
|
|
384
396
|
}
|
|
385
397
|
|