bare-rpc 1.3.8 → 1.3.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 +1 -120
- package/index.d.ts +180 -2
- package/index.js +13 -7
- package/lib/messages.js +20 -13
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -29,126 +29,7 @@ console.log(replyBuffer.toString()) // pong
|
|
|
29
29
|
|
|
30
30
|
## API
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
#### `const rpc = new RPC(stream[, onrequest])`
|
|
35
|
-
|
|
36
|
-
Create an RPC instance using a duplex `stream`. `onrequest` is an optional callback run when a remote request is received. This is where processing and responding to an RPC request happens. `onrequest` receives a `RPCIncomingRequest` as an argument, for example:
|
|
37
|
-
|
|
38
|
-
```js
|
|
39
|
-
const rpc = new RPC(stream, (req) => {
|
|
40
|
-
if (req.command === 42) {
|
|
41
|
-
req.reply('pong')
|
|
42
|
-
}
|
|
43
|
-
})
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
See [`RPCIncomingRequest`](#rpcincomingrequest) for properties and methods for processing the request.
|
|
47
|
-
|
|
48
|
-
`onrequest` can also be a [`RPCCommandRouter`](#rpccommandrouter).
|
|
49
|
-
|
|
50
|
-
#### `const req = rpc.request(command)`
|
|
51
|
-
|
|
52
|
-
Create a request for `command`. `command` is a unique number that should be used to differentiate different requests on the remote end. Returns a `RPCOutgoingRequest`.
|
|
53
|
-
|
|
54
|
-
### `RPCOutgoingRequest`
|
|
55
|
-
|
|
56
|
-
#### `req.command`
|
|
57
|
-
|
|
58
|
-
The command that the request was created with. A command is a unique number.
|
|
59
|
-
|
|
60
|
-
#### `req.sent`
|
|
61
|
-
|
|
62
|
-
A boolean for whether the request has been sent.
|
|
63
|
-
|
|
64
|
-
#### `req.received`
|
|
65
|
-
|
|
66
|
-
A boolean for whether the request has received a reply.
|
|
67
|
-
|
|
68
|
-
#### `req.send([data[, encoding]])`
|
|
69
|
-
|
|
70
|
-
Send the request with the provided `data`. `data` can be a buffer or a string which will be encoded using `encoding`.
|
|
71
|
-
|
|
72
|
-
`.send()` can only be called once per request.
|
|
73
|
-
|
|
74
|
-
#### `const data = await req.reply([encoding])`
|
|
75
|
-
|
|
76
|
-
Await the reply from the remote end to the request. `encoding` can be defined for decoding the response `data` buffer back into a string.
|
|
77
|
-
|
|
78
|
-
#### `const stream = req.createRequestStream([options])`
|
|
79
|
-
|
|
80
|
-
Create a [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream for sending data with the request.
|
|
81
|
-
|
|
82
|
-
#### `const stream = req.createResponseStream([options])`
|
|
83
|
-
|
|
84
|
-
Create a [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream for receiving data in reply to the request.
|
|
85
|
-
|
|
86
|
-
### `RPCIncomingRequest`
|
|
87
|
-
|
|
88
|
-
#### `req.command`
|
|
89
|
-
|
|
90
|
-
The command that the request was sent as. A command is a unique number.
|
|
91
|
-
|
|
92
|
-
#### `req.data`
|
|
93
|
-
|
|
94
|
-
The data buffer sent with the request.
|
|
95
|
-
|
|
96
|
-
#### `req.sent`
|
|
97
|
-
|
|
98
|
-
A boolean for whether a reply has been sent.
|
|
99
|
-
|
|
100
|
-
#### `req.received`
|
|
101
|
-
|
|
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
|
-
|
|
104
|
-
#### `req.reply([data, [encoding]])`
|
|
105
|
-
|
|
106
|
-
Reply to the request with the provided `data`. `data` can be a buffer or a string which will be encoded using `encoding`.
|
|
107
|
-
|
|
108
|
-
#### `const stream = req.createRequestStream([options])`
|
|
109
|
-
|
|
110
|
-
Create a `Readable` stream for receiving data from the request.
|
|
111
|
-
|
|
112
|
-
#### `const stream = req.createResponseStream([options])`
|
|
113
|
-
|
|
114
|
-
Create a `Writable` stream for sending data in reply to the request.
|
|
115
|
-
|
|
116
|
-
### `RPCCommandRouter`
|
|
117
|
-
|
|
118
|
-
An alternative way to define commands and handlers for receiving them.
|
|
119
|
-
|
|
120
|
-
#### `const router = new RPC.CommandRouter()`
|
|
121
|
-
|
|
122
|
-
Create a new command router. This router can then be used when creating an `rpc`. For example:
|
|
123
|
-
|
|
124
|
-
```js
|
|
125
|
-
const router = new RPC.CommandRouter()
|
|
126
|
-
|
|
127
|
-
router.respond(42, (req, data) => {
|
|
128
|
-
console.log(data.toString()) // ping
|
|
129
|
-
|
|
130
|
-
return Buffer.from('pong')
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
const rpc = new RPC(stream, router)
|
|
134
|
-
const req = rpc.request(42)
|
|
135
|
-
req.send('ping')
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
#### `router.respond(command[, options], async (req, data) => {})`
|
|
139
|
-
|
|
140
|
-
Define a command and the handler for it. The callback for a command receives both the request (`req`) and the `data` buffer and can return a value to respond. If the request is responded to in the callback, the return value is ignored.
|
|
141
|
-
|
|
142
|
-
Options include:
|
|
143
|
-
|
|
144
|
-
```js
|
|
145
|
-
options = {
|
|
146
|
-
// Encoding for incoming request
|
|
147
|
-
requestEncoding: c.raw,
|
|
148
|
-
// Encoding for outgoing response
|
|
149
|
-
responseEncoding: c.raw
|
|
150
|
-
}
|
|
151
|
-
```
|
|
32
|
+
See the [`bare-rpc` reference](https://docs.pears.com/reference/bare/modules/bare-rpc).
|
|
152
33
|
|
|
153
34
|
## License
|
|
154
35
|
|
package/index.d.ts
CHANGED
|
@@ -19,11 +19,18 @@ declare const constants: {
|
|
|
19
19
|
|
|
20
20
|
interface RPCIncomingEvent {
|
|
21
21
|
readonly rpc: RPC
|
|
22
|
+
/** The command that the request was created with. A command is a unique number. */
|
|
22
23
|
readonly command: number
|
|
24
|
+
/** The data buffer sent with the request. */
|
|
23
25
|
readonly data: Buffer | null
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
declare class RPCIncomingEvent {
|
|
29
|
+
/**
|
|
30
|
+
* @param rpc - The `RPC` instance the event arrived on.
|
|
31
|
+
* @param command - The command number the event was sent with.
|
|
32
|
+
* @param data - The payload buffer sent with the event.
|
|
33
|
+
*/
|
|
27
34
|
constructor(rpc: RPC, command: number, data: Buffer)
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -32,16 +39,45 @@ interface RPCIncomingRequest {
|
|
|
32
39
|
readonly id: number
|
|
33
40
|
readonly command: number
|
|
34
41
|
readonly data: Buffer | null
|
|
42
|
+
/** A boolean for whether the request has been sent. */
|
|
35
43
|
readonly sent: boolean
|
|
44
|
+
/** A boolean for whether the request has received a reply. */
|
|
36
45
|
readonly received: boolean
|
|
37
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Send a reply to the request. `data` may be a buffer or a string encoded using `encoding`.
|
|
49
|
+
* @param data - The payload to send: a `Buffer`, or a string encoded using `encoding`. Omit to
|
|
50
|
+
* send no data.
|
|
51
|
+
* @param encoding - The encoding used when `data` is a string (defaults to `utf8`).
|
|
52
|
+
* @throws {ALREADY_SENT} a response has already been sent for this request.
|
|
53
|
+
*/
|
|
38
54
|
reply(data?: Buffer | string | null, encoding?: BufferEncoding): void
|
|
39
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Create a [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream for sending
|
|
58
|
+
* the streamed reply to the request.
|
|
59
|
+
* @param opts - Options for the returned
|
|
60
|
+
* [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream.
|
|
61
|
+
* @throws {ALREADY_SENT} a response has already been sent for this request.
|
|
62
|
+
*/
|
|
40
63
|
createResponseStream(opts?: WritableOptions): RPCOutgoingStream
|
|
64
|
+
/**
|
|
65
|
+
* Create a [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream for
|
|
66
|
+
* receiving the request's streamed data.
|
|
67
|
+
* @param opts - Options for the returned
|
|
68
|
+
* [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream.
|
|
69
|
+
* @throws {ALREADY_RECEIVED} the request has already been received.
|
|
70
|
+
*/
|
|
41
71
|
createRequestStream(opts?: ReadableOptions): RPCIncomingStream
|
|
42
72
|
}
|
|
43
73
|
|
|
44
74
|
declare class RPCIncomingRequest {
|
|
75
|
+
/**
|
|
76
|
+
* @param rpc - The `RPC` instance the request arrived on.
|
|
77
|
+
* @param id - The request id, used to correlate the reply with the request.
|
|
78
|
+
* @param command - The command number the request was sent with.
|
|
79
|
+
* @param data - The payload buffer sent with the request.
|
|
80
|
+
*/
|
|
45
81
|
constructor(rpc: RPC, id: number, command: number, data: Buffer)
|
|
46
82
|
}
|
|
47
83
|
|
|
@@ -50,10 +86,20 @@ interface RPCOutgoingEvent {
|
|
|
50
86
|
readonly command: number
|
|
51
87
|
readonly sent: boolean
|
|
52
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @param data - The payload to send: a `Buffer`, or a string encoded using `encoding`. Omit to
|
|
91
|
+
* send no data.
|
|
92
|
+
* @param encoding - The encoding used when `data` is a string (defaults to `utf8`).
|
|
93
|
+
* @throws {ALREADY_SENT} the event has already been sent.
|
|
94
|
+
*/
|
|
53
95
|
send(data?: Buffer | string | null, encoding?: BufferEncoding): void
|
|
54
96
|
}
|
|
55
97
|
|
|
56
98
|
declare class RPCOutgoingEvent {
|
|
99
|
+
/**
|
|
100
|
+
* @param rpc - The `RPC` instance to send the event on.
|
|
101
|
+
* @param command - The command number to send.
|
|
102
|
+
*/
|
|
57
103
|
constructor(rpc: RPC, command: number)
|
|
58
104
|
}
|
|
59
105
|
|
|
@@ -64,19 +110,61 @@ interface RPCOutgoingRequest {
|
|
|
64
110
|
readonly sent: boolean
|
|
65
111
|
readonly received: boolean
|
|
66
112
|
|
|
113
|
+
/**
|
|
114
|
+
* @param data - The payload to send: a `Buffer`, or a string encoded using `encoding`. Omit to
|
|
115
|
+
* send no data.
|
|
116
|
+
* @param encoding - The encoding used when `data` is a string (defaults to `utf8`).
|
|
117
|
+
* @throws {ALREADY_SENT} the request has already been sent.
|
|
118
|
+
*/
|
|
67
119
|
send(data?: Buffer | string | null, encoding?: BufferEncoding): void
|
|
68
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Await the reply from the remote end to the request. `encoding` can be defined for decoding the
|
|
123
|
+
* response `data` buffer back into a string.
|
|
124
|
+
* @param encoding - If given, decodes the reply payload to a string using this encoding; omit to
|
|
125
|
+
* receive the raw `Buffer`.
|
|
126
|
+
* @returns a promise that resolves with the remote end's reply payload, or rejects with the
|
|
127
|
+
* channel's teardown error if it closes before a reply arrives.
|
|
128
|
+
* @throws {ALREADY_RECEIVED} a reply is already being received for this request.
|
|
129
|
+
*/
|
|
69
130
|
reply(encoding?: BufferEncoding): Promise<Buffer | string | null>
|
|
70
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Create a [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream for sending
|
|
134
|
+
* data with the request.
|
|
135
|
+
* @param opts - Options for the returned
|
|
136
|
+
* [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream.
|
|
137
|
+
* @throws {ALREADY_SENT} the request has already been sent.
|
|
138
|
+
*/
|
|
71
139
|
createRequestStream(opts?: WritableOptions): RPCOutgoingStream
|
|
140
|
+
/**
|
|
141
|
+
* Create a [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream for
|
|
142
|
+
* receiving data in reply to the request.
|
|
143
|
+
* @param opts - Options for the returned
|
|
144
|
+
* [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream.
|
|
145
|
+
* @throws {ALREADY_RECEIVED} the response has already been received.
|
|
146
|
+
*/
|
|
72
147
|
createResponseStream(opts?: ReadableOptions): RPCIncomingStream
|
|
73
148
|
}
|
|
74
149
|
|
|
75
150
|
declare class RPCOutgoingRequest {
|
|
151
|
+
/**
|
|
152
|
+
* @param rpc - The `RPC` instance to send the request on.
|
|
153
|
+
* @param id - The request id, used to correlate the reply with the request.
|
|
154
|
+
* @param command - The command number to send.
|
|
155
|
+
*/
|
|
76
156
|
constructor(rpc: RPC, id: number, command: number)
|
|
77
157
|
}
|
|
78
158
|
|
|
79
159
|
declare class RPCIncomingStream extends Readable {
|
|
160
|
+
/**
|
|
161
|
+
* @param rpc - The `RPC` instance the stream belongs to.
|
|
162
|
+
* @param request - The request the stream carries data for.
|
|
163
|
+
* @param type - Whether the stream carries the request body (`constants.type.REQUEST`) or the
|
|
164
|
+
* response body (`constants.type.RESPONSE`).
|
|
165
|
+
* @param opts - Options for the underlying
|
|
166
|
+
* [`Readable`](https://github.com/mafintosh/streamx#readable-stream) stream.
|
|
167
|
+
*/
|
|
80
168
|
constructor(
|
|
81
169
|
rpc: RPC,
|
|
82
170
|
request: RPCIncomingRequest | RPCOutgoingRequest,
|
|
@@ -86,6 +174,14 @@ declare class RPCIncomingStream extends Readable {
|
|
|
86
174
|
}
|
|
87
175
|
|
|
88
176
|
declare class RPCOutgoingStream extends Writable {
|
|
177
|
+
/**
|
|
178
|
+
* @param rpc - The `RPC` instance the stream belongs to.
|
|
179
|
+
* @param request - The request the stream carries data for.
|
|
180
|
+
* @param type - Whether the stream carries the request body (`constants.type.REQUEST`) or the
|
|
181
|
+
* response body (`constants.type.RESPONSE`).
|
|
182
|
+
* @param opts - Options for the underlying
|
|
183
|
+
* [`Writable`](https://github.com/mafintosh/streamx#writable-stream) stream.
|
|
184
|
+
*/
|
|
89
185
|
constructor(
|
|
90
186
|
rpc: RPC,
|
|
91
187
|
request: RPCIncomingRequest | RPCOutgoingRequest,
|
|
@@ -94,17 +190,94 @@ declare class RPCOutgoingStream extends Writable {
|
|
|
94
190
|
)
|
|
95
191
|
}
|
|
96
192
|
|
|
193
|
+
/** A [`compact-encoding`](https://github.com/holepunchto/compact-encoding) encoding, such as `c.raw`. */
|
|
194
|
+
interface RPCValueEncoding {
|
|
195
|
+
preencode(state: unknown, value: unknown): void
|
|
196
|
+
encode(state: unknown, value: unknown): void
|
|
197
|
+
decode(state: unknown): unknown
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface RPCCommandRouterOptions {
|
|
201
|
+
/** The encoding of request and response data for commands that set none (defaults to `c.raw`). */
|
|
202
|
+
valueEncoding?: RPCValueEncoding
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface RPCRespondOptions {
|
|
206
|
+
/** The encoding of both the request and the response data. */
|
|
207
|
+
valueEncoding?: RPCValueEncoding
|
|
208
|
+
/** The encoding to decode the request data with, or `null` to pass the raw buffer. */
|
|
209
|
+
requestEncoding?: RPCValueEncoding | null
|
|
210
|
+
/** The encoding to encode the response data with, or `null` to reply with the value as is. */
|
|
211
|
+
responseEncoding?: RPCValueEncoding | null
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param req - The incoming request.
|
|
216
|
+
* @param data - The request data, decoded with the request encoding of the command.
|
|
217
|
+
* @returns the response data, encoded with the response encoding of the command and sent as the
|
|
218
|
+
* reply unless the handler has already replied.
|
|
219
|
+
*/
|
|
220
|
+
type RPCRequestHandler = (req: RPCIncomingRequest, data: any) => unknown
|
|
221
|
+
|
|
222
|
+
interface RPCCommandRouter {
|
|
223
|
+
/**
|
|
224
|
+
* Answer requests for `command` with `onrequest`, in place of any handler registered before.
|
|
225
|
+
* @param command - The command number to answer.
|
|
226
|
+
* @param opts - The encodings of the command.
|
|
227
|
+
* @param onrequest - The handler of the requests.
|
|
228
|
+
*/
|
|
229
|
+
respond(command: number, onrequest: RPCRequestHandler): void
|
|
230
|
+
respond(command: number, opts: RPCRespondOptions, onrequest: RPCRequestHandler): void
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
declare class RPCCommandRouter {
|
|
234
|
+
/**
|
|
235
|
+
* @param opts - The default encodings of the commands.
|
|
236
|
+
*/
|
|
237
|
+
constructor(opts?: RPCCommandRouterOptions)
|
|
238
|
+
}
|
|
239
|
+
|
|
97
240
|
interface RPC {
|
|
241
|
+
/**
|
|
242
|
+
* Whether there are no requests or responses currently in flight. Useful for determining when it
|
|
243
|
+
* is safe to tear down the underlying stream.
|
|
244
|
+
*/
|
|
98
245
|
readonly idle: boolean
|
|
99
246
|
|
|
247
|
+
/**
|
|
248
|
+
* @param command - A unique number identifying the event; the remote end differentiates events by
|
|
249
|
+
* it.
|
|
250
|
+
* @returns an `RPCOutgoingEvent`; call `send()` on it to dispatch the one-way event.
|
|
251
|
+
*/
|
|
100
252
|
event(command: number): RPCOutgoingEvent
|
|
253
|
+
/**
|
|
254
|
+
* @param command - A unique number identifying the request; the remote end differentiates
|
|
255
|
+
* requests by it.
|
|
256
|
+
* @returns an `RPCOutgoingRequest`; call `send()` on it to dispatch the request and `await
|
|
257
|
+
* reply()` for the response.
|
|
258
|
+
*/
|
|
101
259
|
request(command: number): RPCOutgoingRequest
|
|
102
260
|
}
|
|
103
261
|
|
|
104
262
|
declare class RPC {
|
|
105
|
-
|
|
263
|
+
/**
|
|
264
|
+
* @param stream - The duplex stream to frame RPC messages over, such as a pipe or socket.
|
|
265
|
+
* @param onrequest - Callback run for each incoming request or event, receiving an
|
|
266
|
+
* `RPCIncomingRequest` (or `RPCIncomingEvent`) to inspect and `reply()` to, or an
|
|
267
|
+
* `RPCCommandRouter` that answers each request with the handler of its command. Defaults to a
|
|
268
|
+
* no-op.
|
|
269
|
+
*/
|
|
270
|
+
constructor(
|
|
271
|
+
stream: Duplex,
|
|
272
|
+
onrequest?: ((req: RPCIncomingRequest) => void | Promise<void>) | RPCCommandRouter
|
|
273
|
+
)
|
|
106
274
|
}
|
|
107
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Create an RPC instance using a duplex `stream`. `onrequest` is an optional callback run when a
|
|
278
|
+
* remote request is received. This is where processing and responding to an RPC request happens.
|
|
279
|
+
* `onrequest` receives a `RPCIncomingRequest` as an argument.
|
|
280
|
+
*/
|
|
108
281
|
declare namespace RPC {
|
|
109
282
|
export {
|
|
110
283
|
type RPCIncomingEvent as IncomingEvent,
|
|
@@ -112,7 +285,12 @@ declare namespace RPC {
|
|
|
112
285
|
type RPCIncomingRequest as IncomingRequest,
|
|
113
286
|
type RPCOutgoingRequest as OutgoingRequest,
|
|
114
287
|
type RPCIncomingStream as IncomingStream,
|
|
115
|
-
type RPCOutgoingStream as OutgoingStream
|
|
288
|
+
type RPCOutgoingStream as OutgoingStream,
|
|
289
|
+
RPCCommandRouter as CommandRouter,
|
|
290
|
+
type RPCCommandRouterOptions as CommandRouterOptions,
|
|
291
|
+
type RPCRespondOptions as RespondOptions,
|
|
292
|
+
type RPCRequestHandler as RequestHandler,
|
|
293
|
+
type RPCValueEncoding as ValueEncoding
|
|
116
294
|
}
|
|
117
295
|
}
|
|
118
296
|
|
package/index.js
CHANGED
|
@@ -85,7 +85,7 @@ module.exports = exports = class RPC {
|
|
|
85
85
|
|
|
86
86
|
let flushed = this._stream.write(header)
|
|
87
87
|
|
|
88
|
-
if (message.data) flushed = this._stream.write(message.data)
|
|
88
|
+
if (message.data && m.hasData(message)) flushed = this._stream.write(message.data)
|
|
89
89
|
|
|
90
90
|
if (cb) {
|
|
91
91
|
if (flushed) cb(null)
|
|
@@ -273,19 +273,26 @@ module.exports = exports = class RPC {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
_onbeforeframe() {
|
|
276
|
-
|
|
276
|
+
while (this._buffered >= 4) {
|
|
277
|
+
const buffer = this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
|
|
277
278
|
|
|
278
|
-
|
|
279
|
+
this._buffer = [buffer]
|
|
280
|
+
this._frame = 4 + c.uint32.decode(c.state(0, 4, buffer))
|
|
279
281
|
|
|
280
|
-
|
|
281
|
-
this._frame = 4 + c.uint32.decode(c.state(0, 4, buffer))
|
|
282
|
+
if (this._buffered < this._frame) return
|
|
282
283
|
|
|
283
|
-
|
|
284
|
+
this._onframe()
|
|
285
|
+
}
|
|
284
286
|
}
|
|
285
287
|
|
|
286
288
|
_onafterframe() {
|
|
287
289
|
if (this._buffered < this._frame) return
|
|
288
290
|
|
|
291
|
+
this._onframe()
|
|
292
|
+
this._onbeforeframe()
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
_onframe() {
|
|
289
296
|
const buffer = this._buffer.length === 1 ? this._buffer[0] : b4a.concat(this._buffer)
|
|
290
297
|
|
|
291
298
|
const frame = this._frame
|
|
@@ -295,7 +302,6 @@ module.exports = exports = class RPC {
|
|
|
295
302
|
this._frame = -1
|
|
296
303
|
|
|
297
304
|
this._onmessage(buffer.subarray(0, frame))
|
|
298
|
-
this._onbeforeframe()
|
|
299
305
|
}
|
|
300
306
|
|
|
301
307
|
async _onmessage(buffer) {
|
package/lib/messages.js
CHANGED
|
@@ -21,19 +21,31 @@ const error = {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function hasData(m) {
|
|
25
|
+
switch (m.type) {
|
|
26
|
+
case t.REQUEST:
|
|
27
|
+
return m.stream === 0
|
|
28
|
+
case t.RESPONSE:
|
|
29
|
+
return !m.error && m.stream === 0
|
|
30
|
+
case t.STREAM:
|
|
31
|
+
return (m.stream & s.ERROR) === 0 && (m.stream & s.DATA) !== 0
|
|
32
|
+
default:
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.hasData = hasData
|
|
38
|
+
|
|
24
39
|
exports.header = {
|
|
25
40
|
preencode(state, m) {
|
|
26
41
|
c.uint32.preencode(state, 0) // Frame
|
|
27
42
|
c.uint.preencode(state, m.type)
|
|
28
43
|
c.uint.preencode(state, m.id)
|
|
29
44
|
|
|
30
|
-
let hasData = false
|
|
31
|
-
|
|
32
45
|
switch (m.type) {
|
|
33
46
|
case t.REQUEST:
|
|
34
47
|
c.uint.preencode(state, m.command)
|
|
35
48
|
c.uint.preencode(state, m.stream)
|
|
36
|
-
if (m.stream === 0) hasData = true
|
|
37
49
|
break
|
|
38
50
|
|
|
39
51
|
case t.RESPONSE:
|
|
@@ -41,18 +53,16 @@ exports.header = {
|
|
|
41
53
|
c.uint.preencode(state, m.stream)
|
|
42
54
|
|
|
43
55
|
if (m.error) error.preencode(state, m.error)
|
|
44
|
-
else if (m.stream === 0) hasData = true
|
|
45
56
|
break
|
|
46
57
|
|
|
47
58
|
case t.STREAM:
|
|
48
59
|
c.uint.preencode(state, m.stream)
|
|
49
60
|
|
|
50
61
|
if (m.stream & s.ERROR) error.preencode(state, m.error)
|
|
51
|
-
else if (m.stream & s.DATA) hasData = true
|
|
52
62
|
break
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
if (hasData) c.uint.preencode(state, m.data ? m.data.byteLength : 0)
|
|
65
|
+
if (hasData(m)) c.uint.preencode(state, m.data ? m.data.byteLength : 0)
|
|
56
66
|
},
|
|
57
67
|
encode(state, m) {
|
|
58
68
|
const frame = state.start
|
|
@@ -64,13 +74,10 @@ exports.header = {
|
|
|
64
74
|
c.uint.encode(state, m.type)
|
|
65
75
|
c.uint.encode(state, m.id)
|
|
66
76
|
|
|
67
|
-
let hasData = false
|
|
68
|
-
|
|
69
77
|
switch (m.type) {
|
|
70
78
|
case t.REQUEST:
|
|
71
79
|
c.uint.encode(state, m.command)
|
|
72
80
|
c.uint.encode(state, m.stream)
|
|
73
|
-
if (m.stream === 0) hasData = true
|
|
74
81
|
break
|
|
75
82
|
|
|
76
83
|
case t.RESPONSE:
|
|
@@ -78,24 +85,24 @@ exports.header = {
|
|
|
78
85
|
c.uint.encode(state, m.stream)
|
|
79
86
|
|
|
80
87
|
if (m.error) error.encode(state, m.error)
|
|
81
|
-
else if (m.stream === 0) hasData = true
|
|
82
88
|
break
|
|
83
89
|
|
|
84
90
|
case t.STREAM:
|
|
85
91
|
c.uint.encode(state, m.stream)
|
|
86
92
|
|
|
87
93
|
if (m.stream & s.ERROR) error.encode(state, m.error)
|
|
88
|
-
else if (m.stream & s.DATA) hasData = true
|
|
89
94
|
break
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
|
|
97
|
+
const data = hasData(m)
|
|
98
|
+
|
|
99
|
+
if (data) c.uint.encode(state, m.data ? m.data.byteLength : 0)
|
|
93
100
|
|
|
94
101
|
const end = state.start
|
|
95
102
|
|
|
96
103
|
state.start = frame
|
|
97
104
|
|
|
98
|
-
c.uint32.encode(state, end - start + (
|
|
105
|
+
c.uint32.encode(state, end - start + (data && m.data ? m.data.byteLength : 0))
|
|
99
106
|
|
|
100
107
|
state.start = end
|
|
101
108
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-rpc",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
4
4
|
"description": "librpc ABI compatible RPC for Bare",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"bare-buffer": "^3.0.1",
|
|
46
46
|
"bare-ipc": "^1.1.0",
|
|
47
|
+
"bare-rpc-test": "^0.1.0",
|
|
47
48
|
"brittle": "^3.2.1",
|
|
48
49
|
"lunte": "^1.7.0",
|
|
49
50
|
"prettier": "^3.4.2",
|