bare-rpc 0.1.1 → 0.1.3
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 +82 -0
- package/index.js +112 -68
- package/lib/errors.d.ts +6 -0
- package/lib/errors.js +4 -4
- package/lib/incoming-request.js +12 -7
- package/lib/incoming-stream.js +4 -4
- package/lib/messages.js +21 -18
- package/lib/outgoing-request.js +19 -10
- package/lib/outgoing-stream.js +19 -7
- package/package.json +22 -5
package/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import Buffer, { BufferEncoding } from 'bare-buffer'
|
|
2
|
+
import {
|
|
3
|
+
Readable,
|
|
4
|
+
ReadableOptions,
|
|
5
|
+
Writable,
|
|
6
|
+
WritableOptions,
|
|
7
|
+
PassThrough
|
|
8
|
+
} from 'bare-stream'
|
|
9
|
+
|
|
10
|
+
declare const constants: {
|
|
11
|
+
type: { REQUEST: 1; RESPONSE: 2; STREAM: 3 }
|
|
12
|
+
stream: {
|
|
13
|
+
OPEN: number
|
|
14
|
+
CLOSE: number
|
|
15
|
+
PAUSE: number
|
|
16
|
+
RESUME: number
|
|
17
|
+
DATA: number
|
|
18
|
+
END: number
|
|
19
|
+
DESTROY: number
|
|
20
|
+
ERROR: number
|
|
21
|
+
REQUEST: number
|
|
22
|
+
RESPONSE: number
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface RPCIncomingRequest {
|
|
27
|
+
rpc: RPC
|
|
28
|
+
id: number
|
|
29
|
+
command: string
|
|
30
|
+
data: Buffer
|
|
31
|
+
sent: boolean
|
|
32
|
+
|
|
33
|
+
reply(data: Buffer | string, encoding?: BufferEncoding): void
|
|
34
|
+
|
|
35
|
+
createResponseStream(opts?: WritableOptions): RPCOutgoingStream
|
|
36
|
+
createRequestStream(opts?: ReadableOptions): RPCIncomingStream
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare class RPCIncomingRequest {
|
|
40
|
+
constructor(rpc: RPC, id: number, command: string, data: Buffer)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface RPCOutgoingRequest {
|
|
44
|
+
send(data: Buffer | string, encoding?: BufferEncoding): void
|
|
45
|
+
|
|
46
|
+
reply(encoding?: BufferEncoding): Promise<Buffer>
|
|
47
|
+
|
|
48
|
+
createRequestStream(opts?: WritableOptions): RPCOutgoingStream
|
|
49
|
+
createResponseStream(opts?: ReadableOptions): RPCIncomingStream
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
declare class RPCOutgoingRequest {
|
|
53
|
+
constructor(rpc: RPC, command: string)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare class RPCIncomingStream extends Readable {
|
|
57
|
+
constructor(
|
|
58
|
+
rpc: RPC,
|
|
59
|
+
request: RPCIncomingRequest | RPCOutgoingRequest,
|
|
60
|
+
type: typeof constants.type.REQUEST | typeof constants.type.RESPONSE,
|
|
61
|
+
opts?: ReadableOptions
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class RPCOutgoingStream extends Writable {
|
|
66
|
+
constructor(
|
|
67
|
+
rpc: RPC,
|
|
68
|
+
request: RPCIncomingRequest | RPCOutgoingRequest,
|
|
69
|
+
type: typeof constants.type.REQUEST | typeof constants.type.RESPONSE,
|
|
70
|
+
opts?: WritableOptions
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface RPC {
|
|
75
|
+
request(command: string): RPCOutgoingRequest
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare class RPC {
|
|
79
|
+
constructor(stream: PassThrough, onrequest: (req: RPCIncomingRequest) => void)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export = RPC
|
package/index.js
CHANGED
|
@@ -9,62 +9,73 @@ const OutgoingRequest = require('./lib/outgoing-request')
|
|
|
9
9
|
const OutgoingStream = require('./lib/outgoing-stream')
|
|
10
10
|
|
|
11
11
|
module.exports = class RPC {
|
|
12
|
-
constructor
|
|
12
|
+
constructor(stream, onrequest) {
|
|
13
13
|
this._stream = stream
|
|
14
14
|
|
|
15
15
|
this._id = 0
|
|
16
|
-
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
16
|
+
|
|
17
|
+
this._outgoingRequests = new Map()
|
|
18
|
+
this._outgoingResponses = new Map()
|
|
19
|
+
this._incomingRequests = new Map()
|
|
20
|
+
this._incomingResponses = new Map()
|
|
21
|
+
this._pendingRequests = new Set()
|
|
22
|
+
this._pendingResponses = new Set()
|
|
19
23
|
|
|
20
24
|
this._buffer = null
|
|
21
25
|
|
|
22
26
|
this._onrequest = onrequest.bind(this)
|
|
23
27
|
this._ondata = this._ondata.bind(this)
|
|
24
28
|
|
|
25
|
-
this._stream
|
|
26
|
-
.on('data', this._ondata)
|
|
29
|
+
this._stream.on('data', this._ondata)
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
request
|
|
30
|
-
return new OutgoingRequest(this, command)
|
|
32
|
+
request(command) {
|
|
33
|
+
return new OutgoingRequest(++this._id, this, command)
|
|
31
34
|
}
|
|
32
35
|
|
|
33
|
-
_sendMessage
|
|
36
|
+
_sendMessage(message) {
|
|
34
37
|
this._stream.write(c.encode(m.message, message))
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
_sendRequest
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this._requests.set(id, request)
|
|
40
|
+
_sendRequest(request, data = null) {
|
|
41
|
+
this._outgoingRequests.set(request.id, request)
|
|
41
42
|
|
|
42
43
|
this._sendMessage({
|
|
43
44
|
type: t.REQUEST,
|
|
44
|
-
id,
|
|
45
|
+
id: request.id,
|
|
45
46
|
command: request.command,
|
|
46
47
|
stream: 0,
|
|
47
48
|
data
|
|
48
49
|
})
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
_createRequestStream
|
|
52
|
+
_createRequestStream(request, isInitiator, opts) {
|
|
52
53
|
if (isInitiator) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
this._outgoingRequests.set(request.id, request)
|
|
55
|
+
|
|
56
|
+
request._requestStream = new OutgoingStream(
|
|
57
|
+
this,
|
|
58
|
+
request,
|
|
59
|
+
t.REQUEST,
|
|
60
|
+
opts
|
|
61
|
+
)
|
|
58
62
|
} else {
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
this._incomingRequests.set(request.id, request)
|
|
64
|
+
|
|
65
|
+
request._requestStream = new IncomingStream(
|
|
66
|
+
this,
|
|
67
|
+
request,
|
|
68
|
+
t.REQUEST,
|
|
69
|
+
opts
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
request._requestStream.on('close', () =>
|
|
73
|
+
this._incomingRequests.delete(request.id)
|
|
74
|
+
)
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
_sendResponse
|
|
78
|
+
_sendResponse(request, data) {
|
|
68
79
|
this._sendMessage({
|
|
69
80
|
type: t.RESPONSE,
|
|
70
81
|
id: request.id,
|
|
@@ -74,21 +85,33 @@ module.exports = class RPC {
|
|
|
74
85
|
})
|
|
75
86
|
}
|
|
76
87
|
|
|
77
|
-
_createResponseStream
|
|
88
|
+
_createResponseStream(request, isInitiator, opts) {
|
|
78
89
|
if (isInitiator) {
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
request._responseStream = new OutgoingStream(
|
|
90
|
+
this._outgoingResponses.set(request.id, request)
|
|
91
|
+
|
|
92
|
+
request._responseStream = new OutgoingStream(
|
|
93
|
+
this,
|
|
94
|
+
request,
|
|
95
|
+
t.RESPONSE,
|
|
96
|
+
opts
|
|
97
|
+
)
|
|
82
98
|
} else {
|
|
83
|
-
this.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
this._incomingResponses.set(request.id, request)
|
|
100
|
+
|
|
101
|
+
request._responseStream = new IncomingStream(
|
|
102
|
+
this,
|
|
103
|
+
request,
|
|
104
|
+
t.RESPONSE,
|
|
105
|
+
opts
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
request._responseStream.on('close', () =>
|
|
109
|
+
this._incomingResponses.delete(request.id)
|
|
110
|
+
)
|
|
88
111
|
}
|
|
89
112
|
}
|
|
90
113
|
|
|
91
|
-
_sendError
|
|
114
|
+
_sendError(request, err) {
|
|
92
115
|
this._sendMessage({
|
|
93
116
|
type: t.RESPONSE,
|
|
94
117
|
id: request.id,
|
|
@@ -98,7 +121,7 @@ module.exports = class RPC {
|
|
|
98
121
|
})
|
|
99
122
|
}
|
|
100
123
|
|
|
101
|
-
_ondata
|
|
124
|
+
_ondata(data) {
|
|
102
125
|
if (this._buffer === null) this._buffer = data
|
|
103
126
|
else this._buffer = b4a.concat([this._buffer, data])
|
|
104
127
|
|
|
@@ -118,7 +141,12 @@ module.exports = class RPC {
|
|
|
118
141
|
|
|
119
142
|
switch (message.type) {
|
|
120
143
|
case t.REQUEST: {
|
|
121
|
-
const request = new IncomingRequest(
|
|
144
|
+
const request = new IncomingRequest(
|
|
145
|
+
this,
|
|
146
|
+
message.id,
|
|
147
|
+
message.command,
|
|
148
|
+
message.data
|
|
149
|
+
)
|
|
122
150
|
|
|
123
151
|
try {
|
|
124
152
|
this._onrequest(request)
|
|
@@ -144,14 +172,15 @@ module.exports = class RPC {
|
|
|
144
172
|
}
|
|
145
173
|
}
|
|
146
174
|
|
|
147
|
-
this._buffer =
|
|
175
|
+
this._buffer =
|
|
176
|
+
state.start === state.end ? null : this._buffer.subarray(state.start)
|
|
148
177
|
}
|
|
149
178
|
}
|
|
150
179
|
|
|
151
|
-
_onresponse
|
|
180
|
+
_onresponse(message) {
|
|
152
181
|
if (message.id === 0) return
|
|
153
182
|
|
|
154
|
-
const request = this.
|
|
183
|
+
const request = this._outgoingRequests.get(message.id)
|
|
155
184
|
if (request === undefined) return
|
|
156
185
|
|
|
157
186
|
if (message.error) {
|
|
@@ -161,7 +190,7 @@ module.exports = class RPC {
|
|
|
161
190
|
}
|
|
162
191
|
}
|
|
163
192
|
|
|
164
|
-
_onstream
|
|
193
|
+
_onstream(message) {
|
|
165
194
|
if (message.id === 0) return
|
|
166
195
|
|
|
167
196
|
if (message.stream & s.OPEN) this._onstreamopen(message)
|
|
@@ -173,17 +202,23 @@ module.exports = class RPC {
|
|
|
173
202
|
else if (message.stream & s.DESTROY) this._onstreamdestroy(message)
|
|
174
203
|
}
|
|
175
204
|
|
|
176
|
-
_onstreamopen
|
|
205
|
+
_onstreamopen(message) {
|
|
177
206
|
let stream
|
|
178
207
|
|
|
179
208
|
if (message.stream & s.REQUEST) {
|
|
180
|
-
const request = this.
|
|
181
|
-
if (request === undefined)
|
|
209
|
+
const request = this._outgoingRequests.get(message.id)
|
|
210
|
+
if (request === undefined) {
|
|
211
|
+
this._pendingRequests.add(message.id)
|
|
212
|
+
return
|
|
213
|
+
}
|
|
182
214
|
|
|
183
215
|
stream = request._requestStream
|
|
184
216
|
} else if (message.stream & s.RESPONSE) {
|
|
185
|
-
const request = this.
|
|
186
|
-
if (request === undefined)
|
|
217
|
+
const request = this._outgoingResponses.get(message.id)
|
|
218
|
+
if (request === undefined) {
|
|
219
|
+
this._pendingResponses.add(message.id)
|
|
220
|
+
return
|
|
221
|
+
}
|
|
187
222
|
|
|
188
223
|
stream = request._responseStream
|
|
189
224
|
} else {
|
|
@@ -193,15 +228,18 @@ module.exports = class RPC {
|
|
|
193
228
|
stream._continueOpen()
|
|
194
229
|
}
|
|
195
230
|
|
|
196
|
-
_onstreamclose
|
|
197
|
-
const request = this._incoming.get(message.id)
|
|
198
|
-
if (request === undefined) return
|
|
199
|
-
|
|
231
|
+
_onstreamclose(message) {
|
|
200
232
|
let stream
|
|
201
233
|
|
|
202
234
|
if (message.stream & s.REQUEST) {
|
|
235
|
+
const request = this._incomingRequests.get(message.id)
|
|
236
|
+
if (request === undefined) return
|
|
237
|
+
|
|
203
238
|
stream = request._requestStream
|
|
204
239
|
} else if (message.stream & s.RESPONSE) {
|
|
240
|
+
const request = this._incomingResponses.get(message.id)
|
|
241
|
+
if (request === undefined) return
|
|
242
|
+
|
|
205
243
|
stream = request._responseStream
|
|
206
244
|
} else {
|
|
207
245
|
return
|
|
@@ -211,16 +249,16 @@ module.exports = class RPC {
|
|
|
211
249
|
else stream.push(null)
|
|
212
250
|
}
|
|
213
251
|
|
|
214
|
-
_onstreampause
|
|
252
|
+
_onstreampause(message) {
|
|
215
253
|
let stream
|
|
216
254
|
|
|
217
255
|
if (message.stream & s.REQUEST) {
|
|
218
|
-
const request = this.
|
|
256
|
+
const request = this._outgoingRequests.get(message.id)
|
|
219
257
|
if (request === undefined) return
|
|
220
258
|
|
|
221
259
|
stream = request._requestStream
|
|
222
260
|
} else if (message.stream & s.RESPONSE) {
|
|
223
|
-
const request = this.
|
|
261
|
+
const request = this._outgoingResponses.get(message.id)
|
|
224
262
|
if (request === undefined) return
|
|
225
263
|
|
|
226
264
|
stream = request._responseStream
|
|
@@ -231,16 +269,16 @@ module.exports = class RPC {
|
|
|
231
269
|
stream.cork()
|
|
232
270
|
}
|
|
233
271
|
|
|
234
|
-
_onstreamresume
|
|
272
|
+
_onstreamresume(message) {
|
|
235
273
|
let stream
|
|
236
274
|
|
|
237
275
|
if (message.stream & s.REQUEST) {
|
|
238
|
-
const request = this.
|
|
276
|
+
const request = this._outgoingRequests.get(message.id)
|
|
239
277
|
if (request === undefined) return
|
|
240
278
|
|
|
241
279
|
stream = request._requestStream
|
|
242
280
|
} else if (message.stream & s.RESPONSE) {
|
|
243
|
-
const request = this.
|
|
281
|
+
const request = this._outgoingResponses.get(message.id)
|
|
244
282
|
if (request === undefined) return
|
|
245
283
|
|
|
246
284
|
stream = request._responseStream
|
|
@@ -251,15 +289,18 @@ module.exports = class RPC {
|
|
|
251
289
|
stream.uncork()
|
|
252
290
|
}
|
|
253
291
|
|
|
254
|
-
_onstreamdata
|
|
255
|
-
const request = this._incoming.get(message.id)
|
|
256
|
-
if (request === undefined) return
|
|
257
|
-
|
|
292
|
+
_onstreamdata(message) {
|
|
258
293
|
let stream
|
|
259
294
|
|
|
260
295
|
if (message.stream & s.REQUEST) {
|
|
296
|
+
const request = this._incomingRequests.get(message.id)
|
|
297
|
+
if (request === undefined) return
|
|
298
|
+
|
|
261
299
|
stream = request._requestStream
|
|
262
300
|
} else if (message.stream & s.RESPONSE) {
|
|
301
|
+
const request = this._incomingResponses.get(message.id)
|
|
302
|
+
if (request === undefined) return
|
|
303
|
+
|
|
263
304
|
stream = request._responseStream
|
|
264
305
|
} else {
|
|
265
306
|
return
|
|
@@ -276,15 +317,18 @@ module.exports = class RPC {
|
|
|
276
317
|
}
|
|
277
318
|
}
|
|
278
319
|
|
|
279
|
-
_onstreamend
|
|
280
|
-
const request = this._incoming.get(message.id)
|
|
281
|
-
if (request === undefined) return
|
|
282
|
-
|
|
320
|
+
_onstreamend(message) {
|
|
283
321
|
let stream
|
|
284
322
|
|
|
285
323
|
if (message.stream & s.REQUEST) {
|
|
324
|
+
const request = this._incomingRequests.get(message.id)
|
|
325
|
+
if (request === undefined) return
|
|
326
|
+
|
|
286
327
|
stream = request._requestStream
|
|
287
328
|
} else if (message.stream & s.RESPONSE) {
|
|
329
|
+
const request = this._incomingResponses.get(message.id)
|
|
330
|
+
if (request === undefined) return
|
|
331
|
+
|
|
288
332
|
stream = request._responseStream
|
|
289
333
|
} else {
|
|
290
334
|
return
|
|
@@ -293,16 +337,16 @@ module.exports = class RPC {
|
|
|
293
337
|
stream.push(null)
|
|
294
338
|
}
|
|
295
339
|
|
|
296
|
-
_onstreamdestroy
|
|
340
|
+
_onstreamdestroy(message) {
|
|
297
341
|
let stream
|
|
298
342
|
|
|
299
343
|
if (message.stream & s.REQUEST) {
|
|
300
|
-
const request = this.
|
|
344
|
+
const request = this._outgoingRequests.get(message.id)
|
|
301
345
|
if (request === undefined) return
|
|
302
346
|
|
|
303
347
|
stream = request._requestStream
|
|
304
348
|
} else if (message.stream & s.RESPONSE) {
|
|
305
|
-
const request = this.
|
|
349
|
+
const request = this._outgoingResponses.get(message.id)
|
|
306
350
|
if (request === undefined) return
|
|
307
351
|
|
|
308
352
|
stream = request._responseStream
|
package/lib/errors.d.ts
ADDED
package/lib/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = class RPCError extends Error {
|
|
2
|
-
constructor
|
|
2
|
+
constructor(msg, code, fn = RPCError) {
|
|
3
3
|
super(`${code}: ${msg}`)
|
|
4
4
|
this.code = code
|
|
5
5
|
|
|
@@ -8,15 +8,15 @@ module.exports = class RPCError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
get name
|
|
11
|
+
get name() {
|
|
12
12
|
return 'RPCError'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
static UNKNOWN_MESSAGE
|
|
15
|
+
static UNKNOWN_MESSAGE(msg) {
|
|
16
16
|
return new RPCError(msg, 'UNKNOWN_MESSAGE', RPCError.UNKNOWN_MESSAGE)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
static ALREADY_SENT
|
|
19
|
+
static ALREADY_SENT(msg) {
|
|
20
20
|
return new RPCError(msg, 'ALREADY_SENT', RPCError.ALREADY_SENT)
|
|
21
21
|
}
|
|
22
22
|
}
|
package/lib/incoming-request.js
CHANGED
|
@@ -2,7 +2,7 @@ const b4a = require('b4a')
|
|
|
2
2
|
const errors = require('./errors')
|
|
3
3
|
|
|
4
4
|
module.exports = class RPCIncomingRequest {
|
|
5
|
-
constructor
|
|
5
|
+
constructor(rpc, id, command, data) {
|
|
6
6
|
this.rpc = rpc
|
|
7
7
|
this.id = id
|
|
8
8
|
this.command = command
|
|
@@ -13,21 +13,26 @@ module.exports = class RPCIncomingRequest {
|
|
|
13
13
|
this._responseStream = null
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
reply
|
|
16
|
+
reply(data, encoding) {
|
|
17
17
|
if (this.sent) throw errors.ALREADY_SENT('Response has already been sent')
|
|
18
18
|
this.sent = true
|
|
19
19
|
|
|
20
|
-
this.rpc._sendResponse(
|
|
20
|
+
this.rpc._sendResponse(
|
|
21
|
+
this,
|
|
22
|
+
typeof data === 'string' ? b4a.from(data, encoding) : data
|
|
23
|
+
)
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
createResponseStream
|
|
24
|
-
if (this._responseStream === null)
|
|
26
|
+
createResponseStream(opts = {}) {
|
|
27
|
+
if (this._responseStream === null)
|
|
28
|
+
this.rpc._createResponseStream(this, true, opts)
|
|
25
29
|
|
|
26
30
|
return this._responseStream
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
createRequestStream
|
|
30
|
-
if (this._requestStream === null)
|
|
33
|
+
createRequestStream(opts = {}) {
|
|
34
|
+
if (this._requestStream === null)
|
|
35
|
+
this.rpc._createRequestStream(this, false, opts)
|
|
31
36
|
|
|
32
37
|
return this._requestStream
|
|
33
38
|
}
|
package/lib/incoming-stream.js
CHANGED
|
@@ -2,7 +2,7 @@ const { Readable } = require('bare-stream')
|
|
|
2
2
|
const { type: t, stream: s } = require('./constants')
|
|
3
3
|
|
|
4
4
|
module.exports = class RPCIncomingStream extends Readable {
|
|
5
|
-
constructor
|
|
5
|
+
constructor(rpc, request, type, opts) {
|
|
6
6
|
super({ ...opts, eagerOpen: true })
|
|
7
7
|
|
|
8
8
|
this._rpc = rpc
|
|
@@ -13,7 +13,7 @@ module.exports = class RPCIncomingStream extends Readable {
|
|
|
13
13
|
this._pendingOpen = null
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
_open
|
|
16
|
+
_open(cb) {
|
|
17
17
|
this._rpc._sendMessage({
|
|
18
18
|
type: t.STREAM,
|
|
19
19
|
id: this._request.id,
|
|
@@ -25,7 +25,7 @@ module.exports = class RPCIncomingStream extends Readable {
|
|
|
25
25
|
cb(null)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
_read
|
|
28
|
+
_read() {
|
|
29
29
|
this._rpc._sendMessage({
|
|
30
30
|
type: t.STREAM,
|
|
31
31
|
id: this._request.id,
|
|
@@ -35,7 +35,7 @@ module.exports = class RPCIncomingStream extends Readable {
|
|
|
35
35
|
})
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
_destroy
|
|
38
|
+
_destroy(err, cb) {
|
|
39
39
|
if (err) {
|
|
40
40
|
this._rpc._sendMessage({
|
|
41
41
|
type: t.STREAM,
|
package/lib/messages.js
CHANGED
|
@@ -3,17 +3,17 @@ const { type: t, stream: s } = require('./constants')
|
|
|
3
3
|
const errors = require('./errors')
|
|
4
4
|
|
|
5
5
|
const request = {
|
|
6
|
-
preencode
|
|
6
|
+
preencode(state, m) {
|
|
7
7
|
c.utf8.preencode(state, m.command)
|
|
8
8
|
c.uint.preencode(state, m.stream)
|
|
9
9
|
if (m.stream === 0) c.buffer.preencode(state, m.data)
|
|
10
10
|
},
|
|
11
|
-
encode
|
|
11
|
+
encode(state, m) {
|
|
12
12
|
c.utf8.encode(state, m.command)
|
|
13
13
|
c.uint.encode(state, m.stream)
|
|
14
14
|
if (m.stream === 0) c.buffer.encode(state, m.data)
|
|
15
15
|
},
|
|
16
|
-
decode
|
|
16
|
+
decode(state, id) {
|
|
17
17
|
const command = c.utf8.decode(state)
|
|
18
18
|
const stream = c.uint.decode(state)
|
|
19
19
|
const data = stream === 0 ? c.buffer.decode(state) : null
|
|
@@ -23,17 +23,17 @@ const request = {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const error = {
|
|
26
|
-
preencode
|
|
26
|
+
preencode(state, m) {
|
|
27
27
|
c.utf8.preencode(state, m.message)
|
|
28
28
|
c.utf8.preencode(state, m.code || '')
|
|
29
29
|
c.int.preencode(state, m.errno || 0)
|
|
30
30
|
},
|
|
31
|
-
encode
|
|
31
|
+
encode(state, m) {
|
|
32
32
|
c.utf8.encode(state, m.message)
|
|
33
33
|
c.utf8.encode(state, m.code || '')
|
|
34
34
|
c.int.encode(state, m.errno || 0)
|
|
35
35
|
},
|
|
36
|
-
decode
|
|
36
|
+
decode(state) {
|
|
37
37
|
const err = new Error(`${c.utf8.decode(state)}`)
|
|
38
38
|
err.code = c.utf8.decode(state)
|
|
39
39
|
err.errno = c.int.decode(state)
|
|
@@ -42,56 +42,59 @@ const error = {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const response = {
|
|
45
|
-
preencode
|
|
45
|
+
preencode(state, m) {
|
|
46
46
|
c.bool.preencode(state, !!m.error)
|
|
47
47
|
c.uint.preencode(state, m.stream)
|
|
48
48
|
|
|
49
49
|
if (m.error) error.preencode(state, m.error)
|
|
50
50
|
else if (m.stream === 0) c.buffer.preencode(state, m.data)
|
|
51
51
|
},
|
|
52
|
-
encode
|
|
52
|
+
encode(state, m) {
|
|
53
53
|
c.bool.encode(state, !!m.error)
|
|
54
54
|
c.uint.encode(state, m.stream)
|
|
55
55
|
|
|
56
56
|
if (m.error) error.encode(state, m)
|
|
57
57
|
else if (m.stream === 0) c.buffer.encode(state, m.data)
|
|
58
58
|
},
|
|
59
|
-
decode
|
|
59
|
+
decode(state) {
|
|
60
60
|
const error = c.bool.decode(state)
|
|
61
61
|
const stream = c.uint.decode(state)
|
|
62
62
|
|
|
63
63
|
if (error) return { stream, error: error.decode(state), data: null }
|
|
64
|
-
if (stream === 0)
|
|
64
|
+
if (stream === 0)
|
|
65
|
+
return { stream, error: null, data: c.buffer.decode(state) }
|
|
65
66
|
|
|
66
67
|
return { stream, error: null, data: null }
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
const stream = {
|
|
71
|
-
preencode
|
|
72
|
+
preencode(state, m) {
|
|
72
73
|
c.uint.preencode(state, m.stream)
|
|
73
74
|
|
|
74
75
|
if (m.stream & s.ERROR) error.preencode(state, m.error)
|
|
75
76
|
else if (m.stream & s.DATA) c.buffer.preencode(state, m.data)
|
|
76
77
|
},
|
|
77
|
-
encode
|
|
78
|
+
encode(state, m) {
|
|
78
79
|
c.uint.encode(state, m.stream)
|
|
79
80
|
|
|
80
81
|
if (m.stream & s.ERROR) error.encode(state, m.error)
|
|
81
82
|
else if (m.stream & s.DATA) c.buffer.encode(state, m.data)
|
|
82
83
|
},
|
|
83
|
-
decode
|
|
84
|
+
decode(state) {
|
|
84
85
|
const stream = c.uint.decode(state)
|
|
85
86
|
|
|
86
|
-
if (stream & s.ERROR)
|
|
87
|
-
|
|
87
|
+
if (stream & s.ERROR)
|
|
88
|
+
return { stream, error: error.decode(state), data: null }
|
|
89
|
+
if (stream & s.DATA)
|
|
90
|
+
return { stream, error: null, data: c.buffer.decode(state) }
|
|
88
91
|
|
|
89
92
|
return { stream, error: null, data: null }
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
exports.message = {
|
|
94
|
-
preencode
|
|
97
|
+
preencode(state, m) {
|
|
95
98
|
c.uint32.preencode(state, 0) // Frame
|
|
96
99
|
c.uint.preencode(state, m.type)
|
|
97
100
|
c.uint.preencode(state, m.id)
|
|
@@ -108,7 +111,7 @@ exports.message = {
|
|
|
108
111
|
break
|
|
109
112
|
}
|
|
110
113
|
},
|
|
111
|
-
encode
|
|
114
|
+
encode(state, m) {
|
|
112
115
|
const frame = state.start
|
|
113
116
|
|
|
114
117
|
c.uint32.encode(state, 0) // Frame
|
|
@@ -138,7 +141,7 @@ exports.message = {
|
|
|
138
141
|
|
|
139
142
|
state.start = end
|
|
140
143
|
},
|
|
141
|
-
decode
|
|
144
|
+
decode(state) {
|
|
142
145
|
if (state.end - state.start < 4) return null
|
|
143
146
|
|
|
144
147
|
const frame = c.uint32.decode(state)
|
package/lib/outgoing-request.js
CHANGED
|
@@ -2,9 +2,9 @@ const b4a = require('b4a')
|
|
|
2
2
|
const errors = require('./errors')
|
|
3
3
|
|
|
4
4
|
module.exports = class RPCOutgoingRequest {
|
|
5
|
-
constructor
|
|
5
|
+
constructor(id, rpc, command) {
|
|
6
|
+
this.id = id
|
|
6
7
|
this.rpc = rpc
|
|
7
|
-
this.id = -1
|
|
8
8
|
this.command = command
|
|
9
9
|
this.sent = false
|
|
10
10
|
|
|
@@ -17,25 +17,34 @@ module.exports = class RPCOutgoingRequest {
|
|
|
17
17
|
this._responseStream = null
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
send
|
|
20
|
+
send(data, encoding) {
|
|
21
21
|
if (this.sent) throw errors.ALREADY_SENT('Request has already been sent')
|
|
22
22
|
this.sent = true
|
|
23
23
|
|
|
24
|
-
this.rpc._sendRequest(
|
|
24
|
+
this.rpc._sendRequest(
|
|
25
|
+
this,
|
|
26
|
+
typeof data === 'string' ? b4a.from(data, encoding) : data
|
|
27
|
+
)
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
reply
|
|
28
|
-
return
|
|
30
|
+
reply(encoding) {
|
|
31
|
+
return encoding && encoding !== 'buffer'
|
|
32
|
+
? this._promise.then((data) => b4a.toString(data, encoding))
|
|
33
|
+
: this._promise
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
createRequestStream
|
|
32
|
-
if (this._requestStream === null)
|
|
36
|
+
createRequestStream(opts = {}) {
|
|
37
|
+
if (this._requestStream === null) {
|
|
38
|
+
this.rpc._createRequestStream(this, true, opts)
|
|
39
|
+
}
|
|
33
40
|
|
|
34
41
|
return this._requestStream
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
createResponseStream
|
|
38
|
-
if (this._requestStream === null)
|
|
44
|
+
createResponseStream(opts = {}) {
|
|
45
|
+
if (this._requestStream === null) {
|
|
46
|
+
this.rpc._createResponseStream(this, false, opts)
|
|
47
|
+
}
|
|
39
48
|
|
|
40
49
|
return this._responseStream
|
|
41
50
|
}
|
package/lib/outgoing-stream.js
CHANGED
|
@@ -2,7 +2,7 @@ const { Writable } = require('bare-stream')
|
|
|
2
2
|
const { type: t, stream: s } = require('./constants')
|
|
3
3
|
|
|
4
4
|
module.exports = class RPCOutgoingStream extends Writable {
|
|
5
|
-
constructor
|
|
5
|
+
constructor(rpc, request, type, opts) {
|
|
6
6
|
super({ ...opts, eagerOpen: true })
|
|
7
7
|
|
|
8
8
|
this._rpc = rpc
|
|
@@ -13,11 +13,13 @@ module.exports = class RPCOutgoingStream extends Writable {
|
|
|
13
13
|
this._pendingOpen = null
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
_open
|
|
17
|
-
|
|
16
|
+
_open(cb) {
|
|
17
|
+
let pending
|
|
18
18
|
|
|
19
19
|
switch (this._type) {
|
|
20
20
|
case t.REQUEST:
|
|
21
|
+
pending = this._rpc._pendingRequests
|
|
22
|
+
|
|
21
23
|
this._rpc._sendMessage({
|
|
22
24
|
type: t.REQUEST,
|
|
23
25
|
id: this._request.id,
|
|
@@ -28,6 +30,8 @@ module.exports = class RPCOutgoingStream extends Writable {
|
|
|
28
30
|
break
|
|
29
31
|
|
|
30
32
|
case t.RESPONSE:
|
|
33
|
+
pending = this._rpc._pendingResponses
|
|
34
|
+
|
|
31
35
|
this._rpc._sendMessage({
|
|
32
36
|
type: t.RESPONSE,
|
|
33
37
|
id: this._request.id,
|
|
@@ -37,16 +41,24 @@ module.exports = class RPCOutgoingStream extends Writable {
|
|
|
37
41
|
})
|
|
38
42
|
break
|
|
39
43
|
}
|
|
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
|
+
}
|
|
40
52
|
}
|
|
41
53
|
|
|
42
|
-
_continueOpen
|
|
54
|
+
_continueOpen() {
|
|
43
55
|
if (this._pendingOpen === null) return
|
|
44
56
|
const cb = this._pendingOpen
|
|
45
57
|
this._pendingOpen = null
|
|
46
58
|
cb()
|
|
47
59
|
}
|
|
48
60
|
|
|
49
|
-
_write
|
|
61
|
+
_write(data, encoding, cb) {
|
|
50
62
|
this._rpc._sendMessage({
|
|
51
63
|
type: t.STREAM,
|
|
52
64
|
id: this._request.id,
|
|
@@ -58,7 +70,7 @@ module.exports = class RPCOutgoingStream extends Writable {
|
|
|
58
70
|
cb(null)
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
_final
|
|
73
|
+
_final(cb) {
|
|
62
74
|
this._rpc._sendMessage({
|
|
63
75
|
type: t.STREAM,
|
|
64
76
|
id: this._request.id,
|
|
@@ -70,7 +82,7 @@ module.exports = class RPCOutgoingStream extends Writable {
|
|
|
70
82
|
cb(null)
|
|
71
83
|
}
|
|
72
84
|
|
|
73
|
-
_destroy
|
|
85
|
+
_destroy(err, cb) {
|
|
74
86
|
if (err) {
|
|
75
87
|
this._rpc._sendMessage({
|
|
76
88
|
type: t.STREAM,
|
package/package.json
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-rpc",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "librpc ABI compatible RPC for Bare",
|
|
5
5
|
"exports": {
|
|
6
|
-
".":
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"default": "./index.js"
|
|
9
|
+
},
|
|
7
10
|
"./package": "./package.json",
|
|
8
|
-
"./errors":
|
|
11
|
+
"./errors": {
|
|
12
|
+
"types": "./lib/errors.d.ts",
|
|
13
|
+
"default": "./lib/errors.js"
|
|
14
|
+
}
|
|
9
15
|
},
|
|
10
16
|
"files": [
|
|
11
17
|
"index.js",
|
|
18
|
+
"index.d.ts",
|
|
12
19
|
"lib"
|
|
13
20
|
],
|
|
14
21
|
"scripts": {
|
|
15
|
-
"test": "
|
|
22
|
+
"test": "prettier . --check && bare test.js"
|
|
16
23
|
},
|
|
17
24
|
"repository": {
|
|
18
25
|
"type": "git",
|
|
@@ -31,7 +38,17 @@
|
|
|
31
38
|
"safety-catch": "^1.0.2"
|
|
32
39
|
},
|
|
33
40
|
"devDependencies": {
|
|
41
|
+
"bare-buffer": "^3.0.1",
|
|
34
42
|
"brittle": "^3.2.1",
|
|
35
|
-
"
|
|
43
|
+
"prettier": "^3.4.2",
|
|
44
|
+
"prettier-config-standard": "^7.0.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"bare-buffer": "*"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"bare-buffer": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
36
53
|
}
|
|
37
54
|
}
|