bare-rpc 1.0.0 → 1.2.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/index.d.ts CHANGED
@@ -1,11 +1,5 @@
1
1
  import Buffer, { BufferEncoding } from 'bare-buffer'
2
- import {
3
- Readable,
4
- ReadableOptions,
5
- Writable,
6
- WritableOptions,
7
- Duplex
8
- } from 'bare-stream'
2
+ import { Readable, ReadableOptions, Writable, WritableOptions, Duplex } from 'bare-stream'
9
3
 
10
4
  declare const constants: {
11
5
  type: { REQUEST: 1; RESPONSE: 2; STREAM: 3 }
@@ -23,6 +17,16 @@ declare const constants: {
23
17
  }
24
18
  }
25
19
 
20
+ interface RPCIncomingEvent {
21
+ readonly rpc: RPC
22
+ readonly command: number
23
+ readonly data: Buffer | null
24
+ }
25
+
26
+ declare class RPCIncomingEvent {
27
+ constructor(rpc: RPC, command: number, data: Buffer)
28
+ }
29
+
26
30
  interface RPCIncomingRequest {
27
31
  readonly rpc: RPC
28
32
  readonly id: number
@@ -41,6 +45,18 @@ declare class RPCIncomingRequest {
41
45
  constructor(rpc: RPC, id: number, command: number, data: Buffer)
42
46
  }
43
47
 
48
+ interface RPCOutgoingEvent {
49
+ readonly rpc: RPC
50
+ readonly command: number
51
+ readonly sent: boolean
52
+
53
+ send(data?: Buffer | string | null, encoding?: BufferEncoding): void
54
+ }
55
+
56
+ declare class RPCOutgoingEvent {
57
+ constructor(rpc: RPC, command: number)
58
+ }
59
+
44
60
  interface RPCOutgoingRequest {
45
61
  readonly rpc: RPC
46
62
  readonly id: number
@@ -57,7 +73,7 @@ interface RPCOutgoingRequest {
57
73
  }
58
74
 
59
75
  declare class RPCOutgoingRequest {
60
- constructor(rpc: RPC, command: number)
76
+ constructor(rpc: RPC, id: number, command: number)
61
77
  }
62
78
 
63
79
  declare class RPCIncomingStream extends Readable {
@@ -79,18 +95,18 @@ declare class RPCOutgoingStream extends Writable {
79
95
  }
80
96
 
81
97
  interface RPC {
98
+ event(command: number): RPCOutgoingEvent
82
99
  request(command: number): RPCOutgoingRequest
83
100
  }
84
101
 
85
102
  declare class RPC {
86
- constructor(
87
- stream: Duplex,
88
- onrequest: (req: RPCIncomingRequest) => void | Promise<void>
89
- )
103
+ constructor(stream: Duplex, onrequest: (req: RPCIncomingRequest) => void | Promise<void>)
90
104
  }
91
105
 
92
106
  declare namespace RPC {
93
107
  export {
108
+ type RPCIncomingEvent as IncomingEvent,
109
+ type RPCOutgoingEvent as OutgoingEvent,
94
110
  type RPCIncomingRequest as IncomingRequest,
95
111
  type RPCOutgoingRequest as OutgoingRequest,
96
112
  type RPCIncomingStream as IncomingStream,
package/index.js CHANGED
@@ -3,8 +3,10 @@ const b4a = require('b4a')
3
3
  const c = require('compact-encoding')
4
4
  const m = require('./lib/messages')
5
5
  const { type: t, stream: s } = require('./lib/constants')
6
+ const IncomingEvent = require('./lib/incoming-event')
6
7
  const IncomingRequest = require('./lib/incoming-request')
7
8
  const IncomingStream = require('./lib/incoming-stream')
9
+ const OutgoingEvent = require('./lib/outgoing-event')
8
10
  const OutgoingRequest = require('./lib/outgoing-request')
9
11
  const OutgoingStream = require('./lib/outgoing-stream')
10
12
  const CommandRouter = require('./lib/command-router')
@@ -37,10 +39,11 @@ module.exports = exports = class RPC {
37
39
  this._ondata = this._ondata.bind(this)
38
40
  this._ondrain = this._ondrain.bind(this)
39
41
 
40
- this._stream
41
- .on('error', this._onerror)
42
- .on('data', this._ondata)
43
- .on('drain', this._ondrain)
42
+ this._stream.on('error', this._onerror).on('data', this._ondata).on('drain', this._ondrain)
43
+ }
44
+
45
+ event(command) {
46
+ return new OutgoingEvent(this, command)
44
47
  }
45
48
 
46
49
  request(command) {
@@ -60,6 +63,16 @@ module.exports = exports = class RPC {
60
63
  }
61
64
  }
62
65
 
66
+ _sendEvent(request, data = null) {
67
+ this._sendMessage({
68
+ type: t.REQUEST,
69
+ id: 0,
70
+ command: request.command,
71
+ stream: 0,
72
+ data
73
+ })
74
+ }
75
+
63
76
  _sendRequest(request, data = null) {
64
77
  this._outgoingRequests.set(request.id, request)
65
78
 
@@ -76,25 +89,13 @@ module.exports = exports = class RPC {
76
89
  if (isInitiator) {
77
90
  this._outgoingRequests.set(request.id, request)
78
91
 
79
- request._requestStream = new OutgoingStream(
80
- this,
81
- request,
82
- t.REQUEST,
83
- opts
84
- )
92
+ request._requestStream = new OutgoingStream(this, request, t.REQUEST, opts)
85
93
  } else {
86
94
  this._incomingRequests.set(request.id, request)
87
95
 
88
- request._requestStream = new IncomingStream(
89
- this,
90
- request,
91
- t.REQUEST,
92
- opts
93
- )
96
+ request._requestStream = new IncomingStream(this, request, t.REQUEST, opts)
94
97
 
95
- request._requestStream.on('close', () =>
96
- this._incomingRequests.delete(request.id)
97
- )
98
+ request._requestStream.on('close', () => this._incomingRequests.delete(request.id))
98
99
  }
99
100
  }
100
101
 
@@ -112,25 +113,13 @@ module.exports = exports = class RPC {
112
113
  if (isInitiator) {
113
114
  this._outgoingResponses.set(request.id, request)
114
115
 
115
- request._responseStream = new OutgoingStream(
116
- this,
117
- request,
118
- t.RESPONSE,
119
- opts
120
- )
116
+ request._responseStream = new OutgoingStream(this, request, t.RESPONSE, opts)
121
117
  } else {
122
118
  this._incomingResponses.set(request.id, request)
123
119
 
124
- request._responseStream = new IncomingStream(
125
- this,
126
- request,
127
- t.RESPONSE,
128
- opts
129
- )
120
+ request._responseStream = new IncomingStream(this, request, t.RESPONSE, opts)
130
121
 
131
- request._responseStream.on('close', () =>
132
- this._incomingResponses.delete(request.id)
133
- )
122
+ request._responseStream.on('close', () => this._incomingResponses.delete(request.id))
134
123
  }
135
124
  }
136
125
 
@@ -164,8 +153,7 @@ module.exports = exports = class RPC {
164
153
  _onbeforeframe() {
165
154
  if (this._buffered < 4) return
166
155
 
167
- const buffer =
168
- this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
156
+ const buffer = this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
169
157
 
170
158
  this._buffer = [buffer]
171
159
  this._frame = 4 + c.uint32.decode(c.state(0, 4, buffer))
@@ -176,8 +164,7 @@ module.exports = exports = class RPC {
176
164
  _onafterframe() {
177
165
  if (this._buffered < this._frame) return
178
166
 
179
- const buffer =
180
- this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
167
+ const buffer = this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
181
168
 
182
169
  const frame = this._frame
183
170
 
@@ -201,19 +188,18 @@ module.exports = exports = class RPC {
201
188
 
202
189
  switch (message.type) {
203
190
  case t.REQUEST:
204
- const request = new IncomingRequest(
205
- this,
206
- message.id,
207
- message.command,
208
- message.data
209
- )
191
+ const request =
192
+ message.id === 0
193
+ ? new IncomingEvent(this, message.command, message.data)
194
+ : new IncomingRequest(this, message.id, message.command, message.data)
210
195
 
211
196
  try {
212
197
  await this._onrequest(request)
213
198
  } catch (err) {
214
199
  safetyCatch(err)
215
200
 
216
- this._sendError(request, err)
201
+ if (message.id) this._sendError(request, err)
202
+ else this._stream.destroy(err)
217
203
  }
218
204
  break
219
205
  case t.RESPONSE:
@@ -0,0 +1,7 @@
1
+ module.exports = class RPCIncomingEvent {
2
+ constructor(rpc, command, data) {
3
+ this.rpc = rpc
4
+ this.command = command
5
+ this.data = data
6
+ }
7
+ }
package/lib/messages.js CHANGED
@@ -95,10 +95,7 @@ exports.header = {
95
95
 
96
96
  state.start = frame
97
97
 
98
- c.uint32.encode(
99
- state,
100
- end - start + (hasData && m.data ? m.data.byteLength : 0)
101
- )
98
+ c.uint32.encode(state, end - start + (hasData && m.data ? m.data.byteLength : 0))
102
99
 
103
100
  state.start = end
104
101
  }
@@ -0,0 +1,27 @@
1
+ const c = require('compact-encoding')
2
+ const errors = require('./errors')
3
+
4
+ module.exports = class RPCOutgoingEvent {
5
+ constructor(rpc, command) {
6
+ this.rpc = rpc
7
+ this.command = command
8
+ this.sent = false
9
+ }
10
+
11
+ send(data, encoding) {
12
+ if (this.sent) {
13
+ throw errors.ALREADY_SENT('Event has already been sent')
14
+ }
15
+
16
+ encoding =
17
+ encoding && encoding !== 'buffer'
18
+ ? c.from(encoding)
19
+ : typeof data === 'string'
20
+ ? c.raw.utf8
21
+ : null
22
+
23
+ this.sent = true
24
+
25
+ this.rpc._sendEvent(this, encoding ? c.encode(encoding, data) : data)
26
+ }
27
+ }
@@ -44,9 +44,7 @@ module.exports = class RPCOutgoingRequest {
44
44
 
45
45
  this.received = true
46
46
 
47
- return encoding
48
- ? this._promise.then((data) => c.decode(encoding, data))
49
- : this._promise
47
+ return encoding ? this._promise.then((data) => c.decode(encoding, data)) : this._promise
50
48
  }
51
49
 
52
50
  createRequestStream(opts = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-rpc",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "librpc ABI compatible RPC for Bare",
5
5
  "exports": {
6
6
  ".": {
@@ -11,7 +11,8 @@
11
11
  "./errors": {
12
12
  "types": "./lib/errors.d.ts",
13
13
  "default": "./lib/errors.js"
14
- }
14
+ },
15
+ "./messages": "./lib/messages.js"
15
16
  },
16
17
  "files": [
17
18
  "index.js",
@@ -19,7 +20,8 @@
19
20
  "lib"
20
21
  ],
21
22
  "scripts": {
22
- "test": "prettier . --check && bare test.js"
23
+ "test": "prettier . --check && bare test.js",
24
+ "format": "prettier --write ."
23
25
  },
24
26
  "repository": {
25
27
  "type": "git",
@@ -42,7 +44,7 @@
42
44
  "bare-ipc": "^1.1.0",
43
45
  "brittle": "^3.2.1",
44
46
  "prettier": "^3.4.2",
45
- "prettier-config-standard": "^7.0.0"
47
+ "prettier-config-holepunch": "^2.0.0"
46
48
  },
47
49
  "peerDependencies": {
48
50
  "bare-buffer": "*"