vrpc 3.13.0 → 3.15.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/LICENSE +1 -1
- package/README.md +100 -77
- package/browser/vrpc.js +5 -5
- package/index.js +7 -7
- package/package.json +25 -15
- package/vrpc/ReconnectBackoff.js +79 -0
- package/vrpc/Registrations.js +850 -0
- package/vrpc/SubscribeRetrier.js +33 -0
- package/vrpc/VrpcAdapter.js +552 -294
- package/vrpc/VrpcAgent.js +242 -154
- package/vrpc/VrpcBrowserAdapter.js +417 -285
- package/vrpc/VrpcBrowserAgent.js +239 -128
- package/vrpc/VrpcClient.js +1221 -233
- package/vrpc/VrpcNative.js +10 -5
- package/vrpc/VrpcPersistor.js +1 -1
- package/vrpc/adapter.hpp +1 -1
- package/vrpc/addon.cpp +1 -1
- package/vrpc/comment-parser/parser.js +23 -0
- package/vrpc/namePattern.js +86 -0
- package/vrpc/vrpc-agent-js +3 -11
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2018
|
|
3
|
+
Copyright (c) 2018 Dr. Burkhard C. Heisen
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,126 +1,149 @@
|
|
|
1
|
-
# VRPC JavaScript
|
|
1
|
+
# VRPC for JavaScript
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
4
|
[](https://www.npmjs.com/package/vrpc)
|
|
5
5
|
|
|
6
|
-
**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
**Call classes in other programs as if they were local.** VRPC (Variadic
|
|
7
|
+
Remote Procedure Call) makes the classes of a Node.js, C++, Python or
|
|
8
|
+
Arduino program callable from any other program - a backend service, a
|
|
9
|
+
browser, a device - across any network, without REST routes, schemas or
|
|
10
|
+
WebSocket plumbing.
|
|
11
|
+
|
|
12
|
+
This package is VRPC for JavaScript: the **agent** that offers your Node.js
|
|
13
|
+
or browser code, and the **client** that uses remote code from Node.js or
|
|
14
|
+
the browser.
|
|
15
|
+
|
|
16
|
+
## Why VRPC
|
|
17
|
+
|
|
18
|
+
- **No API layer.** Register a class and its functions are callable
|
|
19
|
+
remotely: instances, static functions, promises, callbacks and errors work
|
|
20
|
+
as they do locally.
|
|
21
|
+
- **Events that scale.** Many clients can listen to the same events; the
|
|
22
|
+
agent calls your event function once, hands every event to every
|
|
23
|
+
listener, greets newcomers with the current state, and cleans up when the
|
|
24
|
+
last one leaves.
|
|
25
|
+
- **Reaches everything.** Built on MQTT: agents and clients only connect out
|
|
26
|
+
to a broker, so code behind firewalls and NATs is reachable, and
|
|
27
|
+
connections that break come back by themselves.
|
|
28
|
+
- **One protocol, several languages.** A browser can call a C++ agent; a
|
|
29
|
+
Python service can listen to a Node.js agent.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
22
32
|
|
|
23
33
|
```bash
|
|
24
34
|
npm install vrpc
|
|
25
|
-
# or
|
|
26
|
-
yarn add vrpc
|
|
27
35
|
```
|
|
28
36
|
|
|
29
|
-
## Quick
|
|
30
|
-
|
|
31
|
-
With VRPC, making a Node.js class remotely accessible and consuming it from a frontend requires almost zero API code.
|
|
37
|
+
## Quick start
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
Offer a class from one program - the **agent**:
|
|
34
40
|
|
|
35
41
|
```javascript
|
|
36
|
-
//
|
|
37
|
-
const { VrpcAdapter, VrpcAgent } = require('vrpc')
|
|
42
|
+
// agent.js
|
|
38
43
|
const EventEmitter = require('events')
|
|
44
|
+
const { VrpcAdapter, VrpcAgent } = require('vrpc')
|
|
39
45
|
|
|
40
|
-
// A standard ES6 Class using Promises and EventEmitters
|
|
41
46
|
class Sensor extends EventEmitter {
|
|
42
|
-
constructor(
|
|
47
|
+
constructor (id) {
|
|
43
48
|
super()
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
// Simulate real-time data
|
|
47
|
-
setInterval(() => {
|
|
48
|
-
this.emit('data', { id: this.id, value: Math.random() })
|
|
49
|
-
}, 1000)
|
|
49
|
+
this._timer = setInterval(() => this.emit('data', { id, value: Math.random() }), 1000)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
async calibrate() {
|
|
53
|
-
console.log(`Calibrating sensor ${this.id}...`)
|
|
52
|
+
async calibrate () {
|
|
54
53
|
return true
|
|
55
54
|
}
|
|
55
|
+
|
|
56
|
+
[Symbol.dispose] () {
|
|
57
|
+
clearInterval(this._timer) // released when the instance is deleted
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
// 1. Register the class
|
|
59
61
|
VrpcAdapter.register(Sensor)
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
agent: 'sensor_backend',
|
|
65
|
-
broker: 'mqtts://broker.hivemq.com:8883'
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
agent.serve().then(() => console.log('Backend is online!'))
|
|
63
|
+
new VrpcAgent({ domain: 'my-domain', agent: 'sensors' })
|
|
64
|
+
.serve()
|
|
65
|
+
.then(() => console.log('Agent is serving'))
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Once your Node.js agent is running, you can interact with it transparently from any VRPC client (Browser or Node.js):
|
|
68
|
+
Use it from another - the **client**, in Node.js or a browser:
|
|
74
69
|
|
|
75
70
|
```javascript
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
async function run() {
|
|
80
|
-
const client = new VrpcClient({
|
|
81
|
-
domain: 'my_domain',
|
|
82
|
-
broker: 'mqtts://broker.hivemq.com:8883'
|
|
83
|
-
})
|
|
71
|
+
// client.js
|
|
72
|
+
const { VrpcClient } = require('vrpc')
|
|
84
73
|
|
|
74
|
+
async function main () {
|
|
75
|
+
const client = new VrpcClient({ domain: 'my-domain' })
|
|
85
76
|
await client.connect()
|
|
86
77
|
|
|
87
|
-
// Create a remote instance of your Node.js class
|
|
88
78
|
const sensor = await client.create({
|
|
89
|
-
agent: '
|
|
79
|
+
agent: 'sensors',
|
|
90
80
|
className: 'Sensor',
|
|
91
|
-
|
|
81
|
+
instance: 'living-room',
|
|
82
|
+
args: ['living-room']
|
|
92
83
|
})
|
|
93
84
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
console.log(`Calibration successful: ${isCalibrated}`)
|
|
97
|
-
|
|
98
|
-
// Listen to remote EventEmitters across the network!
|
|
99
|
-
await sensor.on('data', reading => {
|
|
100
|
-
console.log(`New reading from ${reading.id}: ${reading.value}`)
|
|
101
|
-
})
|
|
85
|
+
console.log('calibrated:', await sensor.calibrate())
|
|
86
|
+
await sensor.on('data', ({ id, value }) => console.log(id, value))
|
|
102
87
|
}
|
|
103
88
|
|
|
104
|
-
|
|
89
|
+
main()
|
|
105
90
|
```
|
|
106
91
|
|
|
107
|
-
|
|
92
|
+
Both connect to a public test broker by default; use a domain of your own,
|
|
93
|
+
and your own broker for anything real. The
|
|
94
|
+
[tutorial](docs/getting-started.md) takes it further in ten minutes.
|
|
108
95
|
|
|
109
|
-
|
|
96
|
+
## Event functions
|
|
110
97
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
98
|
+
A function that calls a handler again and again returns a **registration**
|
|
99
|
+
that tells the agent how to undo the call, and optionally how to greet a new
|
|
100
|
+
listener:
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
/**
|
|
104
|
+
* Calls back with every reading, beginning with the current one
|
|
105
|
+
* @param {Function} handler
|
|
106
|
+
* @returns {Registration}
|
|
107
|
+
*/
|
|
108
|
+
onReading (handler) {
|
|
109
|
+
this._emitter.on('reading', handler)
|
|
110
|
+
return {
|
|
111
|
+
[Symbol.dispose]: () => this._emitter.off('reading', handler),
|
|
112
|
+
greet: greeting => greeting(this._reading)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The agent calls it once, however many clients subscribe, and releases it
|
|
118
|
+
when the last one leaves. See [Events](docs/concepts/events.md) and
|
|
119
|
+
[Writing event functions](docs/guides/event-functions.md).
|
|
115
120
|
|
|
116
121
|
## Documentation
|
|
117
122
|
|
|
118
|
-
|
|
123
|
+
- [Getting started](docs/getting-started.md) - a ten-minute tutorial
|
|
124
|
+
- [How VRPC works](docs/concepts/overview.md), [Instances](docs/concepts/instances.md),
|
|
125
|
+
[Calls](docs/concepts/calls.md), [Events](docs/concepts/events.md)
|
|
126
|
+
- Guides: [offering classes](docs/guides/expose-classes.md),
|
|
127
|
+
[the browser](docs/guides/browser-and-react.md),
|
|
128
|
+
[persistence](docs/guides/persistence.md),
|
|
129
|
+
[security](docs/guides/security.md), [production](docs/guides/production.md),
|
|
130
|
+
[troubleshooting](docs/guides/troubleshooting.md)
|
|
131
|
+
- [API reference](docs/reference/README.md)
|
|
132
|
+
- [Protocol specification](docs/spec/protocol.md), for every VRPC implementation
|
|
133
|
+
- [All documentation](docs/README.md), and [vrpc.io](https://vrpc.io)
|
|
134
|
+
|
|
135
|
+
## The VRPC family
|
|
136
|
+
|
|
137
|
+
- [vrpc-hpp](https://github.com/heisenware/vrpc-hpp) - C++
|
|
138
|
+
- [vrpc-py](https://github.com/heisenware/vrpc-py) - Python
|
|
139
|
+
- [vrpc-arduino](https://github.com/heisenware/vrpc-arduino) - Arduino and ESP32
|
|
140
|
+
- [vrpc-react](https://github.com/heisenware/vrpc-react) - React hooks
|
|
119
141
|
|
|
120
|
-
## Contributing
|
|
142
|
+
## Contributing and security
|
|
121
143
|
|
|
122
|
-
|
|
144
|
+
Bug reports and small fixes are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
145
|
+
Report security issues privately, as described in [SECURITY.md](SECURITY.md).
|
|
123
146
|
|
|
124
147
|
## License
|
|
125
148
|
|
|
126
|
-
|
|
149
|
+
[MIT](LICENSE)
|