vrpc 3.0.0-alpha.2 → 3.0.0-alpha.3

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.2",
3
+ "version": "3.0.0-alpha.3",
4
4
  "description": "Variadic Remote Procedure Calls",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -44,6 +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
48
 
48
49
  /**
49
50
  * Generates an adapter layer for existing code and enables further VRPC-based
@@ -479,6 +480,11 @@ class VrpcAdapter {
479
480
  isIsolated: false
480
481
  })
481
482
  json.r = instanceId
483
+ VrpcAdapter._emitter.emit('create', {
484
+ args,
485
+ className,
486
+ instance: instanceId
487
+ })
482
488
  } catch (err) {
483
489
  json.e = err.message
484
490
  }
@@ -487,14 +493,19 @@ class VrpcAdapter {
487
493
  static _handleCallAll (json) {
488
494
  try {
489
495
  const calls = []
490
- for (const [id, { className, instance }] of VrpcAdapter._instances) {
491
- if (className !== json.c) continue
496
+ for (const [
497
+ id,
498
+ { className, instance, isIsolated }
499
+ ] of VrpcAdapter._instances) {
500
+ // TODO Think about a configurable behavior w.r.t. isolated instances...
501
+ if (className !== json.c || isIsolated) continue
492
502
  let v
493
503
  let e = null
494
504
  try {
495
505
  const wrappedArgs = VrpcAdapter._wrapArguments(json, id)
496
506
  const funcName = wrappedArgs[0]
497
507
  v = instance[funcName].apply(instance, wrappedArgs.slice(1))
508
+ v = VrpcAdapter.sanitizeEventListenerReturnValues(v)
498
509
  } catch (err) {
499
510
  e = err.message
500
511
  }
@@ -514,6 +525,14 @@ class VrpcAdapter {
514
525
  }
515
526
  }
516
527
 
528
+ static sanitizeEventListenerReturnValues (ret) {
529
+ return typeof ret === 'object' &&
530
+ ret._events !== undefined &&
531
+ ret._eventsCount !== undefined
532
+ ? true
533
+ : ret
534
+ }
535
+
517
536
  static _handleDelete (json) {
518
537
  try {
519
538
  const wrappedArgs = VrpcAdapter._wrapArguments(json)
@@ -559,7 +578,8 @@ class VrpcAdapter {
559
578
  const { instance } = entry
560
579
  if (VrpcAdapter._isFunction(instance[json.f])) {
561
580
  try {
562
- const ret = instance[json.f].apply(instance, wrappedArgs)
581
+ let ret = instance[json.f].apply(instance, wrappedArgs)
582
+ ret = VrpcAdapter.sanitizeEventListenerReturnValues(ret)
563
583
  // check if function returns promise
564
584
  if (VrpcAdapter._isPromise(ret)) {
565
585
  this._handlePromise(json, ret)
@@ -336,37 +336,15 @@ class VrpcClient extends EventEmitter {
336
336
  *
337
337
  * @param {String} instance The instance to be retrieved
338
338
  * @param {Object} [options] Explicitly define agent and class
339
- * @param {String} options.className Name of the instance's class
340
- * @param {String} options.agent Agent name. If not provided class default is used
341
- * @param {bool} options.noWait If true immediately fail if instance could not be found in local cache
339
+ * @param {String} [options.className] Name of the instance's class
340
+ * @param {String} [options.agent] Agent name. If not provided class default is used as priority hit
341
+ * @param {bool} [options.noWait=false] If true immediately fail if instance could not be found in local cache
342
342
  * @returns {Promise<Proxy>} Proxy object reflecting the remotely existing instance
343
343
  */
344
- async getInstance (instance, options) {
344
+ async getInstance (instance, options = {}) {
345
345
  if (this._proxies[instance]) return this._proxies[instance]
346
- if (typeof instance === 'string') {
347
- const {
348
- agent,
349
- className,
350
- instance: instanceString
351
- } = await this._getInstanceData(instance, options)
352
- return this._createProxy(agent, className, instanceString)
353
- } else {
354
- // deprecate this
355
- this._indicateDeprecation(
356
- 'VrpcClient.getInstance(): ' +
357
- 'Using an object as single argument is deprecated, ' +
358
- 'use "getInstance(instance, options)" instead.'
359
- )
360
- const fakedOptions = { ...instance }
361
- const fakedInstance = fakedOptions.instance
362
- delete fakedOptions.instance
363
- const {
364
- agent,
365
- className,
366
- instance: instanceString
367
- } = await this._getInstanceData(fakedInstance, fakedOptions)
368
- return this._createProxy(agent, className, instanceString)
369
- }
346
+ const { agent, className } = await this._getInstanceData(instance, options)
347
+ return this._createProxy(agent, className, instance)
370
348
  }
371
349
 
372
350
  /**
@@ -378,30 +356,17 @@ class VrpcClient extends EventEmitter {
378
356
  * @param {String} instance The instance to be deleted
379
357
  * @param {Object} [options] Explicitly define agent and class
380
358
  * @param {String} options.className Name of the instance's class
381
- * @param {String} options.agent Agent name. If not provided class default is used
359
+ * @param {String} options.agent Agent name. If not provided class default is used as priority hit
382
360
  * @returns {Promise<Boolean>} true if successful, false otherwise
383
361
  */
384
- async delete (instance, options) {
385
- let instanceData = { agent: this._agent }
386
- if (typeof instance === 'string') {
387
- instanceData = await this._getInstanceData(instance)
388
- if (options) instanceData = { ...options, ...instanceData }
389
- } else {
390
- // deprecate this
391
- this._indicateDeprecation(
392
- 'VrpcClient.delete(): ' +
393
- 'Using an object as single argument is deprecated, ' +
394
- 'use "delete(instance, options)" instead.'
395
- )
396
- instanceData = { ...instanceData, ...instance }
397
- }
398
- const { agent, className, instance: instanceString } = instanceData
362
+ async delete (instance, options = {}) {
363
+ const { agent, className } = await this._getInstanceData(instance, options)
399
364
  const json = {
400
365
  c: className,
401
366
  f: '__delete__',
402
367
  i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
403
368
  s: `${this._domain}/${os.hostname()}/${this._instance}`,
404
- a: [instanceString],
369
+ a: [instance],
405
370
  v: VRPC_PROTOCOL_VERSION
406
371
  }
407
372
  const topic = `${this._domain}/${agent}/${className}/__static__/__delete__`
@@ -535,19 +500,7 @@ class VrpcClient extends EventEmitter {
535
500
  * @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online agents
536
501
  * @returns {Array} Array of agent names.
537
502
  */
538
- getAvailableAgents (options = {}) {
539
- /// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
540
- // `options = {}` was `domain = this._domain` before
541
- if (typeof options === 'string') {
542
- this._indicateDeprecation(
543
- 'VrpcClient.getAvailableAgents(): ' +
544
- 'Providing a domain here has no effect and will be an error in future.'
545
- )
546
- options = { mustBeOnline: true }
547
- }
548
- ///
549
-
550
- const { mustBeOnline = true } = options
503
+ getAvailableAgents ({ mustBeOnline = true } = {}) {
551
504
  const agents = []
552
505
  if (mustBeOnline) {
553
506
  // loop agents
@@ -568,34 +521,7 @@ class VrpcClient extends EventEmitter {
568
521
  * @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online classes
569
522
  * @returns {Array} Array of class names.
570
523
  */
571
- getAvailableClasses (
572
- options = { agent: this._agent, mustBeOnline: true },
573
- domain
574
- ) {
575
- /// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
576
- let agent = this._agent
577
- let mustBeOnline = true
578
- // `options = {}` was `agent = this._agent` before
579
- if (typeof options === 'string') {
580
- this._indicateDeprecation(
581
- 'VrpcClient.getAvailableClasses(): ' +
582
- 'setting the agent as string argument is deprecated.`' +
583
- 'Use `{ agent: <myAgent> }` instead.'
584
- )
585
- agent = options
586
- } else {
587
- agent = options.agent
588
- mustBeOnline = options.mustBeOnline
589
- }
590
- // was `domain = this._domain` before
591
- if (domain) {
592
- this._indicateDeprecation(
593
- 'VrpcClient.getAvailableClasses(): ' +
594
- 'Providing a domain here has no effect and will be an error in future.'
595
- )
596
- }
597
- ///
598
-
524
+ getAvailableClasses ({ agent = this._agent, mustBeOnline = true } = {}) {
599
525
  if (agent === '*') throw new Error('Agent must be specified')
600
526
  if (!this._agents[agent]) return []
601
527
  const { classes, status } = this._agents[agent]
@@ -606,41 +532,17 @@ class VrpcClient extends EventEmitter {
606
532
  /**
607
533
  * Retrieves all (named) instances on specific class and agent.
608
534
  *
609
- * @param {String} className Class name
610
535
  * @param {Object} [options]
536
+ * @param {String} options.className Class name
611
537
  * @param {String} [options.agent] Agent name. If not provided class default is used
612
538
  * @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online classes
613
539
  * @returns {Array} Array of instance names
614
540
  */
615
- getAvailableInstances (
541
+ getAvailableInstances ({
616
542
  className,
617
- options = { agent: this._agent, mustBeOnline: true },
618
- domain
619
- ) {
620
- /// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
621
- let agent = this._agent
622
- let mustBeOnline = true
623
- // `options = {}` was `agent = this._agent` before
624
- if (typeof options === 'string') {
625
- this._indicateDeprecation(
626
- 'VrpcClient.getAvailableInstances(): ' +
627
- 'Setting the agent as string argument is deprecated.`' +
628
- 'Use `{ agent: <myAgent> }` instead.'
629
- )
630
- agent = options
631
- } else {
632
- agent = options.agent
633
- mustBeOnline = options.mustBeOnline
634
- }
635
- // was `domain = this._domain` before
636
- if (domain) {
637
- this._indicateDeprecation(
638
- 'VrpcClient.getAvailableInstances(): ' +
639
- 'Providing a domain here has no effect and will be an error in future.'
640
- )
641
- }
642
- ///
643
-
543
+ agent = this._agent,
544
+ mustBeOnline = true
545
+ } = {}) {
644
546
  if (agent === '*') throw new Error('Agent must be specified')
645
547
  if (!this._agents[agent]) return []
646
548
  const { classes, status } = this._agents[agent]
@@ -651,41 +553,17 @@ class VrpcClient extends EventEmitter {
651
553
  /**
652
554
  * Retrieves all member functions of specific class and agent.
653
555
  *
654
- * @param {String} className Class name
655
556
  * @param {Object} [options]
557
+ * @param {String} options.className Class name
656
558
  * @param {String} [options.agent] Agent name. If not provided class default is used
657
559
  * @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online classes
658
560
  * @returns {Array} Array of member function names
659
561
  */
660
- getAvailableMemberFunctions (
562
+ getAvailableMemberFunctions ({
661
563
  className,
662
- options = { agent: this._agent, mustBeOnline: true },
663
- domain
664
- ) {
665
- /// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
666
- let agent = this._agent
667
- let mustBeOnline = true
668
- // `options = {}` was `agent = this._agent` before
669
- if (typeof options === 'string') {
670
- this._indicateDeprecation(
671
- 'VrpcClient.getAvailableMemberFunctions(): ' +
672
- 'Setting the agent as string argument is deprecated.`' +
673
- 'Use `{ agent: <myAgent> }` instead.'
674
- )
675
- agent = options
676
- } else {
677
- agent = options.agent
678
- mustBeOnline = options.mustBeOnline
679
- }
680
- // was `domain = this._domain` before
681
- if (domain) {
682
- this._indicateDeprecation(
683
- 'VrpcClient.getAvailableMemberFunctions(): ' +
684
- 'Providing a domain here has no effect and will be an error in future.'
685
- )
686
- }
687
- ///
688
-
564
+ agent = this._agent,
565
+ mustBeOnline = true
566
+ } = {}) {
689
567
  if (agent === '*') throw new Error('Agent must be specified')
690
568
  if (!this._agents[agent]) return []
691
569
  const { classes, status } = this._agents[agent]
@@ -698,41 +576,17 @@ class VrpcClient extends EventEmitter {
698
576
  /**
699
577
  * Retrieves all static functions of specific class and agent.
700
578
  *
701
- * @param {String} className Class name
702
579
  * @param {Object} [options]
580
+ * @param {String} options.className Class name
703
581
  * @param {String} [options.agent] Agent name. If not provided class default is used
704
582
  * @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online classes
705
583
  * @returns {Array} Array of static function names
706
584
  */
707
- getAvailableStaticFunctions (
585
+ getAvailableStaticFunctions ({
708
586
  className,
709
- options = { agent: this._agent, mustBeOnline: true },
710
- domain
711
- ) {
712
- /// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
713
- let agent = this._agent
714
- let mustBeOnline = true
715
- // `options = {}` was `agent = this._agent` before
716
- if (typeof options === 'string') {
717
- this._indicateDeprecation(
718
- 'VrpcClient.getAvailableStaticFunctions(): ' +
719
- 'Setting the agent as string argument is deprecated.`' +
720
- 'Use `{ agent: <myAgent> }` instead.'
721
- )
722
- agent = options
723
- } else {
724
- agent = options.agent
725
- mustBeOnline = options.mustBeOnline
726
- }
727
- // was `domain = this._domain` before
728
- if (domain) {
729
- this._indicateDeprecation(
730
- 'VrpcClient.getAvailableStaticFunctions(): ' +
731
- 'Providing a domain here has no effect and will be an error in future.'
732
- )
733
- }
734
- ///
735
-
587
+ agent = this._agent,
588
+ mustBeOnline = true
589
+ } = {}) {
736
590
  if (agent === '*') throw new Error('Agent must be specified')
737
591
  if (!this._agents[agent]) return []
738
592
  const { classes, status } = this._agents[agent]
@@ -947,7 +801,8 @@ class VrpcClient extends EventEmitter {
947
801
  const json = {
948
802
  c: instance,
949
803
  f: name,
950
- i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
804
+ i: `${this._instance}-${this._invokeId++ %
805
+ Number.MAX_SAFE_INTEGER}`,
951
806
  s: this._vrpcClientId,
952
807
  a: wrapped,
953
808
  v: VRPC_PROTOCOL_VERSION
@@ -1111,7 +966,7 @@ class VrpcClient extends EventEmitter {
1111
966
  )
1112
967
  }
1113
968
 
1114
- async _getInstanceData (instance, options = {}) {
969
+ async _getInstanceData (instance, options) {
1115
970
  const instanceData = this._getInstanceFromCache(instance, options)
1116
971
  if (!instanceData) {
1117
972
  if (options.noWait) {
@@ -1123,6 +978,21 @@ class VrpcClient extends EventEmitter {
1123
978
  }
1124
979
 
1125
980
  _getInstanceFromCache (instance, options = {}) {
981
+ // when no agent is specified, but an explicit class default exists give
982
+ // such instances priority in being found
983
+ if (!options.agent && this._agent !== '*') {
984
+ const { classes, status } = this._agents[this._agent]
985
+ if (!classes || status === 'offline') {
986
+ for (const className in classes) {
987
+ if (options.className && className !== options.className) continue
988
+ const { instances } = classes[className]
989
+ if (!instances) continue
990
+ if (instances.includes(instance)) {
991
+ return { agent, className, instance }
992
+ }
993
+ }
994
+ }
995
+ }
1126
996
  // loop agents
1127
997
  for (const agent in this._agents) {
1128
998
  if (options.agent && agent !== options.agent) continue