Skip to content

Commit 28069e3

Browse files
committed
Removed node.close and added serialize and deserialize
1 parent da16e8d commit 28069e3

File tree

5 files changed

+71
-107
lines changed

5 files changed

+71
-107
lines changed

README.md

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,11 @@
1414

1515
</div>
1616

17-
Distributed Object Protocol is a thin layer on top of your data network that helps you communicate server and clients (nodes) using [RPCs](https://en.wikipedia.org/wiki/Remote_procedure_call). It is also a pattern that makes easy update, mutate or even sync the state of your App using [Patches](https://github.com/DistributedObjectProtocol/protocol#Patches).
18-
19-
## Quick example using RPCs with WebSockets
20-
21-
```js
22-
// Server (node.js)
23-
const { createNode } = require('dop')
24-
const WebSocket = require('ws')
25-
const wss = new WebSocket.Server({ port: 8080 })
26-
27-
const sum = (a, b) => a + b
28-
const multiply = (a, b) => a * b
29-
const getCalculator = () => ({ sum, multiply })
30-
31-
wss.on('connection', ws => {
32-
const client = createNode()
33-
client.open(msg => ws.send(JSON.stringify(msg)), getCalculator)
34-
ws.on('message', msg => client.message(JSON.parse(msg)))
35-
ws.on('close', client.close)
36-
})
37-
```
38-
39-
```js
40-
// Client (Browser)
41-
import { createNode } from 'dop'
42-
const ws = new WebSocket('ws://localhost:8080')
43-
const server = createNode()
44-
45-
ws.onopen = async () => {
46-
const getCalculator = server.open(msg => ws.send(JSON.stringify(msg)))
47-
const { sum, multiply } = await getCalculator()
48-
const result1 = await sum(5, 5)
49-
const result2 = await multiply(5, 5)
50-
console.log(result1, result2) // 10, 25
51-
}
52-
ws.onmessage = msg => server.message(JSON.parse(msg.data))
53-
ws.onclose = server.close
54-
```
17+
**Distributed Object Protocol** is a thin layer on top of your data network that helps you communicate server and clients (nodes) using [RPCs](https://en.wikipedia.org/wiki/Remote_procedure_call). It is also a pattern that makes easy update, mutate or even sync the state of your App using [Patches](https://github.com/DistributedObjectProtocol/protocol#Patches).
18+
19+
## RPCs with WebSockets
20+
21+
image
5522

5623
Check the website for more info [https://distributedobjectprotocol.org/](https://distributedobjectprotocol.org/guide/javascript)
5724

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dop",
3-
"version": "1.0.0-beta.5",
3+
"version": "1.0.0-beta.6",
44
"main": "dist/dop.js",
55
"browser": "dist/dop.umd.js",
66
"license": "MIT",

src/api/createNodeFactory.js

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import converter from '../util/converter'
55
import Func from '../types/Function'
66

77
export default function createNodeFactory({ encoders, decoders }) {
8-
return function createNode({ max_remote_functions = Infinity } = {}) {
8+
return function createNode({
9+
serialize = JSON.stringify,
10+
deserialize = JSON.parse,
11+
max_remote_functions = Infinity
12+
} = {}) {
913
const requests = {}
1014
const local_functions_id = {}
1115
const local_functions = new Map()
@@ -61,74 +65,68 @@ export default function createNodeFactory({ encoders, decoders }) {
6165
function open(send, fn) {
6266
const remote_function_id = remote_function_index++
6367
const local_function_id = local_function_index++
64-
api.send = send
65-
api.opened = true
68+
api.send = msg => send(serialize(msg))
6669
if (isFunction(fn)) registerLocalFunction(fn, local_function_id)
6770
return createRemoteFunction(remote_function_id)
6871
}
6972

7073
function message(msg) {
71-
if (api.opened) {
72-
try {
73-
msg = decode(msg)
74-
} catch (e) {
75-
// Invalid array to decode
76-
return false
77-
}
74+
msg = deserialize(msg)
75+
try {
76+
msg = decode(msg)
77+
} catch (e) {
78+
// Invalid array to decode
79+
return false
80+
}
81+
82+
let [id, function_id, args] = msg
83+
const response_id = -id
84+
85+
if (isInteger(id)) {
86+
const fn = local_functions_id[function_id]
87+
88+
if (id > -1 && isFunction(fn)) {
89+
args = isArray(msg[2]) ? msg[2] : []
7890

79-
let [id, function_id, args] = msg
80-
const response_id = -id
81-
82-
if (isInteger(id)) {
83-
const fn = local_functions_id[function_id]
84-
85-
if (id > -1 && isFunction(fn)) {
86-
args = isArray(msg[2]) ? msg[2] : []
87-
88-
// Request without response
89-
if (id === 0) {
90-
const req = { node: api }
91-
args.push(req)
92-
fn.apply(req, args)
93-
}
94-
95-
// Request
96-
else {
97-
const req = createRequest()
98-
const response = [response_id]
99-
req.node = api
100-
req.then(value => {
101-
response.push(0) // no errors
102-
if (value !== undefined) response.push(value)
103-
api.send(encode(response))
104-
}).catch(error => {
105-
response.push(error) // error
106-
api.send(encode(response))
107-
})
108-
args.push(req)
109-
localProcedureCall(fn, req, args)
110-
}
111-
return true
91+
// Request without response
92+
if (id === 0) {
93+
const req = { node: api }
94+
args.push(req)
95+
fn.apply(req, args)
11296
}
11397

114-
// Response
115-
else if (id < 0 && requests.hasOwnProperty(response_id)) {
116-
const response_status = function_id
117-
const req = requests[response_id]
118-
response_status === 0
119-
? req.resolve(args)
120-
: req.reject(response_status)
121-
return true
98+
// Request
99+
else {
100+
const req = createRequest()
101+
const response = [response_id]
102+
req.node = api
103+
req.then(value => {
104+
response.push(0) // no errors
105+
if (value !== undefined) response.push(value)
106+
api.send(encode(response))
107+
}).catch(error => {
108+
response.push(error) // error
109+
api.send(encode(response))
110+
})
111+
args.push(req)
112+
localProcedureCall(fn, req, args)
122113
}
114+
return true
115+
}
116+
117+
// Response
118+
else if (id < 0 && requests.hasOwnProperty(response_id)) {
119+
const response_status = function_id
120+
const req = requests[response_id]
121+
response_status === 0
122+
? req.resolve(args)
123+
: req.reject(response_status)
124+
return true
123125
}
124126
}
125127
return false
126128
}
127129

128-
function close() {
129-
api.opened = false
130-
}
131-
132130
function registerLocalFunctionFromEncode(fn) {
133131
return registerLocalFunction(fn, local_function_index++)
134132
}
@@ -163,8 +161,6 @@ export default function createNodeFactory({ encoders, decoders }) {
163161
const api = {
164162
open,
165163
message,
166-
close,
167-
opened: false,
168164
requests,
169165
remote_functions // Exposing this can be used to know if a function is a remote function
170166
}

src/util/forEachObject.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ function forEachObjectLoop(origin, destiny, mutator, path) {
1111
forEach(origin, (value_origin, prop) => {
1212
path.push(prop)
1313
const shallWeGoDown = mutator({ origin, destiny, prop, path })
14-
if (shallWeGoDown !== false && isObject(value_origin)) {
14+
if (shallWeGoDown !== false && isObject(value_origin))
1515
forEachObjectLoop(value_origin, destiny[prop], mutator, path)
16-
}
1716
path.pop()
1817
})
1918
}

test/createNode.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ test('Api', async t => {
1717
const callClient = server.open(client.message)
1818
const promise = callClient(2, 5)
1919

20-
t.deepEqual(Object.keys(server).length, 7)
20+
t.deepEqual(Object.keys(server).length, 5)
2121

2222
t.deepEqual(Object.keys(promise).length, 5)
2323
t.true(promise instanceof Promise)
24-
t.is(server.send, client.message)
2524
t.is(promise.node, server)
25+
t.is(typeof server.send, 'function')
2626
t.is(typeof promise.resolve, 'function')
2727
t.is(typeof promise.reject, 'function')
2828
t.is(typeof promise.createdAt, 'number')
@@ -127,8 +127,9 @@ test('Sending remote functions that is from the same node must be replaced as nu
127127
})
128128

129129
test('Testing messages', async t => {
130-
const server = createNode()
131-
const client = createNode()
130+
const serdes = { serialize: m => m, deserialize: m => m }
131+
const server = createNode(serdes)
132+
const client = createNode(serdes)
132133

133134
client.open(
134135
msg => {
@@ -146,8 +147,9 @@ test('Testing messages', async t => {
146147
})
147148

148149
test('Escaping $f', async t => {
149-
const server = createNode()
150-
const client = createNode()
150+
const serdes = { serialize: m => m, deserialize: m => m }
151+
const server = createNode(serdes)
152+
const client = createNode(serdes)
151153

152154
// server side
153155
server.open(
@@ -294,7 +296,7 @@ test('Limiting remote functions to 0', async t => {
294296
t.is(client.remote_functions.size, 2)
295297

296298
// faking calls
297-
t.is(server.message([111, 0]), true)
298-
t.is(server.message([222, 1]), false)
299-
t.is(client.message([222, 0]), false)
299+
t.is(server.message(JSON.stringify([111, 0])), true)
300+
t.is(server.message(JSON.stringify([222, 1])), false)
301+
t.is(client.message(JSON.stringify([222, 0])), false)
300302
})

0 commit comments

Comments
 (0)