vrpc 3.16.0 → 3.16.1
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/browser/vrpc.js +1 -1
- package/package.json +1 -1
- package/vrpc/VrpcAdapter.js +11 -3
- package/vrpc/VrpcAgent.js +35 -5
- package/vrpc/VrpcBrowserAdapter.js +11 -3
- package/vrpc/VrpcBrowserAgent.js +35 -5
package/package.json
CHANGED
package/vrpc/VrpcAdapter.js
CHANGED
|
@@ -661,8 +661,15 @@ class VrpcAdapter {
|
|
|
661
661
|
const [instanceId, ...args] = json.a
|
|
662
662
|
VrpcAdapter._assertInstanceName(instanceId)
|
|
663
663
|
const existing = VrpcAdapter._instances.get(instanceId)
|
|
664
|
-
if (existing
|
|
665
|
-
|
|
664
|
+
if (existing) {
|
|
665
|
+
// an id is never re-homed: an isolated instance stays isolated
|
|
666
|
+
if (existing.isIsolated) {
|
|
667
|
+
throw new Error(`Instance '${instanceId}' exists as an isolated instance`)
|
|
668
|
+
}
|
|
669
|
+
// a create of a name that exists returns it unchanged: its class
|
|
670
|
+
// and arguments stay, and nothing announces it (no 'create' event)
|
|
671
|
+
json.r = instanceId
|
|
672
|
+
return existing.instance
|
|
666
673
|
}
|
|
667
674
|
instance = VrpcAdapter._create(className, instanceId, ...args)
|
|
668
675
|
VrpcAdapter._instances.set(instanceId, {
|
|
@@ -1313,7 +1320,8 @@ class VrpcAdapter {
|
|
|
1313
1320
|
/**
|
|
1314
1321
|
* Event 'create'
|
|
1315
1322
|
*
|
|
1316
|
-
* Emitted
|
|
1323
|
+
* Emitted once an instance was created. A create of a name that exists
|
|
1324
|
+
* returns that instance and emits nothing.
|
|
1317
1325
|
*
|
|
1318
1326
|
* @event VrpcAdapter#create
|
|
1319
1327
|
* @type {Object}
|
package/vrpc/VrpcAgent.js
CHANGED
|
@@ -646,6 +646,9 @@ class VrpcAgent extends EventEmitter {
|
|
|
646
646
|
] of VrpcAdapter._instances.entries()) {
|
|
647
647
|
batches.push(this._methodsTopic(className, instanceId))
|
|
648
648
|
}
|
|
649
|
+
// what the broker retains of this agent's classes: an earlier run's
|
|
650
|
+
// class that is no longer offered is cleared (_sweepClassInfo)
|
|
651
|
+
batches.push(`${this._baseTopic}/+/__classInfoConcise__`)
|
|
649
652
|
let pending = batches.length
|
|
650
653
|
const announce = () => {
|
|
651
654
|
// a connection that ended meanwhile announces nothing: the next
|
|
@@ -659,10 +662,6 @@ class VrpcAgent extends EventEmitter {
|
|
|
659
662
|
this._serving = true
|
|
660
663
|
this.emit('connect')
|
|
661
664
|
}
|
|
662
|
-
if (pending === 0) {
|
|
663
|
-
announce()
|
|
664
|
-
return
|
|
665
|
-
}
|
|
666
665
|
for (const topic of batches) {
|
|
667
666
|
this._mqttSubscribe(topic, undefined, () => {
|
|
668
667
|
pending -= 1
|
|
@@ -743,7 +742,38 @@ class VrpcAgent extends EventEmitter {
|
|
|
743
742
|
return topics
|
|
744
743
|
}
|
|
745
744
|
|
|
746
|
-
|
|
745
|
+
/**
|
|
746
|
+
* A class info under this agent's own name. What the broker retained of
|
|
747
|
+
* a class this agent does not offer is a ghost of an earlier run - a
|
|
748
|
+
* class info only `end({ unregister: true })` would have cleared - and
|
|
749
|
+
* clients would list the class forever: it is cleared, in full and
|
|
750
|
+
* concise. Everything else on the topic - the agent's own announcements
|
|
751
|
+
* and clears, routed back live - passes without a word.
|
|
752
|
+
*
|
|
753
|
+
* @returns {Boolean} whether the message was a class info
|
|
754
|
+
* @private
|
|
755
|
+
*/
|
|
756
|
+
_sweepClassInfo (topic, data, packet) {
|
|
757
|
+
const prefix = `${this._baseTopic}/`
|
|
758
|
+
if (!topic.startsWith(prefix)) return false
|
|
759
|
+
const tokens = topic.slice(prefix.length).split('/')
|
|
760
|
+
if (tokens.length !== 2) return false
|
|
761
|
+
const [className, info] = tokens
|
|
762
|
+
if (info !== '__classInfoConcise__' && info !== '__classInfo__') {
|
|
763
|
+
return false
|
|
764
|
+
}
|
|
765
|
+
const retained = !!packet && packet.retain
|
|
766
|
+
if (!retained || data.length === 0) return true
|
|
767
|
+
if (this._getClasses().includes(className)) return true
|
|
768
|
+
this._log.info(`Clearing the class info of ${className}, no longer offered`)
|
|
769
|
+
for (const name of ['__classInfo__', '__classInfoConcise__']) {
|
|
770
|
+
this._mqttPublish(`${prefix}${className}/${name}`, null, { retain: true })
|
|
771
|
+
}
|
|
772
|
+
return true
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
_handleMessage (topic, data, packet) {
|
|
776
|
+
if (this._sweepClassInfo(topic, data, packet)) return
|
|
747
777
|
let json
|
|
748
778
|
try {
|
|
749
779
|
json = JSON.parse(data.toString())
|
|
@@ -469,8 +469,15 @@ class VrpcAdapter {
|
|
|
469
469
|
const [instanceId, ...args] = json.a
|
|
470
470
|
VrpcAdapter._assertInstanceName(instanceId)
|
|
471
471
|
const existing = VrpcAdapter._instances.get(instanceId)
|
|
472
|
-
if (existing
|
|
473
|
-
|
|
472
|
+
if (existing) {
|
|
473
|
+
// an id is never re-homed: an isolated instance stays isolated
|
|
474
|
+
if (existing.isIsolated) {
|
|
475
|
+
throw new Error(`Instance '${instanceId}' exists as an isolated instance`)
|
|
476
|
+
}
|
|
477
|
+
// a create of a name that exists returns it unchanged: its class
|
|
478
|
+
// and arguments stay, and nothing announces it (no 'create' event)
|
|
479
|
+
json.r = instanceId
|
|
480
|
+
return existing.instance
|
|
474
481
|
}
|
|
475
482
|
instance = VrpcAdapter._create(className, instanceId, ...args)
|
|
476
483
|
VrpcAdapter._instances.set(instanceId, {
|
|
@@ -1132,7 +1139,8 @@ class VrpcAdapter {
|
|
|
1132
1139
|
/**
|
|
1133
1140
|
* Event 'create'
|
|
1134
1141
|
*
|
|
1135
|
-
* Emitted
|
|
1142
|
+
* Emitted once an instance was created. A create of a name that exists
|
|
1143
|
+
* returns that instance and emits nothing.
|
|
1136
1144
|
*
|
|
1137
1145
|
* @event VrpcAdapter#create
|
|
1138
1146
|
* @type {Object}
|
package/vrpc/VrpcBrowserAgent.js
CHANGED
|
@@ -478,6 +478,9 @@ class VrpcAgent extends EventEmitter {
|
|
|
478
478
|
] of VrpcAdapter._instances.entries()) {
|
|
479
479
|
batches.push(this._methodsTopic(className, instanceId))
|
|
480
480
|
}
|
|
481
|
+
// what the broker retains of this agent's classes: an earlier run's
|
|
482
|
+
// class that is no longer offered is cleared (_sweepClassInfo)
|
|
483
|
+
batches.push(`${this._baseTopic}/+/__classInfoConcise__`)
|
|
481
484
|
let pending = batches.length
|
|
482
485
|
const announce = () => {
|
|
483
486
|
// a connection that ended meanwhile announces nothing: the next
|
|
@@ -490,10 +493,6 @@ class VrpcAgent extends EventEmitter {
|
|
|
490
493
|
this._serving = true
|
|
491
494
|
this.emit('connect')
|
|
492
495
|
}
|
|
493
|
-
if (pending === 0) {
|
|
494
|
-
announce()
|
|
495
|
-
return
|
|
496
|
-
}
|
|
497
496
|
for (const topic of batches) {
|
|
498
497
|
this._mqttSubscribe(topic, undefined, () => {
|
|
499
498
|
pending -= 1
|
|
@@ -566,7 +565,38 @@ class VrpcAgent extends EventEmitter {
|
|
|
566
565
|
return topics
|
|
567
566
|
}
|
|
568
567
|
|
|
569
|
-
|
|
568
|
+
/**
|
|
569
|
+
* A class info under this agent's own name. What the broker retained of
|
|
570
|
+
* a class this agent does not offer is a ghost of an earlier run - a
|
|
571
|
+
* class info only `end({ unregister: true })` would have cleared - and
|
|
572
|
+
* clients would list the class forever: it is cleared, in full and
|
|
573
|
+
* concise. Everything else on the topic - the agent's own announcements
|
|
574
|
+
* and clears, routed back live - passes without a word.
|
|
575
|
+
*
|
|
576
|
+
* @returns {Boolean} whether the message was a class info
|
|
577
|
+
* @private
|
|
578
|
+
*/
|
|
579
|
+
_sweepClassInfo (topic, data, packet) {
|
|
580
|
+
const prefix = `${this._baseTopic}/`
|
|
581
|
+
if (!topic.startsWith(prefix)) return false
|
|
582
|
+
const tokens = topic.slice(prefix.length).split('/')
|
|
583
|
+
if (tokens.length !== 2) return false
|
|
584
|
+
const [className, info] = tokens
|
|
585
|
+
if (info !== '__classInfoConcise__' && info !== '__classInfo__') {
|
|
586
|
+
return false
|
|
587
|
+
}
|
|
588
|
+
const retained = !!packet && packet.retain
|
|
589
|
+
if (!retained || data.length === 0) return true
|
|
590
|
+
if (this._getClasses().includes(className)) return true
|
|
591
|
+
this._log.info(`Clearing the class info of ${className}, no longer offered`)
|
|
592
|
+
for (const name of ['__classInfo__', '__classInfoConcise__']) {
|
|
593
|
+
this._mqttPublish(`${prefix}${className}/${name}`, null, { retain: true })
|
|
594
|
+
}
|
|
595
|
+
return true
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
_handleMessage (topic, data, packet) {
|
|
599
|
+
if (this._sweepClassInfo(topic, data, packet)) return
|
|
570
600
|
let json
|
|
571
601
|
try {
|
|
572
602
|
json = JSON.parse(data.toString())
|