bare-rpc 0.2.7 → 0.2.9

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/README.md CHANGED
@@ -65,7 +65,7 @@ A boolean for whether the request has been sent.
65
65
 
66
66
  A boolean for whether the request has received a reply.
67
67
 
68
- #### `req.send(data[, encoding])`
68
+ #### `req.send([data[, encoding]])`
69
69
 
70
70
  Send the request with the provided `data`. `data` can be a buffer or a string which will be encoded using `encoding`.
71
71
 
@@ -101,7 +101,7 @@ A boolean for whether a reply has been sent.
101
101
 
102
102
  A boolean for whether the request has been received as a stream. See [`req.createRequestStream()`](#const-stream--reqcreaterequeststream) for receiving requests as a stream.
103
103
 
104
- #### `req.reply(data, [encoding])`
104
+ #### `req.reply([data, [encoding]])`
105
105
 
106
106
  Reply to the request with the provided `data`. `data` can be a buffer or a string which will be encoded using `encoding`.
107
107
 
@@ -141,12 +141,12 @@ Define a command and the handler for it. The callback for a command receives bot
141
141
 
142
142
  Options include:
143
143
 
144
- ```
145
- {
144
+ ```js
145
+ options = {
146
146
  // Encoding for incoming request
147
147
  requestEncoding: c.raw,
148
148
  // Encoding for outgoing response
149
- responseEncoding: c.raw,
149
+ responseEncoding: c.raw
150
150
  }
151
151
  ```
152
152
 
package/index.d.ts CHANGED
@@ -27,11 +27,11 @@ interface RPCIncomingRequest {
27
27
  readonly rpc: RPC
28
28
  readonly id: number
29
29
  readonly command: number
30
- readonly data: Buffer
30
+ readonly data: Buffer | null
31
31
  readonly sent: boolean
32
32
  readonly received: boolean
33
33
 
34
- reply(data: Buffer | string, encoding?: BufferEncoding): void
34
+ reply(data?: Buffer | string | null, encoding?: BufferEncoding): void
35
35
 
36
36
  createResponseStream(opts?: WritableOptions): RPCOutgoingStream
37
37
  createRequestStream(opts?: ReadableOptions): RPCIncomingStream
@@ -48,9 +48,9 @@ interface RPCOutgoingRequest {
48
48
  readonly sent: boolean
49
49
  readonly received: boolean
50
50
 
51
- send(data: Buffer | string, encoding?: BufferEncoding): void
51
+ send(data?: Buffer | string | null, encoding?: BufferEncoding): void
52
52
 
53
- reply(encoding?: BufferEncoding): Promise<Buffer | string>
53
+ reply(encoding?: BufferEncoding): Promise<Buffer | string | null>
54
54
 
55
55
  createRequestStream(opts?: WritableOptions): RPCOutgoingStream
56
56
  createResponseStream(opts?: ReadableOptions): RPCIncomingStream
package/index.js CHANGED
@@ -24,6 +24,7 @@ module.exports = exports = class RPC {
24
24
  this._buffer = []
25
25
  this._buffered = 0
26
26
  this._frame = -1
27
+ this._draining = []
27
28
 
28
29
  if (typeof onrequest === 'function') {
29
30
  onrequest = onrequest.bind(this)
@@ -33,20 +34,29 @@ module.exports = exports = class RPC {
33
34
 
34
35
  this._onrequest = onrequest
35
36
  this._ondata = this._ondata.bind(this)
37
+ this._ondrain = this._ondrain.bind(this)
36
38
 
37
- this._stream.on('data', this._ondata)
39
+ this._stream
40
+ .on('error', this._onerror)
41
+ .on('data', this._ondata)
42
+ .on('drain', this._ondrain)
38
43
  }
39
44
 
40
45
  request(command) {
41
46
  return new OutgoingRequest(this, ++this._id, command)
42
47
  }
43
48
 
44
- _sendMessage(message) {
49
+ _sendMessage(message, cb) {
45
50
  const header = c.encode(m.header, message)
46
51
 
47
- this._stream.write(header)
52
+ let flushed = this._stream.write(header)
48
53
 
49
- if (message.data) this._stream.write(message.data)
54
+ if (message.data) flushed = this._stream.write(message.data)
55
+
56
+ if (cb) {
57
+ if (flushed) cb(null)
58
+ else this._draining.push(cb)
59
+ }
50
60
  }
51
61
 
52
62
  _sendRequest(request, data = null) {
@@ -133,6 +143,12 @@ module.exports = exports = class RPC {
133
143
  })
134
144
  }
135
145
 
146
+ _onerror(err) {
147
+ this._ondrain(err)
148
+
149
+ // TODO Destroy pending requests and responses
150
+ }
151
+
136
152
  _ondata(data) {
137
153
  this._buffer.push(data)
138
154
  this._buffered += data.byteLength
@@ -404,6 +420,14 @@ module.exports = exports = class RPC {
404
420
 
405
421
  stream.destroy(message.error)
406
422
  }
423
+
424
+ _ondrain(err = null) {
425
+ const draining = this._draining
426
+
427
+ this._draining = []
428
+
429
+ for (const cb of draining) cb(err)
430
+ }
407
431
  }
408
432
 
409
433
  exports.CommandRouter = CommandRouter
@@ -12,15 +12,16 @@ module.exports = class RPCIncomingStream extends Readable {
12
12
  }
13
13
 
14
14
  _open(cb) {
15
- this._rpc._sendMessage({
16
- type: t.STREAM,
17
- id: this._request.id,
18
- stream: this._mask | s.OPEN,
19
- error: null,
20
- data: null
21
- })
22
-
23
- cb(null)
15
+ this._rpc._sendMessage(
16
+ {
17
+ type: t.STREAM,
18
+ id: this._request.id,
19
+ stream: this._mask | s.OPEN,
20
+ error: null,
21
+ data: null
22
+ },
23
+ cb
24
+ )
24
25
  }
25
26
 
26
27
  _read() {
@@ -35,23 +36,27 @@ module.exports = class RPCIncomingStream extends Readable {
35
36
 
36
37
  _destroy(err, cb) {
37
38
  if (err) {
38
- this._rpc._sendMessage({
39
- type: t.STREAM,
40
- id: this._request.id,
41
- stream: this._mask | s.DESTROY | s.ERROR,
42
- error: err,
43
- data: null
44
- })
39
+ this._rpc._sendMessage(
40
+ {
41
+ type: t.STREAM,
42
+ id: this._request.id,
43
+ stream: this._mask | s.DESTROY | s.ERROR,
44
+ error: err,
45
+ data: null
46
+ },
47
+ cb
48
+ )
45
49
  } else {
46
- this._rpc._sendMessage({
47
- type: t.STREAM,
48
- id: this._request.id,
49
- stream: this._mask | s.DESTROY,
50
- error: null,
51
- data: null
52
- })
50
+ this._rpc._sendMessage(
51
+ {
52
+ type: t.STREAM,
53
+ id: this._request.id,
54
+ stream: this._mask | s.DESTROY,
55
+ error: null,
56
+ data: null
57
+ },
58
+ cb
59
+ )
53
60
  }
54
-
55
- cb(null)
56
61
  }
57
62
  }
package/lib/messages.js CHANGED
@@ -52,7 +52,7 @@ exports.header = {
52
52
  break
53
53
  }
54
54
 
55
- if (hasData) c.uint.preencode(state, m.data.byteLength)
55
+ if (hasData) c.uint.preencode(state, m.data ? m.data.byteLength : 0)
56
56
  },
57
57
  encode(state, m) {
58
58
  const frame = state.start
@@ -89,13 +89,16 @@ exports.header = {
89
89
  break
90
90
  }
91
91
 
92
- if (hasData) c.uint.encode(state, m.data.byteLength)
92
+ if (hasData) c.uint.encode(state, m.data ? m.data.byteLength : 0)
93
93
 
94
94
  const end = state.start
95
95
 
96
96
  state.start = frame
97
97
 
98
- c.uint32.encode(state, end - start + (hasData ? m.data.byteLength : 0))
98
+ c.uint32.encode(
99
+ state,
100
+ end - start + (hasData && m.data ? m.data.byteLength : 0)
101
+ )
99
102
 
100
103
  state.start = end
101
104
  }
@@ -16,39 +16,47 @@ module.exports = class RPCOutgoingStream extends Writable {
16
16
  _open(cb) {
17
17
  let pending
18
18
 
19
+ const onflushed = () => {
20
+ if (pending.has(this._request.id)) {
21
+ pending.delete(this._request.id)
22
+
23
+ cb(null)
24
+ } else {
25
+ this._pendingOpen = cb
26
+ }
27
+ }
28
+
19
29
  switch (this._type) {
20
30
  case t.REQUEST:
21
31
  pending = this._rpc._pendingRequests
22
32
 
23
- this._rpc._sendMessage({
24
- type: t.REQUEST,
25
- id: this._request.id,
26
- command: this._request.command,
27
- stream: s.OPEN,
28
- data: null
29
- })
33
+ this._rpc._sendMessage(
34
+ {
35
+ type: t.REQUEST,
36
+ id: this._request.id,
37
+ command: this._request.command,
38
+ stream: s.OPEN,
39
+ data: null
40
+ },
41
+ onflushed
42
+ )
30
43
  break
31
44
 
32
45
  case t.RESPONSE:
33
46
  pending = this._rpc._pendingResponses
34
47
 
35
- this._rpc._sendMessage({
36
- type: t.RESPONSE,
37
- id: this._request.id,
38
- error: false,
39
- stream: s.OPEN,
40
- data: null
41
- })
48
+ this._rpc._sendMessage(
49
+ {
50
+ type: t.RESPONSE,
51
+ id: this._request.id,
52
+ error: false,
53
+ stream: s.OPEN,
54
+ data: null
55
+ },
56
+ onflushed
57
+ )
42
58
  break
43
59
  }
44
-
45
- if (pending.has(this._request.id)) {
46
- pending.delete(this._request.id)
47
-
48
- cb(null)
49
- } else {
50
- this._pendingOpen = cb
51
- }
52
60
  }
53
61
 
54
62
  _continueOpen() {
@@ -59,48 +67,54 @@ module.exports = class RPCOutgoingStream extends Writable {
59
67
  }
60
68
 
61
69
  _write(data, encoding, cb) {
62
- this._rpc._sendMessage({
63
- type: t.STREAM,
64
- id: this._request.id,
65
- stream: this._mask | s.DATA,
66
- error: null,
67
- data
68
- })
69
-
70
- cb(null)
70
+ this._rpc._sendMessage(
71
+ {
72
+ type: t.STREAM,
73
+ id: this._request.id,
74
+ stream: this._mask | s.DATA,
75
+ error: null,
76
+ data
77
+ },
78
+ cb
79
+ )
71
80
  }
72
81
 
73
82
  _final(cb) {
74
- this._rpc._sendMessage({
75
- type: t.STREAM,
76
- id: this._request.id,
77
- stream: this._mask | s.END,
78
- error: null,
79
- data: null
80
- })
81
-
82
- cb(null)
83
+ this._rpc._sendMessage(
84
+ {
85
+ type: t.STREAM,
86
+ id: this._request.id,
87
+ stream: this._mask | s.END,
88
+ error: null,
89
+ data: null
90
+ },
91
+ cb
92
+ )
83
93
  }
84
94
 
85
95
  _destroy(err, cb) {
86
96
  if (err) {
87
- this._rpc._sendMessage({
88
- type: t.STREAM,
89
- id: this._request.id,
90
- stream: this._mask | s.CLOSE | s.ERROR,
91
- error: err,
92
- data: null
93
- })
97
+ this._rpc._sendMessage(
98
+ {
99
+ type: t.STREAM,
100
+ id: this._request.id,
101
+ stream: this._mask | s.CLOSE | s.ERROR,
102
+ error: err,
103
+ data: null
104
+ },
105
+ cb
106
+ )
94
107
  } else {
95
- this._rpc._sendMessage({
96
- type: t.STREAM,
97
- id: this._request.id,
98
- stream: this._mask | s.CLOSE,
99
- error: null,
100
- data: null
101
- })
108
+ this._rpc._sendMessage(
109
+ {
110
+ type: t.STREAM,
111
+ id: this._request.id,
112
+ stream: this._mask | s.CLOSE,
113
+ error: null,
114
+ data: null
115
+ },
116
+ cb
117
+ )
102
118
  }
103
-
104
- cb(null)
105
119
  }
106
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-rpc",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "librpc ABI compatible RPC for Bare",
5
5
  "exports": {
6
6
  ".": {