vrpc 3.0.0-alpha.3 → 3.0.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": "vrpc",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0",
4
4
  "description": "Variadic Remote Procedure Calls",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -12,10 +12,11 @@
12
12
  "build:addon": "ln -sf binding.gyp.no-auto binding.gyp && node-gyp rebuild && rm binding.gyp",
13
13
  "build:browser": "./node_modules/.bin/webpack",
14
14
  "build:doc": "./node_modules/.bin/jsdoc2md -f vrpc/*.js --param-list-format=list --separators > docs/api.md",
15
- "test": "npm run test:agent && npm run test:client && npm run test:native",
15
+ "test": "npm run test:adapter && npm run test:native && npm run test:agent && npm run test:client && npm run test:production",
16
+ "test:adapter": "./node_modules/.bin/mocha tests/adapter/*.js --exit",
17
+ "test:native": "./node_modules/.bin/mocha tests/native/*.js --exit",
16
18
  "test:agent": "tests/agent/test.sh",
17
19
  "test:client": "tests/client/test.sh",
18
- "test:native": "./node_modules/.bin/mocha tests/native/vrpc-native*.js --exit",
19
20
  "test:performance": "tests/performance/test.sh",
20
21
  "test:production": "./node_modules/.bin/mocha tests/production/lifeCycleTest.js --timeout 30000 --exit && tests/production/test.sh"
21
22
  },
@@ -49,7 +50,7 @@
49
50
  "crypto-browserify": "^3.12.0",
50
51
  "dockerode": "^3.2.0",
51
52
  "jsdoc-to-markdown": "^7.0.1",
52
- "mocha": "^6.1.4",
53
+ "mocha": "^9.1.3",
53
54
  "os-browserify": "^0.3.0",
54
55
  "sinon": "^7.3.2",
55
56
  "stream-browserify": "^3.0.0",
@@ -66,8 +67,10 @@
66
67
  "dependencies": {
67
68
  "ajv": "^6.10.0",
68
69
  "argparse": "^2.0.1",
70
+ "buffer": "^6.0.3",
69
71
  "caller": "^1.0.1",
70
72
  "mqtt": "^4.2.6",
71
- "nanoid": "^3.1.23"
73
+ "nanoid": "^3.1.23",
74
+ "process": "^0.11.10"
72
75
  }
73
76
  }
@@ -16,7 +16,7 @@ Author: Dr. Burkhard C. Heisen (https://github.com/heisenware/vrpc)
16
16
 
17
17
 
18
18
  Licensed under the MIT License <http://opensource.org/licenses/MIT>.
19
- Copyright (c) 2018 - 2021 Dr. Burkhard C. Heisen <burkhard.heisen@heisenware.com>.
19
+ Copyright (c) 2018 - 2022 Dr. Burkhard C. Heisen <burkhard.heisen@heisenware.com>.
20
20
 
21
21
  Permission is hereby granted, free of charge, to any person obtaining a copy
22
22
  of this software and associated documentation files (the "Software"), to deal
@@ -44,7 +44,7 @@ const Ajv = require('ajv')
44
44
  const caller = require('caller')
45
45
  const commentParser = require('./comment-parser')
46
46
  const EventEmitter = require('events')
47
- const { type } = require('os')
47
+ const { nanoid } = require('nanoid')
48
48
 
49
49
  /**
50
50
  * Generates an adapter layer for existing code and enables further VRPC-based
@@ -101,17 +101,20 @@ class VrpcAdapter {
101
101
  * NOTE: This function currently only supports registration of classes (either
102
102
  * when provided as object or when exported on the provided module path)
103
103
  */
104
- static register (code, options = {}) {
104
+ static register (code, options = {}) {
105
105
  if (typeof code === 'string') {
106
106
  const absPath = path.resolve(caller(), '../', code)
107
107
  const relPath = path.relative(__dirname, absPath)
108
- const absJsdocPath = `${absPath}.js`
108
+ const absJsdocPath =
109
+ absPath && absPath.endsWith('.js') ? absPath : `${absPath}.js`
109
110
  const Klass = require(relPath)
110
111
  this._registerClass(Klass, absJsdocPath, options)
111
112
  } else {
112
113
  const { jsdocPath } = options
114
+ const sJsdocPath =
115
+ jsdocPath && jsdocPath.endsWith('.js') ? jsdocPath : `${jsdocPath}.js`
113
116
  if (jsdocPath) {
114
- const absJsdocPath = path.resolve(caller(), '../', `${jsdocPath}.js`)
117
+ const absJsdocPath = path.resolve(caller(), '../', sJsdocPath)
115
118
  this._registerClass(code, absJsdocPath, { ...options, jsdoc: true })
116
119
  } else {
117
120
  this._registerClass(code, null, options)
@@ -147,14 +150,16 @@ class VrpcAdapter {
147
150
  const content = fs.readFileSync(absJsdocPath).toString('utf8')
148
151
  meta = this._parseComments(content)
149
152
  }
150
- VrpcAdapter._functionRegistry.set(className, {
151
- memberFunctions,
152
- meta,
153
- Klass: {},
154
- withNew: false,
155
- staticFunctions: [],
156
- schema: null
157
- })
153
+ if (!VrpcAdapter._functionRegistry.has(className)) {
154
+ VrpcAdapter._functionRegistry.set(className, {
155
+ memberFunctions,
156
+ meta,
157
+ Klass: {},
158
+ withNew: false,
159
+ staticFunctions: [],
160
+ schema: null
161
+ })
162
+ }
158
163
  VrpcAdapter._instances.set(instance, {
159
164
  className,
160
165
  instance: obj,
@@ -162,81 +167,56 @@ class VrpcAdapter {
162
167
  })
163
168
  }
164
169
 
165
- static getClasses () {
166
- return JSON.stringify(VrpcAdapter._getClassesArray())
167
- }
168
-
169
- static getMemberFunctions (className) {
170
- return JSON.stringify(VrpcAdapter._getMemberFunctionsArray(className))
171
- }
172
-
173
- static getStaticFunctions (className) {
174
- return JSON.stringify(VrpcAdapter._getStaticFunctionsArray(className))
175
- }
176
-
177
- static getMetaData (className) {
178
- return JSON.stringify(VrpcAdapter._getMetaData(className))
179
- }
180
-
181
- static getInstances (className) {
182
- return JSON.stringify(VrpcAdapter._getInstancesArray(className))
183
- }
184
-
185
- static call (jsonString) {
186
- const json = JSON.parse(jsonString)
187
- VrpcAdapter._call(json)
188
- return JSON.stringify(json)
189
- }
190
-
191
- static onCallback (callback) {
192
- VrpcAdapter._callback = callback
193
- }
194
-
195
- // convenience interface if used in parallel - as local factory and from remote
170
+ /*****************************************************
171
+ * convenience interface if used as plug-able factory *
172
+ ******************************************************/
196
173
 
197
174
  /**
198
- * Creates an un-managed, anonymous instance
175
+ * Creates a new instance
199
176
  *
200
- * @param {String} className Name of the class to create an instance of
201
- * @param {...any} args Arguments to provide to the constructor
202
- * @returns {Object} The real instance (not a proxy!)
203
- */
204
- static create (className, ...args) {
205
- if (typeof className === 'string') {
206
- return VrpcAdapter._create(className, ...args)
207
- }
208
- if (typeof className === 'object') {
209
- if (className.instance) {
210
- return VrpcAdapter._createNamed(
211
- className.className,
212
- className.instance,
213
- ...className.args
214
- )
215
- }
216
- return VrpcAdapter._create(className.className, ...className.args)
217
- }
218
- }
219
-
220
- /**
221
- * Creates a managed named instance
222
- *
223
- * @param {String} className Name of the class to create an instance of
224
- * @param {String} instance Name of the instance
225
- * @param {...any} args Arguments to provide to the constructor
177
+ * @param {Object} options
178
+ * @param {String} options.className Name of the class which should be
179
+ * instantiated
180
+ * @param {String} [options.instance] Name of the created instance. If not
181
+ * provided an id will be generated
182
+ * @param {Array} [options.args] Positional arguments for the constructor call
183
+ * @param {bool} [options.isIsolated=false] If true the created instance will
184
+ * be visible only to the client who created it
226
185
  * @returns {Object} The real instance (not a proxy!)
227
186
  */
228
- static createNamed (className, instance, ...args) {
229
- return VrpcAdapter._createNamed(className, instance, ...args)
187
+ static create ({
188
+ className,
189
+ instance = nanoid(8),
190
+ args = [],
191
+ isIsolated = false
192
+ } = {}) {
193
+ const json = { c: className, a: [instance, ...args] }
194
+ const obj = isIsolated
195
+ ? VrpcAdapter._handleCreateIsolated(json)
196
+ : VrpcAdapter._handleCreateShared(json)
197
+ if (json.e) throw new Error(json.e)
198
+ return obj
230
199
  }
231
200
 
232
201
  /**
233
- * Deletes a managed instance
202
+ * Deletes an instance
234
203
  *
235
- * @param {String} instance Name of the instance to be deleted
204
+ * @param {String|Object} instance Instance (name or object itself) to be deleted
236
205
  * @returns {Boolean} True in case of success, false otherwise
237
206
  */
238
207
  static delete (instance) {
239
- return VrpcAdapter._delete(instance)
208
+ if (typeof instance === 'string') {
209
+ return VrpcAdapter._delete(instance)
210
+ }
211
+ if (typeof instance === 'object') {
212
+ for (const [k, v] of VrpcAdapter._instances) {
213
+ if (v.instance === instance) {
214
+ VrpcAdapter._instances.delete(k)
215
+ return true
216
+ }
217
+ }
218
+ return false
219
+ }
240
220
  }
241
221
 
242
222
  /**
@@ -270,34 +250,14 @@ class VrpcAdapter {
270
250
  return VrpcAdapter._getInstancesArray(className)
271
251
  }
272
252
 
273
- /**
274
- * Provides all available member functions of the specified class.
275
- *
276
- * @param {String} className Name of class to provide member functions for
277
- * @return {Array.<String>} Array of member function names
278
- */
279
- static getAvailableMemberFunctions (className) {
280
- return VrpcAdapter._getMemberFunctionsArray(className)
281
- }
282
-
283
- /**
284
- * Provides all available static functions of a registered class.
285
- *
286
- * @param {String} className Name of class to provide static functions for
287
- * @returns {Array.<String>} Array of static function names
288
- */
289
- static getAvailableStaticFunctions (className) {
290
- return VrpcAdapter._getStaticFunctionsArray(className)
253
+ static call (jsonString) {
254
+ const json = JSON.parse(jsonString)
255
+ VrpcAdapter._call(json)
256
+ return JSON.stringify(json)
291
257
  }
292
258
 
293
- /**
294
- * Provides all available meta data of the registered class.
295
- *
296
- * @param {String} className Name of class to provide meta data for
297
- * @returns {MetaData} Meta Data
298
- */
299
- static getAvailableMetaData (className) {
300
- return VrpcAdapter._getMetaData(className)
259
+ static onCallback (callback) {
260
+ VrpcAdapter._callback = callback
301
261
  }
302
262
 
303
263
  /**
@@ -445,6 +405,7 @@ class VrpcAdapter {
445
405
  VrpcAdapter._handleDelete(json)
446
406
  break
447
407
  default:
408
+ // this call may have the side-effect of taking a listener on board
448
409
  VrpcAdapter._handleCall(json)
449
410
  }
450
411
  const after = Object.keys(VrpcAdapter._listeners).length
@@ -454,26 +415,35 @@ class VrpcAdapter {
454
415
  }
455
416
 
456
417
  static _handleCreateIsolated (json) {
418
+ let instance
457
419
  try {
458
420
  const className = json.c
459
421
  const [instanceId, ...args] = json.a
460
- const instance = VrpcAdapter._create(className, instanceId, ...args)
422
+ instance = VrpcAdapter._create(className, instanceId, ...args)
461
423
  VrpcAdapter._instances.set(instanceId, {
462
424
  instance,
463
425
  className,
464
426
  isIsolated: true
465
427
  })
428
+ VrpcAdapter._emitter.emit('create', {
429
+ args,
430
+ className,
431
+ isIsolated: true,
432
+ instance: instanceId
433
+ })
466
434
  json.r = instanceId
467
435
  } catch (err) {
468
436
  json.e = err.message
469
437
  }
438
+ return instance
470
439
  }
471
440
 
472
441
  static _handleCreateShared (json) {
442
+ let instance
473
443
  try {
474
444
  const className = json.c
475
445
  const [instanceId, ...args] = json.a
476
- const instance = VrpcAdapter._create(className, instanceId, ...args)
446
+ instance = VrpcAdapter._create(className, instanceId, ...args)
477
447
  VrpcAdapter._instances.set(instanceId, {
478
448
  instance,
479
449
  className,
@@ -483,11 +453,13 @@ class VrpcAdapter {
483
453
  VrpcAdapter._emitter.emit('create', {
484
454
  args,
485
455
  className,
456
+ isIsolated: false,
486
457
  instance: instanceId
487
458
  })
488
459
  } catch (err) {
489
460
  json.e = err.message
490
461
  }
462
+ return instance
491
463
  }
492
464
 
493
465
  static _handleCallAll (json) {
@@ -499,13 +471,15 @@ class VrpcAdapter {
499
471
  ] of VrpcAdapter._instances) {
500
472
  // TODO Think about a configurable behavior w.r.t. isolated instances...
501
473
  if (className !== json.c || isIsolated) continue
502
- let v
474
+ let v = true
503
475
  let e = null
504
476
  try {
505
- const wrappedArgs = VrpcAdapter._wrapArguments(json, id)
506
- const funcName = wrappedArgs[0]
507
- v = instance[funcName].apply(instance, wrappedArgs.slice(1))
508
- v = VrpcAdapter.sanitizeEventListenerReturnValues(v)
477
+ const unwrapped = VrpcAdapter._unwrapArguments(json, id)
478
+ if (unwrapped) {
479
+ const funcName = unwrapped[0]
480
+ v = instance[funcName].apply(instance, unwrapped.slice(1))
481
+ v = VrpcAdapter.sanitizeEventListenerReturnValues(v)
482
+ }
509
483
  } catch (err) {
510
484
  e = err.message
511
485
  }
@@ -535,12 +509,11 @@ class VrpcAdapter {
535
509
 
536
510
  static _handleDelete (json) {
537
511
  try {
538
- const wrappedArgs = VrpcAdapter._wrapArguments(json)
539
- const instanceId = wrappedArgs[0]
540
- json.r = VrpcAdapter._delete(instanceId)
512
+ const instance = json.a[0] // first arg is instance to be deleted
513
+ json.r = VrpcAdapter._delete(instance)
541
514
  VrpcAdapter._emitter.emit('delete', {
542
- className: json.c,
543
- instance: wrappedArgs[0]
515
+ instance,
516
+ className: json.c
544
517
  })
545
518
  } catch (err) {
546
519
  json.e = err.message
@@ -548,7 +521,18 @@ class VrpcAdapter {
548
521
  }
549
522
 
550
523
  static _handleCall (json) {
551
- const wrappedArgs = VrpcAdapter._wrapArguments(json)
524
+ // special case: removeAllListeners
525
+ if (json.f === 'removeAllListeners') {
526
+ VrpcAdapter._removeAllListeners(json.a[0], json.s, json.c)
527
+ json.r = true
528
+ return
529
+ }
530
+ const unwrapped = VrpcAdapter._unwrapArguments(json)
531
+ if (!unwrapped) {
532
+ // this call must be skipped (event emitter stuff)
533
+ json.r = true
534
+ return
535
+ }
552
536
  // Check whether context is a registered class
553
537
  const entry = VrpcAdapter._functionRegistry.get(json.c)
554
538
  if (entry !== undefined) {
@@ -560,7 +544,7 @@ class VrpcAdapter {
560
544
  // subscription against all functions
561
545
  if (VrpcAdapter._isFunction(Klass[json.f])) {
562
546
  try {
563
- const ret = Klass[json.f].apply(null, wrappedArgs)
547
+ const ret = Klass[json.f].apply(null, unwrapped)
564
548
  // check if function returns promise
565
549
  if (VrpcAdapter._isPromise(ret)) {
566
550
  this._handlePromise(json, ret)
@@ -578,7 +562,7 @@ class VrpcAdapter {
578
562
  const { instance } = entry
579
563
  if (VrpcAdapter._isFunction(instance[json.f])) {
580
564
  try {
581
- let ret = instance[json.f].apply(instance, wrappedArgs)
565
+ let ret = instance[json.f].apply(instance, unwrapped)
582
566
  ret = VrpcAdapter.sanitizeEventListenerReturnValues(ret)
583
567
  // check if function returns promise
584
568
  if (VrpcAdapter._isPromise(ret)) {
@@ -605,31 +589,35 @@ class VrpcAdapter {
605
589
  static _delete (instanceId) {
606
590
  const entry = VrpcAdapter._instances.get(instanceId)
607
591
  if (entry) {
592
+ // in case the instance was an EventEmitter, free all registered listeners
593
+ if (VrpcAdapter._isFunction(entry.removeAllListeners)) {
594
+ entry.removeAllListeners()
595
+ }
596
+ for (const [key, { clients, instance }] of Object.entries(
597
+ VrpcAdapter._listeners
598
+ )) {
599
+ if (instance === instanceId) {
600
+ VrpcAdapter._listeners[key] = { clients }
601
+ }
602
+ }
608
603
  VrpcAdapter._instances.delete(instanceId)
609
604
  return true
610
605
  }
611
606
  return false
612
607
  }
613
608
 
614
- static _unregisterEventListeners (clientId) {
615
- const listeners = VrpcAdapter._listeners[clientId]
616
- if (listeners) {
617
- listeners.forEach(({ i, e, f }) => {
618
- VrpcAdapter.getInstance(i).removeListener(e, f)
619
- })
620
- }
621
- delete VrpcAdapter._listeners[clientId]
622
- }
623
-
624
- static _unregisterEventListenersOfInstance (instance) {
609
+ static _unregisterClient (clientId) {
625
610
  for (const [key, value] of Object.entries(VrpcAdapter._listeners)) {
626
- VrpcAdapter._listeners[key] = value.filter(({ i, e, f }) => {
627
- if (instance === i) {
628
- VrpcAdapter.getInstance(i).removeListener(e, f)
629
- return false
611
+ const { instance, event, listener, clients } = value
612
+ const filteredClients = clients.filter(x => x !== clientId)
613
+ if (filteredClients.length === 0) {
614
+ if (event) {
615
+ VrpcAdapter.getInstance(instance).removeListener(event, listener)
630
616
  }
631
- return true
632
- })
617
+ delete VrpcAdapter._listeners[key]
618
+ } else {
619
+ VrpcAdapter._listeners[key].clients = filteredClients
620
+ }
633
621
  }
634
622
  }
635
623
 
@@ -641,51 +629,86 @@ class VrpcAdapter {
641
629
  if (!valid) throw new Error(VrpcAdapter._ajv.errorsText())
642
630
  }
643
631
 
644
- static _wrapArguments (json, instanceId) {
632
+ static _unwrapArguments (json, instanceId) {
645
633
  const { f: func, s: sender, a: args, c: context } = json
646
- const wrapped = []
647
- args.forEach(arg => {
648
- // Find those args that actually need to be function callbacks
649
- if (typeof arg === 'string' && arg.substr(0, 5) === '__f__') {
650
- const f = this._generateWrapper(arg, json, instanceId)
651
- wrapped.push(f)
652
- if (!sender) return
653
- // Register this client to later know when he is dead and skip callbacks
654
- if (!VrpcAdapter._listeners[sender]) VrpcAdapter._listeners[sender] = []
655
- // Check whether injected callback is an EventEmitter registration
656
- if (func === 'on' && typeof args[0] === 'string') {
657
- const e = args[0]
658
- const i = context
659
- const r = arg
660
- VrpcAdapter._listeners[sender].push({ i, e, f, r })
634
+ const unwrapped = []
635
+ for (const arg of args) {
636
+ // find those args that actually need to be functions
637
+ if (typeof arg === 'string' && arg.slice(0, 5) === '__f__') {
638
+ const callback = this._generateCallback(arg, json, instanceId)
639
+ unwrapped.push(callback)
640
+ } else if (typeof arg === 'string' && arg.slice(0, 5) === '__e__') {
641
+ const listener = this._generateListener(arg, json, instanceId)
642
+ unwrapped.push(listener)
643
+ // start tracking clients that are registering event listeners
644
+ if (!VrpcAdapter._listeners[arg]) {
645
+ VrpcAdapter._listeners[arg] = {
646
+ listener,
647
+ clients: [sender],
648
+ instance: context,
649
+ event: null
650
+ }
651
+ } else {
652
+ VrpcAdapter._listeners[arg].clients.push(sender)
653
+ }
654
+ // see whether the requested listener is an EventEmitter registration
655
+ if (func === 'on' || func === 'addListener') {
656
+ // if this event is already registered avoid a second registration
657
+ if (VrpcAdapter._listeners[arg].event) {
658
+ return null // means that this call won't be forwarded
659
+ }
660
+ VrpcAdapter._listeners[arg].event = args[0]
661
661
  }
662
- if (
663
- (func === 'off' || func === 'removeListener') &&
664
- typeof args[0] === 'string'
665
- ) {
666
- const listener = VrpcAdapter._listeners[sender]
667
- const entry = listener && listener.find(x => x.r === arg)
668
- if (entry) {
669
- const { i, e, f } = entry
670
- VrpcAdapter.getInstance(i).removeListener(e, f)
662
+ if (func === 'off' || func === 'removeListener') {
663
+ const { clients, listener, event } = VrpcAdapter._listeners[arg]
664
+ const filteredClients = clients.filter(x => x !== sender)
665
+ // don't unregister this event, as other clients are still listening
666
+ if (filteredClients.length > 0) {
667
+ VrpcAdapter._listeners[arg].clients = filteredClients
668
+ } else {
669
+ delete VrpcAdapter._listeners[arg]
670
+ VrpcAdapter.getInstance(context).off(event, listener)
671
671
  }
672
+ return null // means that this call won't be forwarded
672
673
  }
673
674
  } else {
674
- // Leave the others untouched
675
- wrapped.push(arg)
675
+ // default behavior is to not touch
676
+ unwrapped.push(arg)
676
677
  }
677
- })
678
- return wrapped
678
+ }
679
+ return unwrapped
680
+ }
681
+
682
+ static _removeAllListeners (event, sender, context) {
683
+ for (const [key, value] of Object.entries(VrpcAdapter._listeners)) {
684
+ if (value.event === event) {
685
+ const filteredClients = value.clients.filter(x => x !== sender)
686
+ if (filteredClients.length > 0) {
687
+ VrpcAdapter._listeners[key].clients = filteredClients
688
+ } else {
689
+ delete VrpcAdapter._listeners[key]
690
+ VrpcAdapter.getInstance(context).off(event, value.listener)
691
+ }
692
+ }
693
+ }
694
+ }
695
+
696
+ static _generateCallback (id, json, instanceId) {
697
+ return (...innerArgs) => {
698
+ // callAll expects the instanceId as first argument
699
+ const a = instanceId ? [instanceId, ...innerArgs] : [...innerArgs]
700
+ VrpcAdapter._callback({ a, s: json.s, i: id })
701
+ }
679
702
  }
680
703
 
681
- static _generateWrapper (id, json, instanceId) {
682
- const wrapper = (...innerArgs) => {
683
- // do not even trigger a callback for already offline clients
684
- if (json.s && !VrpcAdapter._listeners[json.s]) return
704
+ static _generateListener (id, json, instanceId) {
705
+ return (...innerArgs) => {
706
+ // do not even emit for already offline clients
707
+ if (!VrpcAdapter._listeners[id]) return
708
+ // callAll expects the instanceId as first argument
685
709
  const a = instanceId ? [instanceId, ...innerArgs] : [...innerArgs]
686
- VrpcAdapter._callback({ a, s: json.s, f: json.f, i: id })
710
+ VrpcAdapter._callback({ a, s: json.s, i: id })
687
711
  }
688
- return wrapper
689
712
  }
690
713
 
691
714
  static _handlePromise (json, promise) {
@@ -812,7 +835,7 @@ class VrpcAdapter {
812
835
  /**
813
836
  * Event 'create'
814
837
  *
815
- * Emitted on creation of named instance
838
+ * Emitted on creation of shared instance
816
839
  *
817
840
  * @event VrpcAdapter#create
818
841
  * @type {Object}
@@ -824,7 +847,7 @@ class VrpcAdapter {
824
847
  /**
825
848
  * Event 'delete'
826
849
  *
827
- * Emitted on deletion of named instance
850
+ * Emitted on deletion of shared instance
828
851
  *
829
852
  * @event VrpcAdapter#delete
830
853
  * @type {Object}