starpc 0.1.7 → 0.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/Makefile +1 -0
- package/README.md +24 -5
- package/dist/echo/client-test.d.ts +2 -0
- package/dist/echo/client-test.js +35 -0
- package/dist/echo/echo.d.ts +124 -0
- package/dist/echo/echo.js +42 -0
- package/dist/echo/index.d.ts +3 -0
- package/dist/echo/index.js +3 -0
- package/dist/echo/server.d.ts +8 -0
- package/dist/echo/server.js +50 -0
- package/dist/echo/sever.d.ts +0 -0
- package/dist/echo/sever.js +1 -0
- package/dist/srpc/broadcast-channel.d.ts +3 -2
- package/dist/srpc/broadcast-channel.js +2 -2
- package/dist/srpc/client-rpc.d.ts +4 -28
- package/dist/srpc/client-rpc.js +9 -152
- package/dist/srpc/client.d.ts +2 -2
- package/dist/srpc/client.js +56 -84
- package/dist/srpc/common-rpc.d.ts +24 -0
- package/dist/srpc/common-rpc.js +140 -0
- package/dist/srpc/conn.d.ts +8 -3
- package/dist/srpc/conn.js +19 -3
- package/dist/srpc/definition.d.ts +15 -0
- package/dist/srpc/definition.js +1 -0
- package/dist/srpc/handler.d.ts +24 -0
- package/dist/srpc/handler.js +123 -0
- package/dist/srpc/index.d.ts +7 -3
- package/dist/srpc/index.js +6 -2
- package/dist/srpc/message.d.ts +11 -0
- package/dist/srpc/message.js +32 -0
- package/dist/srpc/mux.d.ts +11 -0
- package/dist/srpc/mux.js +36 -0
- package/dist/srpc/packet.d.ts +4 -4
- package/dist/srpc/packet.js +38 -27
- package/dist/srpc/rpcproto.d.ts +18 -43
- package/dist/srpc/rpcproto.js +37 -78
- package/dist/srpc/server-rpc.d.ts +11 -0
- package/dist/srpc/server-rpc.js +55 -0
- package/dist/srpc/server.d.ts +14 -0
- package/dist/srpc/server.js +31 -0
- package/dist/srpc/websocket.d.ts +3 -2
- package/dist/srpc/websocket.js +4 -4
- package/e2e/README.md +10 -0
- package/e2e/e2e.ts +27 -0
- package/echo/client-test.ts +41 -0
- package/echo/echo.ts +45 -0
- package/echo/index.ts +3 -0
- package/echo/server.ts +57 -0
- package/echo/sever.ts +0 -0
- package/integration/integration.bash +1 -1
- package/integration/integration.ts +10 -42
- package/package.json +18 -17
- package/srpc/broadcast-channel.ts +8 -3
- package/srpc/client-rpc.go +1 -9
- package/srpc/client-rpc.ts +11 -175
- package/srpc/client.ts +58 -99
- package/srpc/common-rpc.ts +171 -0
- package/srpc/conn.ts +33 -5
- package/srpc/definition.ts +30 -0
- package/srpc/handler.ts +174 -0
- package/srpc/index.ts +7 -3
- package/srpc/message.ts +60 -0
- package/srpc/mux.ts +56 -0
- package/srpc/packet.go +4 -11
- package/srpc/packet.ts +44 -30
- package/srpc/rpcproto.pb.go +54 -118
- package/srpc/rpcproto.proto +7 -12
- package/srpc/rpcproto.ts +38 -101
- package/srpc/rpcproto_vtproto.pb.go +58 -210
- package/srpc/server-rpc.go +5 -10
- package/srpc/server-rpc.ts +65 -0
- package/srpc/server.ts +56 -0
- package/srpc/websocket.ts +6 -4
package/dist/srpc/mux.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// createMux builds a new Mux.
|
|
2
|
+
export function createMux() {
|
|
3
|
+
return new StaticMux();
|
|
4
|
+
}
|
|
5
|
+
// StaticMux contains a in-memory mapping between service ID and handlers.
|
|
6
|
+
// implements Mux
|
|
7
|
+
export class StaticMux {
|
|
8
|
+
// services contains a mapping from service id to handlers.
|
|
9
|
+
services = {};
|
|
10
|
+
register(handler) {
|
|
11
|
+
const serviceID = handler?.getServiceID();
|
|
12
|
+
if (!serviceID) {
|
|
13
|
+
throw new Error('service id cannot be empty');
|
|
14
|
+
}
|
|
15
|
+
const serviceMethods = this.services[serviceID] || {};
|
|
16
|
+
const methodIDs = handler.getMethodIDs();
|
|
17
|
+
for (const methodID of methodIDs) {
|
|
18
|
+
serviceMethods[methodID] = handler;
|
|
19
|
+
}
|
|
20
|
+
this.services[serviceID] = serviceMethods;
|
|
21
|
+
}
|
|
22
|
+
async lookupMethod(serviceID, methodID) {
|
|
23
|
+
if (!serviceID) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const serviceMethods = this.services[serviceID];
|
|
27
|
+
if (!serviceMethods) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const handler = serviceMethods[methodID];
|
|
31
|
+
if (!handler) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return await handler.lookupMethod(serviceID, methodID);
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/srpc/packet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { Packet } from './rpcproto';
|
|
3
|
-
export declare
|
|
4
|
-
export declare
|
|
1
|
+
import type { Transform } from 'it-stream-types';
|
|
2
|
+
import { Packet } from './rpcproto.js';
|
|
3
|
+
export declare const decodePacketSource: (source: import("it-stream-types").Source<Uint8Array | Uint8Array[]>) => AsyncIterable<Packet>;
|
|
4
|
+
export declare const encodePacketSource: (source: import("it-stream-types").Source<Packet | Packet[]>) => AsyncIterable<Uint8Array>;
|
|
5
5
|
export declare function prependLengthPrefixTransform(): Transform<Uint8Array>;
|
|
6
6
|
export declare function parseLengthPrefixTransform(): Transform<Uint8Array>;
|
|
7
7
|
export declare function encodeUint32Le(value: number): Uint8Array;
|
package/dist/srpc/packet.js
CHANGED
|
@@ -1,31 +1,10 @@
|
|
|
1
|
-
import { Packet } from './rpcproto';
|
|
2
1
|
import { encode as lengthPrefixEncode, decode as lengthPrefixDecode, } from 'it-length-prefixed';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
}
|
|
2
|
+
import { Packet } from './rpcproto.js';
|
|
3
|
+
import { buildDecodeMessageTransform, buildEncodeMessageTransform, } from './message.js';
|
|
4
|
+
// decodePacketSource decodes packets from a binary data stream.
|
|
5
|
+
export const decodePacketSource = buildDecodeMessageTransform(Packet);
|
|
6
|
+
// encodePacketSource encodes packets from a packet object stream.
|
|
7
|
+
export const encodePacketSource = buildEncodeMessageTransform(Packet);
|
|
29
8
|
// uint32LEDecode removes the length prefix.
|
|
30
9
|
const uint32LEDecode = (data) => {
|
|
31
10
|
if (data.length < 4) {
|
|
@@ -87,3 +66,35 @@ export function prependPacketLen(msgData) {
|
|
|
87
66
|
merged.set(msgData, msgLenData.length);
|
|
88
67
|
return merged;
|
|
89
68
|
}
|
|
69
|
+
/*
|
|
70
|
+
// buildCallDataPacket builds a CallData packet.
|
|
71
|
+
function buildCallDataPacket(data: Uint8Array): Packet {
|
|
72
|
+
const callData: CallData = {
|
|
73
|
+
data: p,
|
|
74
|
+
complete: false,
|
|
75
|
+
error: '',
|
|
76
|
+
}
|
|
77
|
+
const pkt: Packet = {
|
|
78
|
+
body: {
|
|
79
|
+
$case: 'callData',
|
|
80
|
+
callData: callData,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return pkt
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// wrapCallDataTransform is a transformer that wraps call data into a Packet.
|
|
87
|
+
export async function* wrapCallDataTransform(
|
|
88
|
+
source: Source<Uint8Array | Uint8Array>
|
|
89
|
+
): AsyncIterable<Packet> {
|
|
90
|
+
for await (const pkt of source) {
|
|
91
|
+
if (Array.isArray(pkt)) {
|
|
92
|
+
for (const p of pkt) {
|
|
93
|
+
yield* [buildCallDataPacket(p)]
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
yield* [buildCallDataPacket(pkt)]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
*/
|
package/dist/srpc/rpcproto.d.ts
CHANGED
|
@@ -6,9 +6,6 @@ export interface Packet {
|
|
|
6
6
|
body?: {
|
|
7
7
|
$case: 'callStart';
|
|
8
8
|
callStart: CallStart;
|
|
9
|
-
} | {
|
|
10
|
-
$case: 'callStartResp';
|
|
11
|
-
callStartResp: CallStartResp;
|
|
12
9
|
} | {
|
|
13
10
|
$case: 'callData';
|
|
14
11
|
callData: CallData;
|
|
@@ -31,19 +28,15 @@ export interface CallStart {
|
|
|
31
28
|
* Optional if streaming.
|
|
32
29
|
*/
|
|
33
30
|
data: Uint8Array;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export interface CallStartResp {
|
|
37
|
-
/**
|
|
38
|
-
* Error contains any error starting the RPC call.
|
|
39
|
-
* Empty if successful.
|
|
40
|
-
*/
|
|
41
|
-
error: string;
|
|
31
|
+
/** DataIsZero indicates Data is set with an empty message. */
|
|
32
|
+
dataIsZero: boolean;
|
|
42
33
|
}
|
|
43
34
|
/** CallData contains a message in a streaming RPC sequence. */
|
|
44
35
|
export interface CallData {
|
|
45
36
|
/** Data contains the packet in the sequence. */
|
|
46
37
|
data: Uint8Array;
|
|
38
|
+
/** DataIsZero indicates Data is set with an empty message. */
|
|
39
|
+
dataIsZero: boolean;
|
|
47
40
|
/** Complete indicates the RPC call is completed. */
|
|
48
41
|
complete: boolean;
|
|
49
42
|
/**
|
|
@@ -63,18 +56,14 @@ export declare const Packet: {
|
|
|
63
56
|
rpcService?: string | undefined;
|
|
64
57
|
rpcMethod?: string | undefined;
|
|
65
58
|
data?: Uint8Array | undefined;
|
|
59
|
+
dataIsZero?: boolean | undefined;
|
|
66
60
|
} | undefined;
|
|
67
61
|
} & {
|
|
68
62
|
$case: "callStart";
|
|
69
|
-
}) | ({
|
|
70
|
-
callStartResp?: {
|
|
71
|
-
error?: string | undefined;
|
|
72
|
-
} | undefined;
|
|
73
|
-
} & {
|
|
74
|
-
$case: "callStartResp";
|
|
75
63
|
}) | ({
|
|
76
64
|
callData?: {
|
|
77
65
|
data?: Uint8Array | undefined;
|
|
66
|
+
dataIsZero?: boolean | undefined;
|
|
78
67
|
complete?: boolean | undefined;
|
|
79
68
|
error?: string | undefined;
|
|
80
69
|
} | undefined;
|
|
@@ -87,6 +76,7 @@ export declare const Packet: {
|
|
|
87
76
|
rpcService?: string | undefined;
|
|
88
77
|
rpcMethod?: string | undefined;
|
|
89
78
|
data?: Uint8Array | undefined;
|
|
79
|
+
dataIsZero?: boolean | undefined;
|
|
90
80
|
} | undefined;
|
|
91
81
|
} & {
|
|
92
82
|
$case: "callStart";
|
|
@@ -95,28 +85,18 @@ export declare const Packet: {
|
|
|
95
85
|
rpcService?: string | undefined;
|
|
96
86
|
rpcMethod?: string | undefined;
|
|
97
87
|
data?: Uint8Array | undefined;
|
|
88
|
+
dataIsZero?: boolean | undefined;
|
|
98
89
|
} & {
|
|
99
90
|
rpcService?: string | undefined;
|
|
100
91
|
rpcMethod?: string | undefined;
|
|
101
92
|
data?: Uint8Array | undefined;
|
|
93
|
+
dataIsZero?: boolean | undefined;
|
|
102
94
|
} & Record<Exclude<keyof I["body"]["callStart"], keyof CallStart>, never>) | undefined;
|
|
103
95
|
$case: "callStart";
|
|
104
|
-
} & Record<Exclude<keyof I["body"], "
|
|
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>) | ({
|
|
96
|
+
} & Record<Exclude<keyof I["body"], "callStart" | "$case">, never>) | ({
|
|
118
97
|
callData?: {
|
|
119
98
|
data?: Uint8Array | undefined;
|
|
99
|
+
dataIsZero?: boolean | undefined;
|
|
120
100
|
complete?: boolean | undefined;
|
|
121
101
|
error?: string | undefined;
|
|
122
102
|
} | undefined;
|
|
@@ -125,15 +105,17 @@ export declare const Packet: {
|
|
|
125
105
|
} & {
|
|
126
106
|
callData?: ({
|
|
127
107
|
data?: Uint8Array | undefined;
|
|
108
|
+
dataIsZero?: boolean | undefined;
|
|
128
109
|
complete?: boolean | undefined;
|
|
129
110
|
error?: string | undefined;
|
|
130
111
|
} & {
|
|
131
112
|
data?: Uint8Array | undefined;
|
|
113
|
+
dataIsZero?: boolean | undefined;
|
|
132
114
|
complete?: boolean | undefined;
|
|
133
115
|
error?: string | undefined;
|
|
134
116
|
} & Record<Exclude<keyof I["body"]["callData"], keyof CallData>, never>) | undefined;
|
|
135
117
|
$case: "callData";
|
|
136
|
-
} & Record<Exclude<keyof I["body"], "
|
|
118
|
+
} & Record<Exclude<keyof I["body"], "callData" | "$case">, never>) | undefined;
|
|
137
119
|
} & Record<Exclude<keyof I, "body">, never>>(object: I): Packet;
|
|
138
120
|
};
|
|
139
121
|
export declare const CallStart: {
|
|
@@ -145,23 +127,14 @@ export declare const CallStart: {
|
|
|
145
127
|
rpcService?: string | undefined;
|
|
146
128
|
rpcMethod?: string | undefined;
|
|
147
129
|
data?: Uint8Array | undefined;
|
|
130
|
+
dataIsZero?: boolean | undefined;
|
|
148
131
|
} & {
|
|
149
132
|
rpcService?: string | undefined;
|
|
150
133
|
rpcMethod?: string | undefined;
|
|
151
134
|
data?: Uint8Array | undefined;
|
|
135
|
+
dataIsZero?: boolean | undefined;
|
|
152
136
|
} & Record<Exclude<keyof I, keyof CallStart>, never>>(object: I): CallStart;
|
|
153
137
|
};
|
|
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
138
|
export declare const CallData: {
|
|
166
139
|
encode(message: CallData, writer?: _m0.Writer): _m0.Writer;
|
|
167
140
|
decode(input: _m0.Reader | Uint8Array, length?: number): CallData;
|
|
@@ -169,10 +142,12 @@ export declare const CallData: {
|
|
|
169
142
|
toJSON(message: CallData): unknown;
|
|
170
143
|
fromPartial<I extends {
|
|
171
144
|
data?: Uint8Array | undefined;
|
|
145
|
+
dataIsZero?: boolean | undefined;
|
|
172
146
|
complete?: boolean | undefined;
|
|
173
147
|
error?: string | undefined;
|
|
174
148
|
} & {
|
|
175
149
|
data?: Uint8Array | undefined;
|
|
150
|
+
dataIsZero?: boolean | undefined;
|
|
176
151
|
complete?: boolean | undefined;
|
|
177
152
|
error?: string | undefined;
|
|
178
153
|
} & Record<Exclude<keyof I, keyof CallData>, never>>(object: I): CallData;
|
package/dist/srpc/rpcproto.js
CHANGED
|
@@ -10,11 +10,8 @@ export const Packet = {
|
|
|
10
10
|
if (message.body?.$case === 'callStart') {
|
|
11
11
|
CallStart.encode(message.body.callStart, writer.uint32(10).fork()).ldelim();
|
|
12
12
|
}
|
|
13
|
-
if (message.body?.$case === 'callStartResp') {
|
|
14
|
-
CallStartResp.encode(message.body.callStartResp, writer.uint32(18).fork()).ldelim();
|
|
15
|
-
}
|
|
16
13
|
if (message.body?.$case === 'callData') {
|
|
17
|
-
CallData.encode(message.body.callData, writer.uint32(
|
|
14
|
+
CallData.encode(message.body.callData, writer.uint32(18).fork()).ldelim();
|
|
18
15
|
}
|
|
19
16
|
return writer;
|
|
20
17
|
},
|
|
@@ -32,12 +29,6 @@ export const Packet = {
|
|
|
32
29
|
};
|
|
33
30
|
break;
|
|
34
31
|
case 2:
|
|
35
|
-
message.body = {
|
|
36
|
-
$case: 'callStartResp',
|
|
37
|
-
callStartResp: CallStartResp.decode(reader, reader.uint32()),
|
|
38
|
-
};
|
|
39
|
-
break;
|
|
40
|
-
case 3:
|
|
41
32
|
message.body = {
|
|
42
33
|
$case: 'callData',
|
|
43
34
|
callData: CallData.decode(reader, reader.uint32()),
|
|
@@ -57,14 +48,9 @@ export const Packet = {
|
|
|
57
48
|
$case: 'callStart',
|
|
58
49
|
callStart: CallStart.fromJSON(object.callStart),
|
|
59
50
|
}
|
|
60
|
-
: isSet(object.
|
|
61
|
-
? {
|
|
62
|
-
|
|
63
|
-
callStartResp: CallStartResp.fromJSON(object.callStartResp),
|
|
64
|
-
}
|
|
65
|
-
: isSet(object.callData)
|
|
66
|
-
? { $case: 'callData', callData: CallData.fromJSON(object.callData) }
|
|
67
|
-
: undefined,
|
|
51
|
+
: isSet(object.callData)
|
|
52
|
+
? { $case: 'callData', callData: CallData.fromJSON(object.callData) }
|
|
53
|
+
: undefined,
|
|
68
54
|
};
|
|
69
55
|
},
|
|
70
56
|
toJSON(message) {
|
|
@@ -73,10 +59,6 @@ export const Packet = {
|
|
|
73
59
|
(obj.callStart = message.body?.callStart
|
|
74
60
|
? CallStart.toJSON(message.body?.callStart)
|
|
75
61
|
: undefined);
|
|
76
|
-
message.body?.$case === 'callStartResp' &&
|
|
77
|
-
(obj.callStartResp = message.body?.callStartResp
|
|
78
|
-
? CallStartResp.toJSON(message.body?.callStartResp)
|
|
79
|
-
: undefined);
|
|
80
62
|
message.body?.$case === 'callData' &&
|
|
81
63
|
(obj.callData = message.body?.callData
|
|
82
64
|
? CallData.toJSON(message.body?.callData)
|
|
@@ -93,14 +75,6 @@ export const Packet = {
|
|
|
93
75
|
callStart: CallStart.fromPartial(object.body.callStart),
|
|
94
76
|
};
|
|
95
77
|
}
|
|
96
|
-
if (object.body?.$case === 'callStartResp' &&
|
|
97
|
-
object.body?.callStartResp !== undefined &&
|
|
98
|
-
object.body?.callStartResp !== null) {
|
|
99
|
-
message.body = {
|
|
100
|
-
$case: 'callStartResp',
|
|
101
|
-
callStartResp: CallStartResp.fromPartial(object.body.callStartResp),
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
78
|
if (object.body?.$case === 'callData' &&
|
|
105
79
|
object.body?.callData !== undefined &&
|
|
106
80
|
object.body?.callData !== null) {
|
|
@@ -113,7 +87,12 @@ export const Packet = {
|
|
|
113
87
|
},
|
|
114
88
|
};
|
|
115
89
|
function createBaseCallStart() {
|
|
116
|
-
return {
|
|
90
|
+
return {
|
|
91
|
+
rpcService: '',
|
|
92
|
+
rpcMethod: '',
|
|
93
|
+
data: new Uint8Array(),
|
|
94
|
+
dataIsZero: false,
|
|
95
|
+
};
|
|
117
96
|
}
|
|
118
97
|
export const CallStart = {
|
|
119
98
|
encode(message, writer = _m0.Writer.create()) {
|
|
@@ -126,6 +105,9 @@ export const CallStart = {
|
|
|
126
105
|
if (message.data.length !== 0) {
|
|
127
106
|
writer.uint32(26).bytes(message.data);
|
|
128
107
|
}
|
|
108
|
+
if (message.dataIsZero === true) {
|
|
109
|
+
writer.uint32(32).bool(message.dataIsZero);
|
|
110
|
+
}
|
|
129
111
|
return writer;
|
|
130
112
|
},
|
|
131
113
|
decode(input, length) {
|
|
@@ -144,6 +126,9 @@ export const CallStart = {
|
|
|
144
126
|
case 3:
|
|
145
127
|
message.data = reader.bytes();
|
|
146
128
|
break;
|
|
129
|
+
case 4:
|
|
130
|
+
message.dataIsZero = reader.bool();
|
|
131
|
+
break;
|
|
147
132
|
default:
|
|
148
133
|
reader.skipType(tag & 7);
|
|
149
134
|
break;
|
|
@@ -158,6 +143,7 @@ export const CallStart = {
|
|
|
158
143
|
data: isSet(object.data)
|
|
159
144
|
? bytesFromBase64(object.data)
|
|
160
145
|
: new Uint8Array(),
|
|
146
|
+
dataIsZero: isSet(object.dataIsZero) ? Boolean(object.dataIsZero) : false,
|
|
161
147
|
};
|
|
162
148
|
},
|
|
163
149
|
toJSON(message) {
|
|
@@ -166,6 +152,7 @@ export const CallStart = {
|
|
|
166
152
|
message.rpcMethod !== undefined && (obj.rpcMethod = message.rpcMethod);
|
|
167
153
|
message.data !== undefined &&
|
|
168
154
|
(obj.data = base64FromBytes(message.data !== undefined ? message.data : new Uint8Array()));
|
|
155
|
+
message.dataIsZero !== undefined && (obj.dataIsZero = message.dataIsZero);
|
|
169
156
|
return obj;
|
|
170
157
|
},
|
|
171
158
|
fromPartial(object) {
|
|
@@ -173,65 +160,31 @@ export const CallStart = {
|
|
|
173
160
|
message.rpcService = object.rpcService ?? '';
|
|
174
161
|
message.rpcMethod = object.rpcMethod ?? '';
|
|
175
162
|
message.data = object.data ?? new Uint8Array();
|
|
176
|
-
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
function createBaseCallStartResp() {
|
|
180
|
-
return { error: '' };
|
|
181
|
-
}
|
|
182
|
-
export const CallStartResp = {
|
|
183
|
-
encode(message, writer = _m0.Writer.create()) {
|
|
184
|
-
if (message.error !== '') {
|
|
185
|
-
writer.uint32(10).string(message.error);
|
|
186
|
-
}
|
|
187
|
-
return writer;
|
|
188
|
-
},
|
|
189
|
-
decode(input, length) {
|
|
190
|
-
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
191
|
-
let end = length === undefined ? reader.len : reader.pos + length;
|
|
192
|
-
const message = createBaseCallStartResp();
|
|
193
|
-
while (reader.pos < end) {
|
|
194
|
-
const tag = reader.uint32();
|
|
195
|
-
switch (tag >>> 3) {
|
|
196
|
-
case 1:
|
|
197
|
-
message.error = reader.string();
|
|
198
|
-
break;
|
|
199
|
-
default:
|
|
200
|
-
reader.skipType(tag & 7);
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return message;
|
|
205
|
-
},
|
|
206
|
-
fromJSON(object) {
|
|
207
|
-
return {
|
|
208
|
-
error: isSet(object.error) ? String(object.error) : '',
|
|
209
|
-
};
|
|
210
|
-
},
|
|
211
|
-
toJSON(message) {
|
|
212
|
-
const obj = {};
|
|
213
|
-
message.error !== undefined && (obj.error = message.error);
|
|
214
|
-
return obj;
|
|
215
|
-
},
|
|
216
|
-
fromPartial(object) {
|
|
217
|
-
const message = createBaseCallStartResp();
|
|
218
|
-
message.error = object.error ?? '';
|
|
163
|
+
message.dataIsZero = object.dataIsZero ?? false;
|
|
219
164
|
return message;
|
|
220
165
|
},
|
|
221
166
|
};
|
|
222
167
|
function createBaseCallData() {
|
|
223
|
-
return {
|
|
168
|
+
return {
|
|
169
|
+
data: new Uint8Array(),
|
|
170
|
+
dataIsZero: false,
|
|
171
|
+
complete: false,
|
|
172
|
+
error: '',
|
|
173
|
+
};
|
|
224
174
|
}
|
|
225
175
|
export const CallData = {
|
|
226
176
|
encode(message, writer = _m0.Writer.create()) {
|
|
227
177
|
if (message.data.length !== 0) {
|
|
228
178
|
writer.uint32(10).bytes(message.data);
|
|
229
179
|
}
|
|
180
|
+
if (message.dataIsZero === true) {
|
|
181
|
+
writer.uint32(16).bool(message.dataIsZero);
|
|
182
|
+
}
|
|
230
183
|
if (message.complete === true) {
|
|
231
|
-
writer.uint32(
|
|
184
|
+
writer.uint32(24).bool(message.complete);
|
|
232
185
|
}
|
|
233
186
|
if (message.error !== '') {
|
|
234
|
-
writer.uint32(
|
|
187
|
+
writer.uint32(34).string(message.error);
|
|
235
188
|
}
|
|
236
189
|
return writer;
|
|
237
190
|
},
|
|
@@ -246,9 +199,12 @@ export const CallData = {
|
|
|
246
199
|
message.data = reader.bytes();
|
|
247
200
|
break;
|
|
248
201
|
case 2:
|
|
249
|
-
message.
|
|
202
|
+
message.dataIsZero = reader.bool();
|
|
250
203
|
break;
|
|
251
204
|
case 3:
|
|
205
|
+
message.complete = reader.bool();
|
|
206
|
+
break;
|
|
207
|
+
case 4:
|
|
252
208
|
message.error = reader.string();
|
|
253
209
|
break;
|
|
254
210
|
default:
|
|
@@ -263,6 +219,7 @@ export const CallData = {
|
|
|
263
219
|
data: isSet(object.data)
|
|
264
220
|
? bytesFromBase64(object.data)
|
|
265
221
|
: new Uint8Array(),
|
|
222
|
+
dataIsZero: isSet(object.dataIsZero) ? Boolean(object.dataIsZero) : false,
|
|
266
223
|
complete: isSet(object.complete) ? Boolean(object.complete) : false,
|
|
267
224
|
error: isSet(object.error) ? String(object.error) : '',
|
|
268
225
|
};
|
|
@@ -271,6 +228,7 @@ export const CallData = {
|
|
|
271
228
|
const obj = {};
|
|
272
229
|
message.data !== undefined &&
|
|
273
230
|
(obj.data = base64FromBytes(message.data !== undefined ? message.data : new Uint8Array()));
|
|
231
|
+
message.dataIsZero !== undefined && (obj.dataIsZero = message.dataIsZero);
|
|
274
232
|
message.complete !== undefined && (obj.complete = message.complete);
|
|
275
233
|
message.error !== undefined && (obj.error = message.error);
|
|
276
234
|
return obj;
|
|
@@ -278,6 +236,7 @@ export const CallData = {
|
|
|
278
236
|
fromPartial(object) {
|
|
279
237
|
const message = createBaseCallData();
|
|
280
238
|
message.data = object.data ?? new Uint8Array();
|
|
239
|
+
message.dataIsZero = object.dataIsZero ?? false;
|
|
281
240
|
message.complete = object.complete ?? false;
|
|
282
241
|
message.error = object.error ?? '';
|
|
283
242
|
return message;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CallData, CallStart } from './rpcproto.js';
|
|
2
|
+
import { CommonRPC } from './common-rpc.js';
|
|
3
|
+
import { Mux } from './mux.js';
|
|
4
|
+
export declare class ServerRPC extends CommonRPC {
|
|
5
|
+
private mux;
|
|
6
|
+
constructor(mux: Mux);
|
|
7
|
+
handleCallStart(packet: Partial<CallStart>): Promise<void>;
|
|
8
|
+
handleCallData(packet: Partial<CallData>): Promise<void>;
|
|
9
|
+
private invokeRPC;
|
|
10
|
+
private _createDataSink;
|
|
11
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CommonRPC } from './common-rpc.js';
|
|
2
|
+
// ServerRPC is an ongoing RPC from the server side.
|
|
3
|
+
export class ServerRPC extends CommonRPC {
|
|
4
|
+
// mux is used to handle incoming rpcs.
|
|
5
|
+
mux;
|
|
6
|
+
constructor(mux) {
|
|
7
|
+
super();
|
|
8
|
+
this.mux = mux;
|
|
9
|
+
}
|
|
10
|
+
// handleCallStart handles a CallStart cket.
|
|
11
|
+
async handleCallStart(packet) {
|
|
12
|
+
if (this.service || this.method) {
|
|
13
|
+
throw new Error('call start must be sent only once');
|
|
14
|
+
}
|
|
15
|
+
this.service = packet.rpcService;
|
|
16
|
+
this.method = packet.rpcMethod;
|
|
17
|
+
if (!this.service || !this.method) {
|
|
18
|
+
throw new Error('rpcService and rpcMethod cannot be empty');
|
|
19
|
+
}
|
|
20
|
+
const methodDef = await this.mux.lookupMethod(this.service, this.method);
|
|
21
|
+
if (!methodDef) {
|
|
22
|
+
throw new Error(`not found: ${this.service}/${this.method}`);
|
|
23
|
+
}
|
|
24
|
+
this.pushRpcData(packet.data, packet.dataIsZero);
|
|
25
|
+
this.invokeRPC(methodDef);
|
|
26
|
+
}
|
|
27
|
+
// handleCallData handles a CallData packet.
|
|
28
|
+
async handleCallData(packet) {
|
|
29
|
+
if (!this.service || !this.method) {
|
|
30
|
+
throw new Error('call start must be sent before call data');
|
|
31
|
+
}
|
|
32
|
+
return super.handleCallData(packet);
|
|
33
|
+
}
|
|
34
|
+
// invokeRPC starts invoking the RPC handler.
|
|
35
|
+
invokeRPC(invokeFn) {
|
|
36
|
+
const dataSink = this._createDataSink();
|
|
37
|
+
invokeFn(this.rpcDataSource, dataSink).catch((err) => {
|
|
38
|
+
this.close(err);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// _createDataSink creates a sink for outgoing data packets.
|
|
42
|
+
_createDataSink() {
|
|
43
|
+
return async (source) => {
|
|
44
|
+
try {
|
|
45
|
+
for await (const msg of source) {
|
|
46
|
+
await this.writeCallData(msg);
|
|
47
|
+
}
|
|
48
|
+
await this.writeCallData(undefined, true);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
this.close(err);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Stream } from '@libp2p/interface-connection';
|
|
2
|
+
import { Duplex } from 'it-stream-types';
|
|
3
|
+
import { Mux } from './mux.js';
|
|
4
|
+
import { ServerRPC } from './server-rpc.js';
|
|
5
|
+
import { Packet } from './rpcproto.js';
|
|
6
|
+
import { StreamHandler } from './conn.js';
|
|
7
|
+
export declare class Server implements StreamHandler {
|
|
8
|
+
private mux;
|
|
9
|
+
constructor(mux: Mux);
|
|
10
|
+
startRpc(): ServerRPC;
|
|
11
|
+
handleStream(stream: Stream): Promise<void>;
|
|
12
|
+
handleDuplex(stream: Duplex<Uint8Array>): Promise<void>;
|
|
13
|
+
handlePacketStream(stream: Duplex<Packet>): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { pipe } from 'it-pipe';
|
|
2
|
+
import { ServerRPC } from './server-rpc.js';
|
|
3
|
+
import { parseLengthPrefixTransform, prependLengthPrefixTransform, decodePacketSource, encodePacketSource, } from './packet.js';
|
|
4
|
+
// Server implements the SRPC server in TypeScript with a Mux.
|
|
5
|
+
export class Server {
|
|
6
|
+
// mux is the mux used to handle requests.
|
|
7
|
+
mux;
|
|
8
|
+
constructor(mux) {
|
|
9
|
+
this.mux = mux;
|
|
10
|
+
}
|
|
11
|
+
// startRpc starts a new server-side RPC.
|
|
12
|
+
// the returned RPC handles incoming Packets.
|
|
13
|
+
startRpc() {
|
|
14
|
+
return new ServerRPC(this.mux);
|
|
15
|
+
}
|
|
16
|
+
// handleStream handles an incoming Uint8Array message duplex.
|
|
17
|
+
// closes the stream when the rpc completes.
|
|
18
|
+
handleStream(stream) {
|
|
19
|
+
return this.handleDuplex(stream);
|
|
20
|
+
}
|
|
21
|
+
// handleDuplex handles an incoming message duplex.
|
|
22
|
+
async handleDuplex(stream) {
|
|
23
|
+
const rpc = this.startRpc();
|
|
24
|
+
await pipe(stream, parseLengthPrefixTransform(), decodePacketSource, rpc, encodePacketSource, prependLengthPrefixTransform(), stream);
|
|
25
|
+
}
|
|
26
|
+
// handlePacketStream handles an incoming Packet duplex.
|
|
27
|
+
async handlePacketStream(stream) {
|
|
28
|
+
const rpc = this.startRpc();
|
|
29
|
+
await pipe(stream, rpc, stream);
|
|
30
|
+
}
|
|
31
|
+
}
|
package/dist/srpc/websocket.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Conn } from './conn.js';
|
|
2
1
|
import type WebSocket from 'isomorphic-ws';
|
|
2
|
+
import { Conn } from './conn.js';
|
|
3
|
+
import { Server } from './server.js';
|
|
3
4
|
export declare class WebSocketConn extends Conn {
|
|
4
5
|
private socket;
|
|
5
|
-
constructor(socket: WebSocket);
|
|
6
|
+
constructor(socket: WebSocket, server?: Server);
|
|
6
7
|
getSocket(): WebSocket;
|
|
7
8
|
}
|
package/dist/srpc/websocket.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Conn } from './conn.js';
|
|
2
1
|
import { duplex } from 'it-ws';
|
|
3
2
|
import { pipe } from 'it-pipe';
|
|
4
3
|
import { Mplex } from '@libp2p/mplex';
|
|
5
|
-
|
|
4
|
+
import { Conn } from './conn.js';
|
|
5
|
+
// WebSocketConn implements a connection with a WebSocket and optional Server.
|
|
6
6
|
export class WebSocketConn extends Conn {
|
|
7
7
|
// socket is the web socket
|
|
8
8
|
socket;
|
|
9
|
-
constructor(socket) {
|
|
10
|
-
super({
|
|
9
|
+
constructor(socket, server) {
|
|
10
|
+
super(server, {
|
|
11
11
|
muxerFactory: new Mplex(),
|
|
12
12
|
});
|
|
13
13
|
this.socket = socket;
|
package/e2e/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# E2E
|
|
2
|
+
|
|
3
|
+
E2E contains tests using the client and server written in the same language.
|
|
4
|
+
|
|
5
|
+
For example:
|
|
6
|
+
|
|
7
|
+
- Go Client calling Go server: "go test" or "yarn test:go"
|
|
8
|
+
- TypeScript client calling TypeScript server: "yarn test:js"
|
|
9
|
+
|
|
10
|
+
For cross-language tests, i.e. Ts <-> Go, see [integration](../integration).
|