vrpc 2.5.1 → 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/CHANGELOG.md +66 -0
- package/README.md +31 -56
- package/binding.gyp.no-auto +4 -26
- package/browser/vrpc.js +1 -1
- package/index.js +2 -2
- package/package.json +12 -16
- package/vrpc/VrpcAdapter.js +202 -193
- package/vrpc/VrpcAgent.js +86 -80
- package/vrpc/{VrpcRemote.js → VrpcClient.js} +302 -425
- package/vrpc/VrpcNative.js +307 -0
- package/vrpc/{vrpc.hpp → adapter.hpp} +1001 -1115
- package/vrpc/addon.cpp +5 -5
- package/vrpc/json.hpp +1769 -870
- package/vrpc/vrpc-agent-js +4 -4
- package/README.rst +0 -18
- package/third_party/include/catch.hpp +0 -12749
- package/third_party/install.sh +0 -22
- package/vrpc/VrpcLocal.js +0 -264
- package/vrpc/VrpcLocal.py +0 -171
- package/vrpc/__init__.py +0 -1
- package/vrpc/module.cpp +0 -183
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
module.exports = {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
VrpcNative: require('./vrpc/VrpcNative'),
|
|
4
|
+
VrpcClient: require('./vrpc/VrpcClient'),
|
|
5
5
|
VrpcAdapter: require('./vrpc/VrpcAdapter'),
|
|
6
6
|
VrpcAgent: require('./vrpc/VrpcAgent')
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vrpc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.3",
|
|
4
4
|
"description": "Variadic Remote Procedure Calls",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
@@ -9,18 +9,15 @@
|
|
|
9
9
|
"test": "test"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "ln -sf binding.gyp.no-auto binding.gyp &&
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"test
|
|
16
|
-
"test:
|
|
17
|
-
"test:
|
|
18
|
-
"test:
|
|
19
|
-
"test:
|
|
20
|
-
"
|
|
21
|
-
"build:jsdoc": "./node_modules/.bin/jsdoc2md -f vrpc/*.js --param-list-format=list --separators > docs/reference/nodeJs.md",
|
|
22
|
-
"build:doc": "npm run build:pydoc; npm run build:jsdoc",
|
|
23
|
-
"build:browser": "./node_modules/.bin/webpack"
|
|
12
|
+
"build:addon": "ln -sf binding.gyp.no-auto binding.gyp && node-gyp rebuild && rm binding.gyp",
|
|
13
|
+
"build:browser": "./node_modules/.bin/webpack",
|
|
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",
|
|
16
|
+
"test:agent": "tests/agent/test.sh",
|
|
17
|
+
"test:client": "tests/client/test.sh",
|
|
18
|
+
"test:native": "./node_modules/.bin/mocha tests/native/vrpc-native*.js --exit",
|
|
19
|
+
"test:performance": "tests/performance/test.sh",
|
|
20
|
+
"test:production": "./node_modules/.bin/mocha tests/production/lifeCycleTest.js --timeout 30000 --exit && tests/production/test.sh"
|
|
24
21
|
},
|
|
25
22
|
"bin": {
|
|
26
23
|
"vrpc-agent-js": "./vrpc/vrpc-agent-js"
|
|
@@ -34,7 +31,7 @@
|
|
|
34
31
|
"remote procedural calls",
|
|
35
32
|
"language binding",
|
|
36
33
|
"C++",
|
|
37
|
-
"C++
|
|
34
|
+
"C++ embedding",
|
|
38
35
|
"header-only"
|
|
39
36
|
],
|
|
40
37
|
"repository": {
|
|
@@ -51,7 +48,7 @@
|
|
|
51
48
|
"chai": "^4.2.0",
|
|
52
49
|
"crypto-browserify": "^3.12.0",
|
|
53
50
|
"dockerode": "^3.2.0",
|
|
54
|
-
"jsdoc-to-markdown": "^
|
|
51
|
+
"jsdoc-to-markdown": "^7.0.1",
|
|
55
52
|
"mocha": "^6.1.4",
|
|
56
53
|
"os-browserify": "^0.3.0",
|
|
57
54
|
"sinon": "^7.3.2",
|
|
@@ -62,7 +59,6 @@
|
|
|
62
59
|
},
|
|
63
60
|
"files": [
|
|
64
61
|
"vrpc/",
|
|
65
|
-
"third_party/",
|
|
66
62
|
"browser/",
|
|
67
63
|
"binding.gyp.no-auto"
|
|
68
64
|
],
|
package/vrpc/VrpcAdapter.js
CHANGED
|
@@ -10,9 +10,9 @@ __\/\\\_______\/\\\__/\\\///////\\\___\/\\\/////////\\\____/\\\////////__
|
|
|
10
10
|
________\///________\///________\///__\///___________________\/////////__
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
Non-intrusively
|
|
13
|
+
Non-intrusively adapts code and provides access in form of asynchronous remote
|
|
14
14
|
procedure calls (RPC).
|
|
15
|
-
Author: Dr. Burkhard C. Heisen (https://github.com/
|
|
15
|
+
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>.
|
|
@@ -42,9 +42,9 @@ const path = require('path')
|
|
|
42
42
|
const fs = require('fs')
|
|
43
43
|
const Ajv = require('ajv')
|
|
44
44
|
const caller = require('caller')
|
|
45
|
-
const { nanoid } = require('nanoid')
|
|
46
45
|
const commentParser = require('./comment-parser')
|
|
47
46
|
const EventEmitter = require('events')
|
|
47
|
+
const { type } = require('os')
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Generates an adapter layer for existing code and enables further VRPC-based
|
|
@@ -152,10 +152,14 @@ class VrpcAdapter {
|
|
|
152
152
|
meta,
|
|
153
153
|
Klass: {},
|
|
154
154
|
withNew: false,
|
|
155
|
-
staticFunctions: [
|
|
155
|
+
staticFunctions: [],
|
|
156
156
|
schema: null
|
|
157
157
|
})
|
|
158
|
-
VrpcAdapter._instances.set(instance, {
|
|
158
|
+
VrpcAdapter._instances.set(instance, {
|
|
159
|
+
className,
|
|
160
|
+
instance: obj,
|
|
161
|
+
isIsolated: false
|
|
162
|
+
})
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
static getClasses () {
|
|
@@ -351,11 +355,10 @@ class VrpcAdapter {
|
|
|
351
355
|
staticFunctions = staticFunctions.filter(f => !f.startsWith('_'))
|
|
352
356
|
}
|
|
353
357
|
// Inject constructor and destructor
|
|
354
|
-
staticFunctions.push('
|
|
355
|
-
staticFunctions.push('
|
|
356
|
-
staticFunctions.push('__createNamed__')
|
|
357
|
-
staticFunctions.push('__getNamed__')
|
|
358
|
+
staticFunctions.push('__createIsolated__')
|
|
359
|
+
staticFunctions.push('__createShared__')
|
|
358
360
|
staticFunctions.push('__callAll__')
|
|
361
|
+
staticFunctions.push('__delete__')
|
|
359
362
|
let memberFunctions = VrpcAdapter._extractMemberFunctions(Klass)
|
|
360
363
|
if (onlyPublic) {
|
|
361
364
|
memberFunctions = memberFunctions.filter(f => {
|
|
@@ -416,7 +419,7 @@ class VrpcAdapter {
|
|
|
416
419
|
},
|
|
417
420
|
...params
|
|
418
421
|
]
|
|
419
|
-
meta.
|
|
422
|
+
meta.__createShared__ = { description, params: modified, ret }
|
|
420
423
|
} else {
|
|
421
424
|
meta[functionName] = { description, params, ret }
|
|
422
425
|
}
|
|
@@ -427,133 +430,170 @@ class VrpcAdapter {
|
|
|
427
430
|
}
|
|
428
431
|
|
|
429
432
|
static _call (json) {
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
case '
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
data.r = instanceId
|
|
441
|
-
} catch (err) {
|
|
442
|
-
data.e = err.message
|
|
443
|
-
}
|
|
433
|
+
const before = Object.keys(VrpcAdapter._listeners).length
|
|
434
|
+
switch (json.f) {
|
|
435
|
+
case '__createIsolated__':
|
|
436
|
+
VrpcAdapter._handleCreateIsolated(json)
|
|
437
|
+
break
|
|
438
|
+
case '__createShared__':
|
|
439
|
+
VrpcAdapter._handleCreateShared(json)
|
|
440
|
+
break
|
|
441
|
+
case '__callAll__':
|
|
442
|
+
VrpcAdapter._handleCallAll(json)
|
|
444
443
|
break
|
|
445
|
-
// Special case: dtor
|
|
446
444
|
case '__delete__':
|
|
447
|
-
|
|
448
|
-
const instanceId = wrappedArgs[0]
|
|
449
|
-
data.r = VrpcAdapter._delete(instanceId)
|
|
450
|
-
VrpcAdapter._emitter.emit('delete', {
|
|
451
|
-
className: context,
|
|
452
|
-
instance: wrappedArgs[0]
|
|
453
|
-
})
|
|
454
|
-
} catch (err) {
|
|
455
|
-
data.e = err.message
|
|
456
|
-
}
|
|
445
|
+
VrpcAdapter._handleDelete(json)
|
|
457
446
|
break
|
|
458
|
-
|
|
459
|
-
|
|
447
|
+
default:
|
|
448
|
+
VrpcAdapter._handleCall(json)
|
|
449
|
+
}
|
|
450
|
+
const after = Object.keys(VrpcAdapter._listeners).length
|
|
451
|
+
// if we took a listener on board we must tell our caller such that
|
|
452
|
+
// things can be cleaned up later.
|
|
453
|
+
return after > before
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
static _handleCreateIsolated (json) {
|
|
457
|
+
try {
|
|
458
|
+
const className = json.c
|
|
459
|
+
const [instanceId, ...args] = json.a
|
|
460
|
+
const instance = VrpcAdapter._create(className, instanceId, ...args)
|
|
461
|
+
VrpcAdapter._instances.set(instanceId, {
|
|
462
|
+
instance,
|
|
463
|
+
className,
|
|
464
|
+
isIsolated: true
|
|
465
|
+
})
|
|
466
|
+
json.r = instanceId
|
|
467
|
+
} catch (err) {
|
|
468
|
+
json.e = err.message
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
static _handleCreateShared (json) {
|
|
473
|
+
try {
|
|
474
|
+
const className = json.c
|
|
475
|
+
const [instanceId, ...args] = json.a
|
|
476
|
+
const instance = VrpcAdapter._create(className, instanceId, ...args)
|
|
477
|
+
VrpcAdapter._instances.set(instanceId, {
|
|
478
|
+
instance,
|
|
479
|
+
className,
|
|
480
|
+
isIsolated: false
|
|
481
|
+
})
|
|
482
|
+
json.r = instanceId
|
|
483
|
+
VrpcAdapter._emitter.emit('create', {
|
|
484
|
+
args,
|
|
485
|
+
className,
|
|
486
|
+
instance: instanceId
|
|
487
|
+
})
|
|
488
|
+
} catch (err) {
|
|
489
|
+
json.e = err.message
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
static _handleCallAll (json) {
|
|
494
|
+
try {
|
|
495
|
+
const calls = []
|
|
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
|
|
502
|
+
let v
|
|
503
|
+
let e = null
|
|
460
504
|
try {
|
|
461
|
-
VrpcAdapter.
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
instance: wrappedArgs[0],
|
|
466
|
-
args: wrappedArgs.slice(1)
|
|
467
|
-
})
|
|
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)
|
|
468
509
|
} catch (err) {
|
|
469
|
-
|
|
510
|
+
e = err.message
|
|
470
511
|
}
|
|
471
|
-
|
|
472
|
-
|
|
512
|
+
if (VrpcAdapter._isPromise(v)) {
|
|
513
|
+
calls.push(
|
|
514
|
+
v
|
|
515
|
+
.then(val => ({ id, val, err: null }))
|
|
516
|
+
.catch(err => ({ id, err, val: null }))
|
|
517
|
+
)
|
|
518
|
+
} else {
|
|
519
|
+
calls.push({ id, val: v, err: e })
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
this._handlePromise(json, Promise.all(calls))
|
|
523
|
+
} catch (err) {
|
|
524
|
+
json.e = err.message
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
static sanitizeEventListenerReturnValues (ret) {
|
|
529
|
+
return typeof ret === 'object' &&
|
|
530
|
+
ret._events !== undefined &&
|
|
531
|
+
ret._eventsCount !== undefined
|
|
532
|
+
? true
|
|
533
|
+
: ret
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
static _handleDelete (json) {
|
|
537
|
+
try {
|
|
538
|
+
const wrappedArgs = VrpcAdapter._wrapArguments(json)
|
|
539
|
+
const instanceId = wrappedArgs[0]
|
|
540
|
+
json.r = VrpcAdapter._delete(instanceId)
|
|
541
|
+
VrpcAdapter._emitter.emit('delete', {
|
|
542
|
+
className: json.c,
|
|
543
|
+
instance: wrappedArgs[0]
|
|
544
|
+
})
|
|
545
|
+
} catch (err) {
|
|
546
|
+
json.e = err.message
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
static _handleCall (json) {
|
|
551
|
+
const wrappedArgs = VrpcAdapter._wrapArguments(json)
|
|
552
|
+
// Check whether context is a registered class
|
|
553
|
+
const entry = VrpcAdapter._functionRegistry.get(json.c)
|
|
554
|
+
if (entry !== undefined) {
|
|
555
|
+
// entry is class -> function is static
|
|
556
|
+
const { Klass } = entry
|
|
557
|
+
// TODO Think about whether to do live checking (like here) or
|
|
558
|
+
// rather sticking to those functions registered before...
|
|
559
|
+
// TODO This is even more important now as the agent does a wildcard
|
|
560
|
+
// subscription against all functions
|
|
561
|
+
if (VrpcAdapter._isFunction(Klass[json.f])) {
|
|
473
562
|
try {
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
if (
|
|
477
|
-
|
|
563
|
+
const ret = Klass[json.f].apply(null, wrappedArgs)
|
|
564
|
+
// check if function returns promise
|
|
565
|
+
if (VrpcAdapter._isPromise(ret)) {
|
|
566
|
+
this._handlePromise(json, ret)
|
|
567
|
+
} else json.r = ret
|
|
478
568
|
} catch (err) {
|
|
479
|
-
|
|
569
|
+
json.e = err.message
|
|
480
570
|
}
|
|
481
|
-
|
|
482
|
-
|
|
571
|
+
} else throw new Error(`Could not find function: ${json.f}`)
|
|
572
|
+
} else {
|
|
573
|
+
// is not static
|
|
574
|
+
const entry = VrpcAdapter._instances.get(json.c)
|
|
575
|
+
if (entry === undefined) {
|
|
576
|
+
throw new Error(`Could not find context: ${json.c}`)
|
|
577
|
+
}
|
|
578
|
+
const { instance } = entry
|
|
579
|
+
if (VrpcAdapter._isFunction(instance[json.f])) {
|
|
483
580
|
try {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
try {
|
|
491
|
-
v = instance[funcName].apply(instance, wrappedArgs.slice(1))
|
|
492
|
-
} catch (err) {
|
|
493
|
-
e = err
|
|
494
|
-
}
|
|
495
|
-
// check wether function returned a promise
|
|
496
|
-
if (VrpcAdapter._isPromise(v)) {
|
|
497
|
-
calls.push(
|
|
498
|
-
v
|
|
499
|
-
.then(val => ({ id, val, err: null }))
|
|
500
|
-
.catch(err => ({ id, err, val: null }))
|
|
501
|
-
)
|
|
502
|
-
} else {
|
|
503
|
-
calls.push({ id, val: v, err: e })
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
this._handlePromise(json, method, Promise.all(calls))
|
|
581
|
+
let ret = instance[json.f].apply(instance, wrappedArgs)
|
|
582
|
+
ret = VrpcAdapter.sanitizeEventListenerReturnValues(ret)
|
|
583
|
+
// check if function returns promise
|
|
584
|
+
if (VrpcAdapter._isPromise(ret)) {
|
|
585
|
+
this._handlePromise(json, ret)
|
|
586
|
+
} else json.r = ret
|
|
507
587
|
} catch (err) {
|
|
508
|
-
|
|
588
|
+
json.e = err.message
|
|
509
589
|
}
|
|
510
|
-
|
|
511
|
-
// Regular function call
|
|
512
|
-
default: {
|
|
513
|
-
// Check whether context is a registered class
|
|
514
|
-
const entry = VrpcAdapter._functionRegistry.get(context)
|
|
515
|
-
if (entry !== undefined) {
|
|
516
|
-
// entry is class -> function is static
|
|
517
|
-
const { Klass } = entry
|
|
518
|
-
// TODO Think about whether to do live checking (like here) or
|
|
519
|
-
// rather sticking to those functions registered before...
|
|
520
|
-
// TODO This is even more important now as the agent does a wildcard
|
|
521
|
-
// subscription against all functions
|
|
522
|
-
if (VrpcAdapter._isFunction(Klass[method])) {
|
|
523
|
-
try {
|
|
524
|
-
const ret = Klass[method].apply(null, wrappedArgs)
|
|
525
|
-
// check if function returns promise
|
|
526
|
-
if (ret && this._isFunction(ret.then)) {
|
|
527
|
-
this._handlePromise(json, method, ret)
|
|
528
|
-
} else data.r = ret
|
|
529
|
-
} catch (err) {
|
|
530
|
-
data.e = err.message
|
|
531
|
-
}
|
|
532
|
-
} else throw new Error(`Could not find function: ${method}`)
|
|
533
|
-
} else {
|
|
534
|
-
// is not static
|
|
535
|
-
const entry = VrpcAdapter._instances.get(context)
|
|
536
|
-
if (entry === undefined) {
|
|
537
|
-
throw new Error(`Could not find context: ${context}`)
|
|
538
|
-
}
|
|
539
|
-
const { instance } = entry
|
|
540
|
-
if (VrpcAdapter._isFunction(instance[method])) {
|
|
541
|
-
try {
|
|
542
|
-
const ret = instance[method].apply(instance, wrappedArgs)
|
|
543
|
-
// check if function returns promise
|
|
544
|
-
if (VrpcAdapter._isPromise(ret)) {
|
|
545
|
-
this._handlePromise(json, method, ret)
|
|
546
|
-
} else data.r = ret
|
|
547
|
-
} catch (err) {
|
|
548
|
-
data.e = err.message
|
|
549
|
-
}
|
|
550
|
-
} else throw new Error(`Could not find function: ${method}`)
|
|
551
|
-
}
|
|
552
|
-
}
|
|
590
|
+
} else throw new Error(`Could not find function: ${json.f}`)
|
|
553
591
|
}
|
|
554
592
|
}
|
|
555
593
|
|
|
556
|
-
static _create (className, ...args) {
|
|
594
|
+
static _create (className, instanceId, ...args) {
|
|
595
|
+
const entry = VrpcAdapter._instances.get(instanceId)
|
|
596
|
+
if (entry) return entry.instance
|
|
557
597
|
const { Klass, withNew, schema } = VrpcAdapter._getClassEntry(className)
|
|
558
598
|
if (schema !== null) {
|
|
559
599
|
VrpcAdapter._validate(schema, ...args)
|
|
@@ -562,16 +602,6 @@ class VrpcAdapter {
|
|
|
562
602
|
return Klass(...args)
|
|
563
603
|
}
|
|
564
604
|
|
|
565
|
-
static _createNamed (className, instanceId, ...args) {
|
|
566
|
-
const entry = VrpcAdapter._instances.get(instanceId)
|
|
567
|
-
if (!entry) {
|
|
568
|
-
const instance = VrpcAdapter._create(className, ...args)
|
|
569
|
-
VrpcAdapter._instances.set(instanceId, { className, instance })
|
|
570
|
-
return instance
|
|
571
|
-
}
|
|
572
|
-
return entry.instance
|
|
573
|
-
}
|
|
574
|
-
|
|
575
605
|
static _delete (instanceId) {
|
|
576
606
|
const entry = VrpcAdapter._instances.get(instanceId)
|
|
577
607
|
if (entry) {
|
|
@@ -591,6 +621,18 @@ class VrpcAdapter {
|
|
|
591
621
|
delete VrpcAdapter._listeners[clientId]
|
|
592
622
|
}
|
|
593
623
|
|
|
624
|
+
static _unregisterEventListenersOfInstance (instance) {
|
|
625
|
+
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
|
|
630
|
+
}
|
|
631
|
+
return true
|
|
632
|
+
})
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
594
636
|
static _validate (schema, params) {
|
|
595
637
|
if (!VrpcAdapter._ajv) {
|
|
596
638
|
VrpcAdapter._ajv = new Ajv({ useDefaults: true })
|
|
@@ -599,42 +641,30 @@ class VrpcAdapter {
|
|
|
599
641
|
if (!valid) throw new Error(VrpcAdapter._ajv.errorsText())
|
|
600
642
|
}
|
|
601
643
|
|
|
602
|
-
static
|
|
603
|
-
const {
|
|
604
|
-
const
|
|
605
|
-
const wrappedArgs = []
|
|
644
|
+
static _wrapArguments (json, instanceId) {
|
|
645
|
+
const { f: func, s: sender, a: args, c: context } = json
|
|
646
|
+
const wrapped = []
|
|
606
647
|
args.forEach(arg => {
|
|
607
648
|
// Find those args that actually need to be function callbacks
|
|
608
649
|
if (typeof arg === 'string' && arg.substr(0, 5) === '__f__') {
|
|
609
|
-
const f = (
|
|
610
|
-
|
|
611
|
-
if (sender && !VrpcAdapter._listeners[sender]) return
|
|
612
|
-
const data = {}
|
|
613
|
-
innerArgs.forEach((value, index) => {
|
|
614
|
-
data[`_${index + 1}`] = value
|
|
615
|
-
})
|
|
616
|
-
const callbackJson = Object.assign({}, json, { data, id: arg })
|
|
617
|
-
const callbackJsonString = VrpcAdapter._stringifySafely(callbackJson)
|
|
618
|
-
VrpcAdapter._callback(callbackJsonString, callbackJson)
|
|
619
|
-
}
|
|
620
|
-
wrappedArgs.push(f)
|
|
650
|
+
const f = this._generateWrapper(arg, json, instanceId)
|
|
651
|
+
wrapped.push(f)
|
|
621
652
|
if (!sender) return
|
|
622
653
|
// Register this client to later know when he is dead and skip callbacks
|
|
623
654
|
if (!VrpcAdapter._listeners[sender]) VrpcAdapter._listeners[sender] = []
|
|
624
655
|
// Check whether injected callback is an EventEmitter registration
|
|
625
|
-
if (
|
|
656
|
+
if (func === 'on' && typeof args[0] === 'string') {
|
|
626
657
|
const e = args[0]
|
|
627
658
|
const i = context
|
|
628
659
|
const r = arg
|
|
629
660
|
VrpcAdapter._listeners[sender].push({ i, e, f, r })
|
|
630
661
|
}
|
|
631
662
|
if (
|
|
632
|
-
(
|
|
663
|
+
(func === 'off' || func === 'removeListener') &&
|
|
633
664
|
typeof args[0] === 'string'
|
|
634
665
|
) {
|
|
635
|
-
const
|
|
636
|
-
const
|
|
637
|
-
const entry = s && s.find(x => x.r === r)
|
|
666
|
+
const listener = VrpcAdapter._listeners[sender]
|
|
667
|
+
const entry = listener && listener.find(x => x.r === arg)
|
|
638
668
|
if (entry) {
|
|
639
669
|
const { i, e, f } = entry
|
|
640
670
|
VrpcAdapter.getInstance(i).removeListener(e, f)
|
|
@@ -642,54 +672,33 @@ class VrpcAdapter {
|
|
|
642
672
|
}
|
|
643
673
|
} else {
|
|
644
674
|
// Leave the others untouched
|
|
645
|
-
|
|
675
|
+
wrapped.push(arg)
|
|
646
676
|
}
|
|
647
677
|
})
|
|
648
|
-
return
|
|
678
|
+
return wrapped
|
|
649
679
|
}
|
|
650
680
|
|
|
651
|
-
static
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
.then(value => {
|
|
658
|
-
const data = { r: value }
|
|
659
|
-
const promiseJson = Object.assign({}, json, { data, id })
|
|
660
|
-
const promiseJsonString = VrpcAdapter._stringifySafely(promiseJson)
|
|
661
|
-
VrpcAdapter._callback(promiseJsonString, promiseJson)
|
|
662
|
-
})
|
|
663
|
-
.catch(err => {
|
|
664
|
-
const data = { e: err.message }
|
|
665
|
-
const promiseJson = Object.assign({}, json, { data, id })
|
|
666
|
-
const promiseJsonString = VrpcAdapter._stringifySafely(promiseJson)
|
|
667
|
-
VrpcAdapter._callback(promiseJsonString, promiseJson)
|
|
668
|
-
})
|
|
669
|
-
} catch (err) {
|
|
670
|
-
json.data.e = err.message
|
|
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
|
|
685
|
+
const a = instanceId ? [instanceId, ...innerArgs] : [...innerArgs]
|
|
686
|
+
VrpcAdapter._callback({ a, s: json.s, f: json.f, i: id })
|
|
671
687
|
}
|
|
688
|
+
return wrapper
|
|
672
689
|
}
|
|
673
690
|
|
|
674
|
-
static
|
|
675
|
-
let jsonString
|
|
691
|
+
static _handlePromise (json, promise) {
|
|
676
692
|
try {
|
|
677
|
-
|
|
693
|
+
const cid = VrpcAdapter._correlationId++ % Number.MAX_SAFE_INTEGER
|
|
694
|
+
const id = `__p__${json.f}-${cid}`
|
|
695
|
+
json.r = id
|
|
696
|
+
promise
|
|
697
|
+
.then(r => VrpcAdapter._callback({ ...json, r, i: id }))
|
|
698
|
+
.catch(err => VrpcAdapter._callback({ ...json, e: err.message, i: id }))
|
|
678
699
|
} catch (err) {
|
|
679
|
-
|
|
680
|
-
`Failed serialization of return value for: ${json.context}::${json.method}, because: ${err.message}`
|
|
681
|
-
)
|
|
682
|
-
json.data.r = '__vrpc::not-serializable__'
|
|
683
|
-
jsonString = JSON.stringify(json)
|
|
700
|
+
json.data.e = err.message
|
|
684
701
|
}
|
|
685
|
-
return jsonString
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
static _extractDataToArray (data) {
|
|
689
|
-
return Object.keys(data)
|
|
690
|
-
.sort()
|
|
691
|
-
.filter(value => value[0] === '_')
|
|
692
|
-
.map(key => data[key])
|
|
693
702
|
}
|
|
694
703
|
|
|
695
704
|
static _generateId (object) {
|
|
@@ -775,8 +784,8 @@ class VrpcAdapter {
|
|
|
775
784
|
|
|
776
785
|
static _getInstancesArray (className) {
|
|
777
786
|
const instances = []
|
|
778
|
-
VrpcAdapter._instances.forEach((
|
|
779
|
-
if (
|
|
787
|
+
VrpcAdapter._instances.forEach((v, k) => {
|
|
788
|
+
if (v.className === className && !v.isIsolated) instances.push(k)
|
|
780
789
|
})
|
|
781
790
|
return instances
|
|
782
791
|
}
|