vrpc 3.12.1 → 3.13.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.
@@ -546,7 +546,27 @@ class VrpcClient extends EventEmitter {
546
546
  const topic = `${this._domain}/${agent}/${className}/__static__/__delete__`
547
547
  this._mqttPublish(topic, JSON.stringify(json))
548
548
  delete this._proxies[`${agent}/${className}/${instance}`]
549
- return this._handleAgentAnswer(json, agent)
549
+ const deleted = await this._handleAgentAnswer(json, agent)
550
+ // the answer and the class info that no longer lists the instance
551
+ // travel on different topics, and a broker need not keep their order:
552
+ // what this client deleted is gone for it at once
553
+ if (deleted === true) this._forgetInstance({ agent, className, instance })
554
+ return deleted
555
+ }
556
+
557
+ /**
558
+ * Takes an instance off this client's view of its agent, the way a class
559
+ * info without it does: listing, instanceGone, cached subscriptions. A
560
+ * class info that arrives later finds nothing left to remove.
561
+ */
562
+ _forgetInstance ({ agent, className, instance }) {
563
+ const info = this._agents[agent] && this._agents[agent].classes[className]
564
+ if (!info || !Array.isArray(info.instances)) return
565
+ if (!info.instances.includes(instance)) return
566
+ info.instances = info.instances.filter(x => x !== instance)
567
+ const domain = this._domain
568
+ this.emit('instanceGone', [instance], { domain, agent, className })
569
+ this._clearCachedSubscriptions({ lostInstance: instance, agent, className })
550
570
  }
551
571
 
552
572
  /**
@@ -98,6 +98,8 @@ class VrpcPersistor {
98
98
  .replace(/[^a-zA-Z0-9]/g, '-')}`
99
99
 
100
100
  this._storage = null
101
+ // the 'update' listener on each persisted instance, dropped on delete
102
+ this._updateListeners = new Map()
101
103
  this._isInitialized = this._init(Storage)
102
104
 
103
105
  this._log.info(
@@ -282,7 +284,11 @@ class VrpcPersistor {
282
284
  const obj = VrpcAdapter.getInstance(instance)
283
285
  // Ensure the object is an event emitter
284
286
  if (obj && typeof obj.on === 'function') {
285
- obj.on('update', data => {
287
+ const listener = data => {
288
+ // a deleted object never rewrites the record of its name
289
+ // (#1705): an in-process delete announces nothing
290
+ const live = VrpcAdapter._instances.get(instance)
291
+ if (!live || live.instance !== obj) return
286
292
  this._log.info(
287
293
  `[VrpcPersistor] Persisting update for: ${instance} (${className})`
288
294
  )
@@ -293,7 +299,9 @@ class VrpcPersistor {
293
299
  `[VrpcPersistor] Failed persisting update of ${instance} (${className}): ${err.message}`
294
300
  )
295
301
  )
296
- })
302
+ }
303
+ obj.on('update', listener)
304
+ this._updateListeners.set(instance, { obj, listener })
297
305
  }
298
306
  } catch (err) {
299
307
  this._log.warn(
@@ -304,6 +312,11 @@ class VrpcPersistor {
304
312
 
305
313
  // Persist instance deletion
306
314
  VrpcAdapter.on('delete', ({ instance, className }) => {
315
+ const update = this._updateListeners.get(instance)
316
+ if (update) {
317
+ this._updateListeners.delete(instance)
318
+ update.obj.removeListener('update', update.listener)
319
+ }
307
320
  this._log.info(
308
321
  `[VrpcPersistor] Deleting persisted instance: ${instance} (${className})`
309
322
  )
@@ -230,6 +230,17 @@ function mkextract (opts) {
230
230
  indent = startPos + MARKER_START.length
231
231
  }
232
232
 
233
+ // a member with a computed key ([Symbol.asyncDispose]) names no remote
234
+ // function: the block documents it and nothing else - without this it
235
+ // landed on the first call in the member's body
236
+ if (
237
+ findMethod &&
238
+ /^\s*(static\s+)?(async\s+)?\*?\s*((get|set)\s+)?\[[^\]]+\]\s*\(/.test(line)
239
+ ) {
240
+ result = parse_block(chunk, opts)
241
+ findMethod = false
242
+ }
243
+
233
244
  if (findMethod) {
234
245
  const ret = line.match(/\s*function\s+(\w+)\s*\(/) ||
235
246
  line.match(/\s*(\w+)\s*=?\s*\(/)