Skip to content

Commit a091a6e

Browse files
authored
Merge pull request #47 from datapartyjs/protocol-updates
host protocol scheme
2 parents 9a72331 + d91f8bf commit a091a6e

11 files changed

Lines changed: 541 additions & 52 deletions

examples/test-loopback-party.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async function main(){
3333
})
3434

3535

36-
let comms2 = new Dataparty.Comms.LoopbackComms({ channel: loopback.peer2 })
36+
let comms2 = new Dataparty.Comms.LoopbackComms({ channel: loopback.peer2, session: 'foobar' })
3737

3838
let peer2 = new Dataparty.PeerParty({
3939
comms: comms2,
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
const debug = require('debug')('test.peer-party-service')
2+
const WRTC = require('wrtc')
3+
const Path = require('path')
4+
const BouncerModel = require('@dataparty/bouncer-model/dist/bouncer-model.json')
5+
const Dataparty = require('../src')
6+
7+
const BouncerServerModels = require('@dataparty/bouncer-model')
8+
9+
class ExampleService extends Dataparty.IService {
10+
constructor(opts){
11+
super(opts)
12+
13+
this.addMiddleware(Dataparty.middleware_paths.pre.decrypt)
14+
this.addMiddleware(Dataparty.middleware_paths.pre.validate)
15+
16+
this.addMiddleware(Dataparty.middleware_paths.post.validate)
17+
this.addMiddleware(Dataparty.middleware_paths.post.encrypt)
18+
19+
this.addEndpoint(Dataparty.endpoint_paths.echo)
20+
this.addEndpoint(Dataparty.endpoint_paths.secureecho)
21+
this.addEndpoint(Dataparty.endpoint_paths.identity)
22+
this.addEndpoint(Dataparty.endpoint_paths.version)
23+
}
24+
25+
}
26+
27+
async function main(){
28+
const dbPath = '/tmp/local-peer-party-service'
29+
30+
debug('db location', dbPath)
31+
32+
let hostLocal = new Dataparty.TingoParty({
33+
path: dbPath,
34+
model: BouncerModel,
35+
serverModels: BouncerServerModels,
36+
config: new Dataparty.Config.JsonFileConfig({basePath: dbPath})
37+
})
38+
39+
const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' })
40+
41+
const build = await service.compile(Path.join(__dirname,'/dataparty'), true)
42+
43+
debug('built', Object.keys(build))
44+
45+
const runner = new Dataparty.ServiceRunnerNode({
46+
party: hostLocal, service,
47+
sendFullErrors: false
48+
})
49+
50+
/*let hostLocal = new Dataparty.LokiParty({
51+
path: dbPath,
52+
model: BouncerModel,
53+
config: new Dataparty.Config.MemoryConfig()
54+
})*/
55+
56+
let peer1 = new Dataparty.PeerParty({
57+
comms: new Dataparty.Comms.RTCSocketComms({
58+
host: true,
59+
wrtc: WRTC,
60+
trickle: true,
61+
discoverRemoteIdentity: true
62+
}),
63+
hostParty: hostLocal,
64+
hostRunner: runner,
65+
model: BouncerModel,
66+
config: new Dataparty.Config.MemoryConfig()
67+
})
68+
69+
70+
let peer2 = new Dataparty.PeerParty({
71+
comms: new Dataparty.Comms.RTCSocketComms({
72+
wrtc: WRTC,
73+
trickle: true,
74+
session: 'foobar'
75+
}),
76+
model: BouncerModel,
77+
config: new Dataparty.Config.MemoryConfig()
78+
})
79+
80+
81+
82+
await peer1.loadIdentity()
83+
await peer2.loadIdentity()
84+
85+
//peer1.comms.remoteIdentity = peer2.identity
86+
peer2.comms.remoteIdentity = peer1.identity
87+
88+
await peer1.start()
89+
await runner.start()
90+
91+
await peer2.start()
92+
93+
peer1.comms.socket.on('signal', data=>{
94+
debug('p1 >> p2', data)
95+
peer2.comms.socket.signal(data)
96+
})
97+
98+
peer2.comms.socket.on('signal', data=>{
99+
debug('p1 << p2', data)
100+
peer1.comms.socket.signal(data)
101+
})
102+
103+
debug('waiting for auth')
104+
await Promise.all([
105+
peer1.comms.authorized(),
106+
peer2.comms.authorized()
107+
])
108+
109+
debug('authed')
110+
111+
const remoteVersion = await peer2.comms.call('version')
112+
const remoteId = await peer2.comms.call('identity')
113+
114+
115+
116+
let user = (await peer2.find()
117+
.type('user')
118+
.where('name').equals('tester')
119+
.exec())[0]
120+
121+
122+
if(!user){
123+
debug('creating document')
124+
user = await peer2.createDocument('user', {name: 'tester', created: (new Date()).toISOString() })
125+
}
126+
else{
127+
debug('loaded document')
128+
}
129+
130+
131+
console.log(remoteId)
132+
console.log(remoteVersion)
133+
134+
console.log(user.data)
135+
process.exit()
136+
}
137+
138+
139+
main().catch(err=>{
140+
console.error(err)
141+
})

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@dataparty/api",
33
"private": false,
4-
"version": "1.2.16",
4+
"version": "1.2.17",
55
"main": "dist/dataparty.js",
66
"frontend": "dist/dataparty-browser.js",
77
"backend": "dist/dataparty.js",
@@ -76,6 +76,7 @@
7676
"express": "^4.17.1",
7777
"express-list-routes": "^0.1.4",
7878
"git-repo-info": "^2.1.1",
79+
"joi-objectid": "^4.0.2",
7980
"jshashes": "^1.0.8",
8081
"jsonpath-plus": "^0.20.1",
8182
"last-eventemitter": "^1.1.1",
@@ -86,6 +87,7 @@
8687
"morgan": "^1.10.0",
8788
"multer": "^1.4.5-lts.1",
8889
"nconf": "^0.10.0",
90+
"node-mocks-http": "^1.12.1",
8991
"node-persist": "^3.0.1",
9092
"origin-router": "^1.6.4",
9193
"parse-url": "^5.0.1",
@@ -128,7 +130,7 @@
128130
"tmp": "^0.2.1",
129131
"url": "^0.11.0",
130132
"util": "^0.12.4",
131-
"wrtc": "^0.4.7"
133+
"wrtc": "npm:@koush/wrtc@^0.5.3"
132134
},
133135
"repository": {
134136
"type": "git",

src/comms/host/host-op.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
const reach = require('../../utils/reach')
2+
const debug = require('debug')('dataparty.op.host-op')
3+
const moment = require('moment')
4+
const EventEmitter = require('eventemitter3')
5+
6+
const OP_STATUS_LEVEL = {
7+
Status_Undefined: 'Status_Undefined',
8+
Status_None: 'Status_None',
9+
Status_Error: 'Status_Error',
10+
Status_Warning: 'Status_Warning',
11+
Status_Info: 'Status_Info',
12+
Status_Debug: 'Status_Debug'
13+
}
14+
15+
16+
const OP_STATES = {
17+
Pending: 'Pending',
18+
Starting: 'Starting',
19+
Running: 'Running',
20+
Finished_Success: 'Finished_Success',
21+
Finished_Fail: 'Finished_Fail',
22+
Finished_Permission_Denied: 'Finished_Permission_Denied',
23+
Finished_Invalid_Op: 'Finished_Invalid_Op',
24+
Finished_Invalid_Id: 'Finished_Invalid_Id',
25+
Finished_Buffer_Full: 'Finished_Buffer_Full'
26+
}
27+
28+
class Op extends EventEmitter {
29+
constructor({msg, input}){
30+
super()
31+
this.msg = msg //! original encrypted message
32+
this.input = input //! parsed and validated input
33+
this.start = Date.now()
34+
this.end = undefined
35+
this.state = Op.STATES.Pending
36+
this.level = Op.STATUS_LEVELS.Status_Info
37+
this.result = null
38+
}
39+
40+
get op(){
41+
return reach(this.input, 'op')
42+
}
43+
44+
get id(){
45+
return reach(this.input, 'id')
46+
}
47+
48+
49+
static get STATES(){
50+
return OP_STATES
51+
}
52+
53+
static get STATUS_LEVELS(){
54+
return OP_STATUS_LEVEL
55+
}
56+
57+
setState(state, level, message){
58+
59+
this.state = state
60+
61+
const status = {
62+
op: 'status',
63+
id: this.id,
64+
state: this.state,
65+
level: level || Op.STATUS_LEVELS.Status_Info,
66+
msg: message || undefined,
67+
timestamp: Date.now(),
68+
stats: {
69+
start: this.start,
70+
end: this.end,
71+
duration_ms: this.end - this.start
72+
}
73+
}
74+
75+
if(this.state == Op.STATES.Finished_Success ||
76+
this.state == Op.STATES.Finished_Fail ||
77+
this.state == Op.STATES.Finished_Invalid_Op ||
78+
this.state == Op.STATES.Finished_Invalid_Id ||
79+
this.state == Op.STATES.Finished_Permission_Denied ||
80+
this.state == Op.STATES.Finished_Buffer_Full)
81+
{
82+
debug('set end time')
83+
this.end = Date.now()
84+
this.emit('finished', true)
85+
}
86+
else{
87+
this.emit('finished', false)
88+
this.emit('status', status)
89+
}
90+
}
91+
92+
setOpStatusLevel(level){
93+
this.level = level
94+
}
95+
96+
}
97+
98+
module.exports = Op
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
const Joi = require('@hapi/joi')
2+
Joi.objectId = require('joi-objectid')(Joi)
3+
4+
const ID_SCHEME = Joi.alternatives().try(Joi.string(), Joi.number())
5+
6+
const OP_HEADER = Joi.object().keys({
7+
id: ID_SCHEME.required(),
8+
op: Joi.string().valid(
9+
'auth',
10+
'peer-call',
11+
'advertise',
12+
'subscribe',
13+
'unsubscribe',
14+
'publish'
15+
).required()
16+
})
17+
18+
19+
const AUTH_OP = Joi.object().keys({
20+
id: ID_SCHEME.required(),
21+
op: Joi.string().valid('auth').required(),
22+
session: Joi.string().required(), //Joi.objectId().required(),
23+
})
24+
25+
const CALL_OP = Joi.object().keys({
26+
id: ID_SCHEME.required(),
27+
op: Joi.string().valid('peer-call').required(),
28+
session: Joi.string(), //Joi.objectId(),
29+
endpoint: Joi.string(),
30+
data: Joi.object()
31+
})
32+
33+
const ADVERTISE_OP = Joi.object().keys({
34+
id: ID_SCHEME.required(),
35+
op: Joi.string().valid('advertise').required(),
36+
type: Joi.string().required(),
37+
topic: Joi.string().required(),
38+
queue_size: Joi.number(),
39+
latch: Joi.boolean()
40+
})
41+
42+
const UNADVERTISE_OP = Joi.object().keys({
43+
id: ID_SCHEME.required(),
44+
op: Joi.string().valid('unadvertise').required(),
45+
topic: Joi.string().required()
46+
})
47+
48+
49+
const SUBSCRIBE_OP = Joi.object().keys({
50+
id: ID_SCHEME.required(),
51+
op: Joi.string().valid('subscribe').required(),
52+
type: Joi.string().required(),
53+
topic: Joi.string().required(),
54+
compression: Joi.string(),
55+
queue_length: Joi.number(),
56+
throttle_rate: Joi.number()
57+
})
58+
59+
const UNSUBSCRIBE_OP = Joi.object().keys({
60+
id: ID_SCHEME.required(),
61+
op: Joi.string().valid('unsubscribe').required(),
62+
topic: Joi.string().required()
63+
})
64+
65+
const PUBLISH_OP = Joi.object().keys({
66+
id: ID_SCHEME.required(),
67+
op: Joi.string().valid('publish').required(),
68+
topic: Joi.string().required(),
69+
latch: Joi.boolean(),
70+
msg: Joi.any()
71+
})
72+
73+
74+
const ANY_OP = Joi.alternatives().try(
75+
ADVERTISE_OP,
76+
UNADVERTISE_OP,
77+
SUBSCRIBE_OP,
78+
UNSUBSCRIBE_OP,
79+
PUBLISH_OP,
80+
CALL_OP
81+
)
82+
83+
module.exports = {
84+
'OP_HEADER': OP_HEADER,
85+
'AUTH_OP': AUTH_OP,
86+
'ADVERTISE_OP': ADVERTISE_OP,
87+
'UNADVERTISE_OP': UNADVERTISE_OP,
88+
'SUBSCRIBE_OP': SUBSCRIBE_OP,
89+
'UNSUBSCRIBE_OP': UNSUBSCRIBE_OP,
90+
'PUBLISH_OP': PUBLISH_OP,
91+
'PEER_CALL_OP': CALL_OP,
92+
'ANY_OP': ANY_OP
93+
}

0 commit comments

Comments
 (0)