starpc 0.0.1 → 0.1.2
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/LICENSE +19 -0
- package/Makefile +140 -0
- package/README.md +128 -26
- package/dist/echo/echo.d.ts +59 -0
- package/dist/echo/echo.js +85 -0
- package/dist/srpc/broadcast-channel.d.ts +16 -0
- package/dist/srpc/broadcast-channel.js +60 -0
- package/dist/srpc/client-rpc.d.ts +31 -0
- package/dist/srpc/client-rpc.js +176 -0
- package/dist/srpc/client.d.ts +12 -0
- package/dist/srpc/client.js +129 -0
- package/dist/srpc/conn.d.ts +14 -0
- package/dist/srpc/conn.js +38 -0
- package/dist/srpc/index.d.ts +3 -0
- package/dist/srpc/index.js +2 -0
- package/dist/srpc/packet.d.ts +9 -0
- package/dist/srpc/packet.js +89 -0
- package/dist/srpc/rpcproto.d.ts +194 -0
- package/dist/srpc/rpcproto.js +322 -0
- package/dist/srpc/stream.d.ts +5 -0
- package/dist/srpc/stream.js +1 -0
- package/dist/srpc/ts-proto-rpc.d.ts +7 -0
- package/dist/srpc/ts-proto-rpc.js +1 -0
- package/dist/srpc/websocket.d.ts +7 -0
- package/dist/srpc/websocket.js +18 -0
- package/e2e/e2e.go +1 -0
- package/e2e/e2e_test.go +158 -0
- package/echo/echo.go +1 -0
- package/echo/echo.pb.go +165 -0
- package/echo/echo.proto +19 -0
- package/echo/echo.ts +191 -0
- package/echo/echo_srpc.pb.go +333 -0
- package/echo/echo_vtproto.pb.go +271 -0
- package/echo/server.go +73 -0
- package/go.mod +50 -0
- package/go.sum +210 -0
- package/integration/integration.bash +25 -0
- package/integration/integration.go +30 -0
- package/integration/integration.ts +54 -0
- package/integration/tsconfig.json +11 -0
- package/package.json +77 -9
- package/patches/@libp2p+mplex+1.2.1.patch +22 -0
- package/srpc/broadcast-channel.ts +72 -0
- package/srpc/client-rpc.go +163 -0
- package/srpc/client-rpc.ts +197 -0
- package/srpc/client.go +96 -0
- package/srpc/client.ts +182 -0
- package/srpc/conn.go +7 -0
- package/srpc/conn.ts +49 -0
- package/srpc/errors.go +20 -0
- package/srpc/handler.go +13 -0
- package/srpc/index.ts +3 -0
- package/srpc/message.go +7 -0
- package/srpc/mux.go +76 -0
- package/srpc/packet-rw.go +102 -0
- package/srpc/packet.go +71 -0
- package/srpc/packet.ts +105 -0
- package/srpc/rpc-stream.go +76 -0
- package/srpc/rpcproto.pb.go +455 -0
- package/srpc/rpcproto.proto +46 -0
- package/srpc/rpcproto.ts +467 -0
- package/srpc/rpcproto_vtproto.pb.go +1094 -0
- package/srpc/server-http.go +66 -0
- package/srpc/server-pipe.go +26 -0
- package/srpc/server-rpc.go +160 -0
- package/srpc/server.go +29 -0
- package/srpc/stream-pipe.go +86 -0
- package/srpc/stream.go +24 -0
- package/srpc/stream.ts +11 -0
- package/srpc/ts-proto-rpc.ts +29 -0
- package/srpc/websocket.go +68 -0
- package/srpc/websocket.ts +22 -0
- package/srpc/writer.go +9 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Packet } from './rpcproto';
|
|
2
|
+
import { pushable } from 'it-pushable';
|
|
3
|
+
// ClientRPC is an ongoing RPC from the client side.
|
|
4
|
+
export class ClientRPC {
|
|
5
|
+
// sink is the data sink for incoming messages.
|
|
6
|
+
sink;
|
|
7
|
+
// source is the packet source for outgoing Packets.
|
|
8
|
+
source;
|
|
9
|
+
// _source is used to write to the source.
|
|
10
|
+
_source;
|
|
11
|
+
// service is the rpc service
|
|
12
|
+
service;
|
|
13
|
+
// method is the rpc method
|
|
14
|
+
method;
|
|
15
|
+
// dataCb is called with any incoming data.
|
|
16
|
+
dataCb;
|
|
17
|
+
// started is resolved when the request starts.
|
|
18
|
+
started;
|
|
19
|
+
// onStarted is called by the message handler when the request starts.
|
|
20
|
+
onStarted;
|
|
21
|
+
// complete is resolved when the request completes.
|
|
22
|
+
// rejected with an error if the call encountered any error.
|
|
23
|
+
complete;
|
|
24
|
+
// onComplete is called by the message handler when the call completes.
|
|
25
|
+
onComplete;
|
|
26
|
+
// closed indicates close has been called
|
|
27
|
+
closed;
|
|
28
|
+
constructor(service, method, dataCb) {
|
|
29
|
+
this.closed = false;
|
|
30
|
+
this.sink = this._createSink();
|
|
31
|
+
const sourcev = this._createSource();
|
|
32
|
+
this.source = sourcev;
|
|
33
|
+
this._source = sourcev;
|
|
34
|
+
this.service = service;
|
|
35
|
+
this.method = method;
|
|
36
|
+
if (dataCb) {
|
|
37
|
+
this.dataCb = dataCb;
|
|
38
|
+
}
|
|
39
|
+
this.started = new Promise((resolveStarted, rejectStarted) => {
|
|
40
|
+
this.onStarted = (err) => {
|
|
41
|
+
if (err) {
|
|
42
|
+
rejectStarted(err);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
resolveStarted();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
this.complete = new Promise((resolveComplete, rejectComplete) => {
|
|
50
|
+
this.onComplete = (err) => {
|
|
51
|
+
this.closed = true;
|
|
52
|
+
if (err) {
|
|
53
|
+
rejectComplete(err);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
resolveComplete();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// waitStarted returns the started promise.
|
|
62
|
+
waitStarted() {
|
|
63
|
+
return this.started;
|
|
64
|
+
}
|
|
65
|
+
// waitComplete returns the complete promise.
|
|
66
|
+
waitComplete() {
|
|
67
|
+
return this.complete;
|
|
68
|
+
}
|
|
69
|
+
// writeCallStart writes the call start packet.
|
|
70
|
+
async writeCallStart(data) {
|
|
71
|
+
const callStart = {
|
|
72
|
+
rpcService: this.service,
|
|
73
|
+
rpcMethod: this.method,
|
|
74
|
+
data: data || new Uint8Array(0),
|
|
75
|
+
};
|
|
76
|
+
await this.writePacket({
|
|
77
|
+
body: {
|
|
78
|
+
$case: 'callStart',
|
|
79
|
+
callStart,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// writeCallData writes the call data packet.
|
|
84
|
+
async writeCallData(data, complete, error) {
|
|
85
|
+
const callData = {
|
|
86
|
+
data,
|
|
87
|
+
complete: complete || false,
|
|
88
|
+
error: error || "",
|
|
89
|
+
};
|
|
90
|
+
await this.writePacket({
|
|
91
|
+
body: {
|
|
92
|
+
$case: 'callData',
|
|
93
|
+
callData,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// writePacket writes a packet to the stream.
|
|
98
|
+
async writePacket(packet) {
|
|
99
|
+
this._source.push(packet);
|
|
100
|
+
}
|
|
101
|
+
// handleMessage handles an incoming encoded Packet.
|
|
102
|
+
//
|
|
103
|
+
// note: may throw an error if the message was unexpected or invalid.
|
|
104
|
+
async handleMessage(message) {
|
|
105
|
+
return this.handlePacket(Packet.decode(message));
|
|
106
|
+
}
|
|
107
|
+
// handlePacket handles an incoming packet.
|
|
108
|
+
async handlePacket(packet) {
|
|
109
|
+
switch (packet?.body?.$case) {
|
|
110
|
+
case 'callStart':
|
|
111
|
+
return this.handleCallStart(packet.body.callStart);
|
|
112
|
+
case 'callStartResp':
|
|
113
|
+
return this.handleCallStartResp(packet.body.callStartResp);
|
|
114
|
+
case 'callData':
|
|
115
|
+
return this.handleCallData(packet.body.callData);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// handleCallStart handles a CallStart packet.
|
|
119
|
+
async handleCallStart(packet) {
|
|
120
|
+
// we do not implement server -> client RPCs.
|
|
121
|
+
throw new Error(`unexpected server to client rpc: ${packet.rpcService}/${packet.rpcMethod}`);
|
|
122
|
+
}
|
|
123
|
+
// handleCallStartResp handles a CallStartResp packet.
|
|
124
|
+
async handleCallStartResp(packet) {
|
|
125
|
+
if (packet.error && packet.error.length) {
|
|
126
|
+
const err = new Error(packet.error);
|
|
127
|
+
this.onStarted(err);
|
|
128
|
+
this.onComplete(err);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// handleCallData handles a CallData packet.
|
|
132
|
+
async handleCallData(packet) {
|
|
133
|
+
const data = packet.data;
|
|
134
|
+
if (this.dataCb && data?.length) {
|
|
135
|
+
await this.dataCb(data);
|
|
136
|
+
}
|
|
137
|
+
if (packet.error && packet.error.length) {
|
|
138
|
+
this.onComplete(new Error(packet.error));
|
|
139
|
+
}
|
|
140
|
+
else if (packet.complete) {
|
|
141
|
+
this.onComplete();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// close closes the active call if not already completed.
|
|
145
|
+
async close(err) {
|
|
146
|
+
if (!this.closed) {
|
|
147
|
+
await this.writeCallData(new Uint8Array(0), true, err ? err.message : "");
|
|
148
|
+
}
|
|
149
|
+
if (!err) {
|
|
150
|
+
err = new Error('call closed');
|
|
151
|
+
}
|
|
152
|
+
this.onComplete(err);
|
|
153
|
+
}
|
|
154
|
+
// _createSink initializes the sink field.
|
|
155
|
+
_createSink() {
|
|
156
|
+
return async (source) => {
|
|
157
|
+
try {
|
|
158
|
+
for await (const msg of source) {
|
|
159
|
+
await this.handlePacket(msg);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
this.close(err);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// _createSource initializes the source field.
|
|
168
|
+
_createSource() {
|
|
169
|
+
return pushable({
|
|
170
|
+
objectMode: true,
|
|
171
|
+
onEnd: (err) => {
|
|
172
|
+
this.onComplete(err);
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import type { TsProtoRpc } from './ts-proto-rpc';
|
|
3
|
+
import type { OpenStreamFunc } from './stream';
|
|
4
|
+
export declare class Client implements TsProtoRpc {
|
|
5
|
+
private openConnFn;
|
|
6
|
+
constructor(openConnFn: OpenStreamFunc);
|
|
7
|
+
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
8
|
+
clientStreamingRequest(service: string, method: string, data: Observable<Uint8Array>): Promise<Uint8Array>;
|
|
9
|
+
serverStreamingRequest(service: string, method: string, data: Uint8Array): Observable<Uint8Array>;
|
|
10
|
+
bidirectionalStreamingRequest(service: string, method: string, data: Observable<Uint8Array>): Observable<Uint8Array>;
|
|
11
|
+
private startRpc;
|
|
12
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { from as observableFrom } from 'rxjs';
|
|
2
|
+
import { ClientRPC } from './client-rpc';
|
|
3
|
+
import { pipe } from 'it-pipe';
|
|
4
|
+
import { pushable } from 'it-pushable';
|
|
5
|
+
import { decodePacketSource, encodePacketSource, parseLengthPrefixTransform, prependLengthPrefixTransform, } from './packet';
|
|
6
|
+
// unaryDataCb builds a new unary request data callback.
|
|
7
|
+
function unaryDataCb(resolve) {
|
|
8
|
+
return async (data) => {
|
|
9
|
+
// resolve the promise
|
|
10
|
+
resolve(data);
|
|
11
|
+
// this is the last data we expect.
|
|
12
|
+
return false;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
// streamingDataCb builds a new streaming request data callback.
|
|
16
|
+
/*
|
|
17
|
+
function streamingDataCb(resolve: (data: Uint8Array) => void): DataCb {
|
|
18
|
+
return async (
|
|
19
|
+
data: Uint8Array
|
|
20
|
+
): Promise<boolean | void> => {
|
|
21
|
+
// TODO
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
*/
|
|
25
|
+
// writeClientStream registers the subscriber to write the client data stream.
|
|
26
|
+
function writeClientStream(call, data) {
|
|
27
|
+
data.subscribe({
|
|
28
|
+
next(value) {
|
|
29
|
+
call.writeCallData(value);
|
|
30
|
+
},
|
|
31
|
+
error(err) {
|
|
32
|
+
call.close(err);
|
|
33
|
+
},
|
|
34
|
+
complete() {
|
|
35
|
+
call.writeCallData(new Uint8Array(0), true);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// waitCallComplete handles the call complete promise.
|
|
40
|
+
function waitCallComplete(call, resolve, reject) {
|
|
41
|
+
call.waitComplete().catch(reject).finally(() => {
|
|
42
|
+
// ensure we resolve it if no data was ever returned.
|
|
43
|
+
resolve(new Uint8Array());
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Client implements the ts-proto Rpc interface with the drpcproto protocol.
|
|
47
|
+
export class Client {
|
|
48
|
+
// openConnFn is the open connection function.
|
|
49
|
+
// called when starting RPC.
|
|
50
|
+
openConnFn;
|
|
51
|
+
constructor(openConnFn) {
|
|
52
|
+
this.openConnFn = openConnFn;
|
|
53
|
+
}
|
|
54
|
+
// request starts a non-streaming request.
|
|
55
|
+
async request(service, method, data) {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const dataCb = unaryDataCb(resolve);
|
|
58
|
+
this.startRpc(service, method, data, dataCb)
|
|
59
|
+
.then((call) => {
|
|
60
|
+
waitCallComplete(call, resolve, reject);
|
|
61
|
+
})
|
|
62
|
+
.catch(reject);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// clientStreamingRequest starts a client side streaming request.
|
|
66
|
+
clientStreamingRequest(service, method, data) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const dataCb = unaryDataCb(resolve);
|
|
69
|
+
this.startRpc(service, method, null, dataCb)
|
|
70
|
+
.then((call) => {
|
|
71
|
+
writeClientStream(call, data);
|
|
72
|
+
waitCallComplete(call, resolve, reject);
|
|
73
|
+
})
|
|
74
|
+
.catch(reject);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// serverStreamingRequest starts a server-side streaming request.
|
|
78
|
+
serverStreamingRequest(service, method, data) {
|
|
79
|
+
const pushServerData = pushable();
|
|
80
|
+
const serverData = observableFrom(pushServerData);
|
|
81
|
+
const dataCb = async (data) => {
|
|
82
|
+
// push the message to the observable
|
|
83
|
+
pushServerData.push(data);
|
|
84
|
+
// expect more messages
|
|
85
|
+
return true;
|
|
86
|
+
};
|
|
87
|
+
this.startRpc(service, method, data, dataCb)
|
|
88
|
+
.then((call) => {
|
|
89
|
+
call.waitComplete().catch((err) => {
|
|
90
|
+
pushServerData.throw(err);
|
|
91
|
+
}).finally(() => {
|
|
92
|
+
pushServerData.end();
|
|
93
|
+
});
|
|
94
|
+
})
|
|
95
|
+
.catch(pushServerData.throw.bind(pushServerData));
|
|
96
|
+
return serverData;
|
|
97
|
+
}
|
|
98
|
+
// bidirectionalStreamingRequest starts a two-way streaming request.
|
|
99
|
+
bidirectionalStreamingRequest(service, method, data) {
|
|
100
|
+
const pushServerData = pushable();
|
|
101
|
+
const serverData = observableFrom(pushServerData);
|
|
102
|
+
const dataCb = async (data) => {
|
|
103
|
+
// push the message to the observable
|
|
104
|
+
pushServerData.push(data);
|
|
105
|
+
// expect more messages
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
this.startRpc(service, method, null, dataCb)
|
|
109
|
+
.then((call) => {
|
|
110
|
+
writeClientStream(call, data);
|
|
111
|
+
call.waitComplete().catch((err) => {
|
|
112
|
+
pushServerData.throw(err);
|
|
113
|
+
}).finally(() => {
|
|
114
|
+
pushServerData.end();
|
|
115
|
+
});
|
|
116
|
+
})
|
|
117
|
+
.catch(pushServerData.throw.bind(pushServerData));
|
|
118
|
+
return serverData;
|
|
119
|
+
}
|
|
120
|
+
// startRpc is a common utility function to begin a rpc call.
|
|
121
|
+
// throws any error starting the rpc call
|
|
122
|
+
async startRpc(rpcService, rpcMethod, data, dataCb) {
|
|
123
|
+
const conn = await this.openConnFn();
|
|
124
|
+
const call = new ClientRPC(rpcService, rpcMethod, dataCb);
|
|
125
|
+
pipe(conn, parseLengthPrefixTransform(), decodePacketSource, call, encodePacketSource, prependLengthPrefixTransform(), conn);
|
|
126
|
+
await call.writeCallStart(data || undefined);
|
|
127
|
+
return call;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Stream } from '@libp2p/interfaces/connection';
|
|
2
|
+
import type { Duplex } from 'it-stream-types';
|
|
3
|
+
import type { Stream as SRPCStream } from './stream';
|
|
4
|
+
import { Client } from './client';
|
|
5
|
+
export declare class Conn implements Duplex<Uint8Array> {
|
|
6
|
+
private muxer;
|
|
7
|
+
constructor();
|
|
8
|
+
get sink(): import("it-stream-types").Sink<Uint8Array, Promise<void>>;
|
|
9
|
+
get source(): AsyncIterable<Uint8Array>;
|
|
10
|
+
get streams(): Stream[];
|
|
11
|
+
buildClient(): Client;
|
|
12
|
+
openStream(): Promise<SRPCStream>;
|
|
13
|
+
private handleIncomingStream;
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Components } from '@libp2p/interfaces/components';
|
|
2
|
+
import { MplexStreamMuxer } from '@libp2p/mplex';
|
|
3
|
+
import { Client } from './client';
|
|
4
|
+
// Conn implements a generic connection with a two-way stream.
|
|
5
|
+
export class Conn {
|
|
6
|
+
// muxer is the mplex stream muxer.
|
|
7
|
+
muxer;
|
|
8
|
+
constructor() {
|
|
9
|
+
// see https://github.com/libp2p/js-libp2p-mplex/pull/179
|
|
10
|
+
this.muxer = new MplexStreamMuxer(new Components(), {
|
|
11
|
+
onIncomingStream: this.handleIncomingStream.bind(this),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// sink returns the message sink.
|
|
15
|
+
get sink() {
|
|
16
|
+
return this.muxer.sink;
|
|
17
|
+
}
|
|
18
|
+
// source returns the outgoing message source.
|
|
19
|
+
get source() {
|
|
20
|
+
return this.muxer.source;
|
|
21
|
+
}
|
|
22
|
+
// streams returns the set of all ongoing streams.
|
|
23
|
+
get streams() {
|
|
24
|
+
return this.muxer.streams;
|
|
25
|
+
}
|
|
26
|
+
// buildClient builds a new client from the connection.
|
|
27
|
+
buildClient() {
|
|
28
|
+
return new Client(this.openStream.bind(this));
|
|
29
|
+
}
|
|
30
|
+
// openStream implements the client open stream function.
|
|
31
|
+
async openStream() {
|
|
32
|
+
return this.muxer.newStream();
|
|
33
|
+
}
|
|
34
|
+
// handleIncomingStream handles an incoming stream.
|
|
35
|
+
handleIncomingStream(strm) {
|
|
36
|
+
strm.abort(new Error('server -> client streams not implemented'));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Source, Transform } from 'it-stream-types';
|
|
2
|
+
import { Packet } from './rpcproto';
|
|
3
|
+
export declare function decodePacketSource(source: Source<Uint8Array | Uint8Array[]>): AsyncIterable<Packet>;
|
|
4
|
+
export declare function encodePacketSource(source: Source<Packet | Packet[]>): AsyncIterable<Uint8Array>;
|
|
5
|
+
export declare function prependLengthPrefixTransform(): Transform<Uint8Array>;
|
|
6
|
+
export declare function parseLengthPrefixTransform(): Transform<Uint8Array>;
|
|
7
|
+
export declare function encodeUint32Le(value: number): Uint8Array;
|
|
8
|
+
export declare function decodeUint32Le(data: Uint8Array): number;
|
|
9
|
+
export declare function prependPacketLen(msgData: Uint8Array): Uint8Array;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Packet } from './rpcproto';
|
|
2
|
+
import { encode as lengthPrefixEncode, decode as lengthPrefixDecode, } from 'it-length-prefixed';
|
|
3
|
+
// decodePacketSource unmarshals and async yields encoded Packets.
|
|
4
|
+
export async function* decodePacketSource(source) {
|
|
5
|
+
for await (const pkt of source) {
|
|
6
|
+
if (Array.isArray(pkt)) {
|
|
7
|
+
for (const p of pkt) {
|
|
8
|
+
yield* [Packet.decode(p)];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
yield* [Packet.decode(pkt)];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// encodePacketSource marshals and async yields packets.
|
|
17
|
+
export async function* encodePacketSource(source) {
|
|
18
|
+
for await (const pkt of source) {
|
|
19
|
+
if (Array.isArray(pkt)) {
|
|
20
|
+
for (const p of pkt) {
|
|
21
|
+
yield* [Packet.encode(p).finish()];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
yield* [Packet.encode(pkt).finish()];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// uint32LEDecode removes the length prefix.
|
|
30
|
+
const uint32LEDecode = (data) => {
|
|
31
|
+
if (data.length < 4) {
|
|
32
|
+
throw RangeError('Could not decode int32BE');
|
|
33
|
+
}
|
|
34
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
35
|
+
return view.getUint32(0, true);
|
|
36
|
+
};
|
|
37
|
+
uint32LEDecode.bytes = 4;
|
|
38
|
+
// uint32LEEncode adds the length prefix.
|
|
39
|
+
const uint32LEEncode = (value, target, offset) => {
|
|
40
|
+
target = target ?? new Uint8Array(4);
|
|
41
|
+
const view = new DataView(target.buffer, target.byteOffset, target.byteLength);
|
|
42
|
+
view.setUint32(offset ?? 0, value, true);
|
|
43
|
+
return target;
|
|
44
|
+
};
|
|
45
|
+
uint32LEEncode.bytes = 4;
|
|
46
|
+
// prependLengthPrefixTransform adds a length prefix to a message source.
|
|
47
|
+
// little-endian uint32
|
|
48
|
+
export function prependLengthPrefixTransform() {
|
|
49
|
+
return lengthPrefixEncode({ lengthEncoder: uint32LEEncode });
|
|
50
|
+
}
|
|
51
|
+
// parseLengthPrefixTransform parses the length prefix from a message source.
|
|
52
|
+
// little-endian uint32
|
|
53
|
+
export function parseLengthPrefixTransform() {
|
|
54
|
+
return lengthPrefixDecode({ lengthDecoder: uint32LEDecode });
|
|
55
|
+
}
|
|
56
|
+
// encodeUint32Le encodes the number as a uint32 with little endian.
|
|
57
|
+
export function encodeUint32Le(value) {
|
|
58
|
+
// output is a 4 byte array
|
|
59
|
+
const output = new Uint8Array(4);
|
|
60
|
+
for (let index = 0; index < output.length; index++) {
|
|
61
|
+
const b = value & 0xff;
|
|
62
|
+
output[index] = b;
|
|
63
|
+
value = (value - b) / 256;
|
|
64
|
+
}
|
|
65
|
+
return output;
|
|
66
|
+
}
|
|
67
|
+
// decodeUint32Le decodes a uint32 from a 4 byte Uint8Array.
|
|
68
|
+
// returns 0 if decoding failed.
|
|
69
|
+
// callers should check that len(data) == 4
|
|
70
|
+
export function decodeUint32Le(data) {
|
|
71
|
+
let value = 0;
|
|
72
|
+
let nbytes = 4;
|
|
73
|
+
if (data.length < nbytes) {
|
|
74
|
+
nbytes = data.length;
|
|
75
|
+
}
|
|
76
|
+
for (let i = nbytes - 1; i >= 0; i--) {
|
|
77
|
+
value = value * 256 + data[i];
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
// prependPacketLen adds the message length prefix to a packet.
|
|
82
|
+
export function prependPacketLen(msgData) {
|
|
83
|
+
const msgLen = msgData.length;
|
|
84
|
+
const msgLenData = encodeUint32Le(msgLen);
|
|
85
|
+
const merged = new Uint8Array(msgLen + msgLenData.length);
|
|
86
|
+
merged.set(msgLenData);
|
|
87
|
+
merged.set(msgData, msgLenData.length);
|
|
88
|
+
return merged;
|
|
89
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import Long from 'long';
|
|
2
|
+
import * as _m0 from 'protobufjs/minimal';
|
|
3
|
+
export declare const protobufPackage = "srpc";
|
|
4
|
+
/** Packet is a message sent over a srpc packet connection. */
|
|
5
|
+
export interface Packet {
|
|
6
|
+
body?: {
|
|
7
|
+
$case: 'callStart';
|
|
8
|
+
callStart: CallStart;
|
|
9
|
+
} | {
|
|
10
|
+
$case: 'callStartResp';
|
|
11
|
+
callStartResp: CallStartResp;
|
|
12
|
+
} | {
|
|
13
|
+
$case: 'callData';
|
|
14
|
+
callData: CallData;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** CallStart requests starting a new RPC call. */
|
|
18
|
+
export interface CallStart {
|
|
19
|
+
/**
|
|
20
|
+
* RpcService is the service to contact.
|
|
21
|
+
* Must be set.
|
|
22
|
+
*/
|
|
23
|
+
rpcService: string;
|
|
24
|
+
/**
|
|
25
|
+
* RpcMethod is the RPC method to call.
|
|
26
|
+
* Must be set.
|
|
27
|
+
*/
|
|
28
|
+
rpcMethod: string;
|
|
29
|
+
/**
|
|
30
|
+
* Data contains the request or the first message in the stream.
|
|
31
|
+
* Optional if streaming.
|
|
32
|
+
*/
|
|
33
|
+
data: Uint8Array;
|
|
34
|
+
}
|
|
35
|
+
/** CallStartResp is the response to CallStart. */
|
|
36
|
+
export interface CallStartResp {
|
|
37
|
+
/**
|
|
38
|
+
* Error contains any error starting the RPC call.
|
|
39
|
+
* Empty if successful.
|
|
40
|
+
*/
|
|
41
|
+
error: string;
|
|
42
|
+
}
|
|
43
|
+
/** CallData contains a message in a streaming RPC sequence. */
|
|
44
|
+
export interface CallData {
|
|
45
|
+
/** Data contains the packet in the sequence. */
|
|
46
|
+
data: Uint8Array;
|
|
47
|
+
/** Complete indicates the RPC call is completed. */
|
|
48
|
+
complete: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Error contains any error that caused the RPC to fail.
|
|
51
|
+
* If set, implies complete=true.
|
|
52
|
+
*/
|
|
53
|
+
error: string;
|
|
54
|
+
}
|
|
55
|
+
export declare const Packet: {
|
|
56
|
+
encode(message: Packet, writer?: _m0.Writer): _m0.Writer;
|
|
57
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): Packet;
|
|
58
|
+
fromJSON(object: any): Packet;
|
|
59
|
+
toJSON(message: Packet): unknown;
|
|
60
|
+
fromPartial<I extends {
|
|
61
|
+
body?: ({
|
|
62
|
+
callStart?: {
|
|
63
|
+
rpcService?: string | undefined;
|
|
64
|
+
rpcMethod?: string | undefined;
|
|
65
|
+
data?: Uint8Array | undefined;
|
|
66
|
+
} | undefined;
|
|
67
|
+
} & {
|
|
68
|
+
$case: "callStart";
|
|
69
|
+
}) | ({
|
|
70
|
+
callStartResp?: {
|
|
71
|
+
error?: string | undefined;
|
|
72
|
+
} | undefined;
|
|
73
|
+
} & {
|
|
74
|
+
$case: "callStartResp";
|
|
75
|
+
}) | ({
|
|
76
|
+
callData?: {
|
|
77
|
+
data?: Uint8Array | undefined;
|
|
78
|
+
complete?: boolean | undefined;
|
|
79
|
+
error?: string | undefined;
|
|
80
|
+
} | undefined;
|
|
81
|
+
} & {
|
|
82
|
+
$case: "callData";
|
|
83
|
+
}) | undefined;
|
|
84
|
+
} & {
|
|
85
|
+
body?: ({
|
|
86
|
+
callStart?: {
|
|
87
|
+
rpcService?: string | undefined;
|
|
88
|
+
rpcMethod?: string | undefined;
|
|
89
|
+
data?: Uint8Array | undefined;
|
|
90
|
+
} | undefined;
|
|
91
|
+
} & {
|
|
92
|
+
$case: "callStart";
|
|
93
|
+
} & {
|
|
94
|
+
callStart?: ({
|
|
95
|
+
rpcService?: string | undefined;
|
|
96
|
+
rpcMethod?: string | undefined;
|
|
97
|
+
data?: Uint8Array | undefined;
|
|
98
|
+
} & {
|
|
99
|
+
rpcService?: string | undefined;
|
|
100
|
+
rpcMethod?: string | undefined;
|
|
101
|
+
data?: Uint8Array | undefined;
|
|
102
|
+
} & Record<Exclude<keyof I["body"]["callStart"], keyof CallStart>, never>) | undefined;
|
|
103
|
+
$case: "callStart";
|
|
104
|
+
} & Record<Exclude<keyof I["body"], "$case" | "callStart">, never>) | ({
|
|
105
|
+
callStartResp?: {
|
|
106
|
+
error?: string | undefined;
|
|
107
|
+
} | undefined;
|
|
108
|
+
} & {
|
|
109
|
+
$case: "callStartResp";
|
|
110
|
+
} & {
|
|
111
|
+
callStartResp?: ({
|
|
112
|
+
error?: string | undefined;
|
|
113
|
+
} & {
|
|
114
|
+
error?: string | undefined;
|
|
115
|
+
} & Record<Exclude<keyof I["body"]["callStartResp"], "error">, never>) | undefined;
|
|
116
|
+
$case: "callStartResp";
|
|
117
|
+
} & Record<Exclude<keyof I["body"], "$case" | "callStartResp">, never>) | ({
|
|
118
|
+
callData?: {
|
|
119
|
+
data?: Uint8Array | undefined;
|
|
120
|
+
complete?: boolean | undefined;
|
|
121
|
+
error?: string | undefined;
|
|
122
|
+
} | undefined;
|
|
123
|
+
} & {
|
|
124
|
+
$case: "callData";
|
|
125
|
+
} & {
|
|
126
|
+
callData?: ({
|
|
127
|
+
data?: Uint8Array | undefined;
|
|
128
|
+
complete?: boolean | undefined;
|
|
129
|
+
error?: string | undefined;
|
|
130
|
+
} & {
|
|
131
|
+
data?: Uint8Array | undefined;
|
|
132
|
+
complete?: boolean | undefined;
|
|
133
|
+
error?: string | undefined;
|
|
134
|
+
} & Record<Exclude<keyof I["body"]["callData"], keyof CallData>, never>) | undefined;
|
|
135
|
+
$case: "callData";
|
|
136
|
+
} & Record<Exclude<keyof I["body"], "$case" | "callData">, never>) | undefined;
|
|
137
|
+
} & Record<Exclude<keyof I, "body">, never>>(object: I): Packet;
|
|
138
|
+
};
|
|
139
|
+
export declare const CallStart: {
|
|
140
|
+
encode(message: CallStart, writer?: _m0.Writer): _m0.Writer;
|
|
141
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): CallStart;
|
|
142
|
+
fromJSON(object: any): CallStart;
|
|
143
|
+
toJSON(message: CallStart): unknown;
|
|
144
|
+
fromPartial<I extends {
|
|
145
|
+
rpcService?: string | undefined;
|
|
146
|
+
rpcMethod?: string | undefined;
|
|
147
|
+
data?: Uint8Array | undefined;
|
|
148
|
+
} & {
|
|
149
|
+
rpcService?: string | undefined;
|
|
150
|
+
rpcMethod?: string | undefined;
|
|
151
|
+
data?: Uint8Array | undefined;
|
|
152
|
+
} & Record<Exclude<keyof I, keyof CallStart>, never>>(object: I): CallStart;
|
|
153
|
+
};
|
|
154
|
+
export declare const CallStartResp: {
|
|
155
|
+
encode(message: CallStartResp, writer?: _m0.Writer): _m0.Writer;
|
|
156
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): CallStartResp;
|
|
157
|
+
fromJSON(object: any): CallStartResp;
|
|
158
|
+
toJSON(message: CallStartResp): unknown;
|
|
159
|
+
fromPartial<I extends {
|
|
160
|
+
error?: string | undefined;
|
|
161
|
+
} & {
|
|
162
|
+
error?: string | undefined;
|
|
163
|
+
} & Record<Exclude<keyof I, "error">, never>>(object: I): CallStartResp;
|
|
164
|
+
};
|
|
165
|
+
export declare const CallData: {
|
|
166
|
+
encode(message: CallData, writer?: _m0.Writer): _m0.Writer;
|
|
167
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): CallData;
|
|
168
|
+
fromJSON(object: any): CallData;
|
|
169
|
+
toJSON(message: CallData): unknown;
|
|
170
|
+
fromPartial<I extends {
|
|
171
|
+
data?: Uint8Array | undefined;
|
|
172
|
+
complete?: boolean | undefined;
|
|
173
|
+
error?: string | undefined;
|
|
174
|
+
} & {
|
|
175
|
+
data?: Uint8Array | undefined;
|
|
176
|
+
complete?: boolean | undefined;
|
|
177
|
+
error?: string | undefined;
|
|
178
|
+
} & Record<Exclude<keyof I, keyof CallData>, never>>(object: I): CallData;
|
|
179
|
+
};
|
|
180
|
+
declare type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
181
|
+
export declare type DeepPartial<T> = T extends Builtin ? T : T extends Long ? string | number | Long : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {
|
|
182
|
+
$case: string;
|
|
183
|
+
} ? {
|
|
184
|
+
[K in keyof Omit<T, '$case'>]?: DeepPartial<T[K]>;
|
|
185
|
+
} & {
|
|
186
|
+
$case: T['$case'];
|
|
187
|
+
} : T extends {} ? {
|
|
188
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
189
|
+
} : Partial<T>;
|
|
190
|
+
declare type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
191
|
+
export declare type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
|
192
|
+
[K in keyof P]: Exact<P[K], I[K]>;
|
|
193
|
+
} & Record<Exclude<keyof I, KeysOfUnion<P>>, never>;
|
|
194
|
+
export {};
|