starpc 0.3.5 → 0.4.1
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 +22 -13
- package/README.md +4 -0
- package/dist/echo/client-test.js +1 -1
- package/dist/echo/{echo.d.ts → echo.pb.d.ts} +0 -0
- package/dist/echo/{echo.js → echo.pb.js} +0 -1
- package/dist/echo/index.d.ts +1 -1
- package/dist/echo/index.js +1 -1
- package/dist/echo/server.d.ts +1 -1
- package/dist/rpcstream/rpcstream.d.ts +19 -0
- package/dist/rpcstream/rpcstream.js +94 -0
- package/dist/rpcstream/rpcstream.pb.d.ts +85 -0
- package/dist/rpcstream/rpcstream.pb.js +160 -0
- package/dist/srpc/broadcast-channel.js +0 -10
- package/dist/srpc/client-rpc.d.ts +1 -1
- package/dist/srpc/client.d.ts +5 -5
- package/dist/srpc/client.js +21 -25
- package/dist/srpc/common-rpc.d.ts +2 -2
- package/dist/srpc/common-rpc.js +1 -15
- package/dist/srpc/conn-duplex.js +1 -3
- package/dist/srpc/conn.d.ts +1 -1
- package/dist/srpc/conn.js +0 -4
- package/dist/srpc/handler.js +12 -14
- package/dist/srpc/index.d.ts +2 -1
- package/dist/srpc/index.js +1 -0
- package/dist/srpc/message-port.js +0 -10
- package/dist/srpc/mux.js +4 -2
- package/dist/srpc/observable-source.d.ts +9 -0
- package/dist/srpc/observable-source.js +25 -0
- package/dist/srpc/packet.d.ts +1 -1
- package/dist/srpc/packet.js +1 -1
- package/dist/srpc/{rpcproto.d.ts → rpcproto.pb.d.ts} +0 -0
- package/dist/srpc/{rpcproto.js → rpcproto.pb.js} +0 -0
- package/dist/srpc/server-rpc.d.ts +1 -1
- package/dist/srpc/server-rpc.js +0 -2
- package/dist/srpc/server.d.ts +4 -4
- package/dist/srpc/server.js +6 -7
- package/dist/srpc/stream.d.ts +1 -1
- package/dist/srpc/websocket.js +1 -3
- package/e2e/debug.test +0 -0
- package/e2e/e2e_test.go +20 -2
- package/echo/client-test.ts +1 -1
- package/echo/{echo.ts → echo.pb.ts} +0 -0
- package/echo/index.ts +1 -1
- package/echo/server.ts +1 -1
- package/go.mod +2 -2
- package/go.sum +2 -2
- package/integration/integration.ts +2 -2
- package/package.json +4 -3
- package/srpc/broadcast-channel.ts +1 -1
- package/srpc/client-rpc.go +8 -3
- package/srpc/client-rpc.ts +1 -1
- package/srpc/client.go +4 -4
- package/srpc/client.ts +27 -25
- package/srpc/common-rpc.ts +2 -2
- package/srpc/conn-duplex.ts +1 -1
- package/srpc/conn.ts +1 -1
- package/srpc/handler.ts +14 -10
- package/srpc/index.ts +2 -2
- package/srpc/{rpc-stream.go → msg-stream.go} +13 -13
- package/srpc/muxed-conn.go +31 -0
- package/srpc/observable-source.ts +40 -0
- package/srpc/packet.go +4 -3
- package/srpc/packet.ts +1 -1
- package/srpc/{rpcproto.ts → rpcproto.pb.ts} +0 -0
- package/srpc/server-pipe.go +1 -1
- package/srpc/server-rpc.go +3 -3
- package/srpc/server-rpc.ts +1 -1
- package/srpc/server.go +8 -1
- package/srpc/server.ts +8 -7
- package/srpc/stream.ts +1 -1
- package/srpc/websocket.go +1 -4
- package/srpc/websocket.ts +1 -1
- package/srpc/conn.go +0 -7
package/Makefile
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
# https://github.com/aperturerobotics/protobuf-project
|
|
2
|
+
|
|
1
3
|
PROTOWRAP=hack/bin/protowrap
|
|
2
4
|
PROTOC_GEN_GO=hack/bin/protoc-gen-go
|
|
5
|
+
PROTOC_GEN_GO_STARPC=hack/bin/protoc-gen-go-starpc
|
|
3
6
|
PROTOC_GEN_VTPROTO=hack/bin/protoc-gen-go-vtproto
|
|
4
|
-
PROTOC_GEN_STARPC=hack/bin/protoc-gen-go-starpc
|
|
5
7
|
GOIMPORTS=hack/bin/goimports
|
|
6
8
|
GOLANGCI_LINT=hack/bin/golangci-lint
|
|
7
9
|
GO_MOD_OUTDATED=hack/bin/go-mod-outdated
|
|
8
|
-
export GO111MODULE=on
|
|
9
10
|
GOLIST=go list -f "{{ .Dir }}" -m
|
|
10
11
|
|
|
12
|
+
export GO111MODULE=on
|
|
13
|
+
undefine GOARCH
|
|
14
|
+
undefine GOOS
|
|
15
|
+
|
|
11
16
|
all:
|
|
12
17
|
|
|
13
18
|
vendor:
|
|
@@ -17,19 +22,19 @@ $(PROTOC_GEN_GO):
|
|
|
17
22
|
cd ./hack; \
|
|
18
23
|
go build -v \
|
|
19
24
|
-o ./bin/protoc-gen-go \
|
|
20
|
-
|
|
25
|
+
google.golang.org/protobuf/cmd/protoc-gen-go
|
|
21
26
|
|
|
22
|
-
$(
|
|
27
|
+
$(PROTOC_GEN_GO_STARPC):
|
|
23
28
|
cd ./hack; \
|
|
24
29
|
go build -v \
|
|
25
|
-
-o ./bin/protoc-gen-go-
|
|
26
|
-
github.com/
|
|
30
|
+
-o ./bin/protoc-gen-go-starpc \
|
|
31
|
+
github.com/aperturerobotics/starpc/cmd/protoc-gen-go-starpc
|
|
27
32
|
|
|
28
|
-
$(
|
|
33
|
+
$(PROTOC_GEN_VTPROTO):
|
|
29
34
|
cd ./hack; \
|
|
30
35
|
go build -v \
|
|
31
|
-
-o ./bin/protoc-gen-go-
|
|
32
|
-
github.com/
|
|
36
|
+
-o ./bin/protoc-gen-go-vtproto \
|
|
37
|
+
github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto
|
|
33
38
|
|
|
34
39
|
$(GOIMPORTS):
|
|
35
40
|
cd ./hack; \
|
|
@@ -56,7 +61,7 @@ $(GO_MOD_OUTDATED):
|
|
|
56
61
|
github.com/psampaz/go-mod-outdated
|
|
57
62
|
|
|
58
63
|
.PHONY: gengo
|
|
59
|
-
gengo: $(GOIMPORTS) $(PROTOWRAP) $(PROTOC_GEN_GO) $(
|
|
64
|
+
gengo: $(GOIMPORTS) $(PROTOWRAP) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_STARPC) $(PROTOC_GEN_VTPROTO)
|
|
60
65
|
go mod vendor
|
|
61
66
|
shopt -s globstar; \
|
|
62
67
|
set -eo pipefail; \
|
|
@@ -99,9 +104,10 @@ gents: $(PROTOWRAP) node_modules
|
|
|
99
104
|
-I $$(pwd)/vendor \
|
|
100
105
|
--plugin=./node_modules/.bin/protoc-gen-ts_proto \
|
|
101
106
|
--ts_proto_out=$$(pwd)/vendor \
|
|
107
|
+
--ts_proto_opt=esModuleInterop=true \
|
|
108
|
+
--ts_proto_opt=fileSuffix=.pb \
|
|
102
109
|
--ts_proto_opt=forceLong=long \
|
|
103
110
|
--ts_proto_opt=oneof=unions \
|
|
104
|
-
--ts_proto_opt=esModuleInterop=true \
|
|
105
111
|
--ts_proto_opt=outputServices=default,outputServices=generic-definitions \
|
|
106
112
|
--proto_path $$(pwd)/vendor \
|
|
107
113
|
--print_structure \
|
|
@@ -119,15 +125,19 @@ genproto: gengo gents
|
|
|
119
125
|
.PHONY: gen
|
|
120
126
|
gen: genproto
|
|
121
127
|
|
|
128
|
+
.PHONY: outdated
|
|
122
129
|
outdated: $(GO_MOD_OUTDATED)
|
|
123
130
|
go list -mod=mod -u -m -json all | $(GO_MOD_OUTDATED) -update -direct
|
|
124
131
|
|
|
132
|
+
.PHONY: list
|
|
125
133
|
list: $(GO_MOD_OUTDATED)
|
|
126
134
|
go list -mod=mod -u -m -json all | $(GO_MOD_OUTDATED)
|
|
127
135
|
|
|
136
|
+
.PHONY: lint
|
|
128
137
|
lint: $(GOLANGCI_LINT)
|
|
129
138
|
$(GOLANGCI_LINT) run
|
|
130
139
|
|
|
140
|
+
.PHONY: fix
|
|
131
141
|
fix: $(GOLANGCI_LINT)
|
|
132
142
|
$(GOLANGCI_LINT) run --fix
|
|
133
143
|
|
|
@@ -137,5 +147,4 @@ test:
|
|
|
137
147
|
|
|
138
148
|
.PHONY: integration
|
|
139
149
|
integration: node_modules vendor
|
|
140
|
-
cd ./integration &&
|
|
141
|
-
bash ./integration.bash
|
|
150
|
+
cd ./integration && bash ./integration.bash
|
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ Can use any Stream multiplexer: defaults to [libp2p-mplex] over a WebSocket.
|
|
|
13
13
|
|
|
14
14
|
[libp2p-mplex]: https://github.com/libp2p/js-libp2p-mplex
|
|
15
15
|
|
|
16
|
+
[rpcstream] supports sub-streams for per-component sub-services.
|
|
17
|
+
|
|
18
|
+
[rpcstream]: ./rpcstream
|
|
19
|
+
|
|
16
20
|
# Usage
|
|
17
21
|
|
|
18
22
|
Starting with the [protobuf-project] repository on the "starpc" branch.
|
package/dist/echo/client-test.js
CHANGED
|
File without changes
|
package/dist/echo/index.d.ts
CHANGED
package/dist/echo/index.js
CHANGED
package/dist/echo/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
|
-
import { Echoer, EchoMsg } from './echo';
|
|
2
|
+
import { Echoer, EchoMsg } from './echo.pb.js';
|
|
3
3
|
export declare class EchoerServer implements Echoer {
|
|
4
4
|
Echo(request: EchoMsg): Promise<EchoMsg>;
|
|
5
5
|
EchoServerStream(request: EchoMsg): Observable<EchoMsg>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { Packet } from './rpcstream.pb.js';
|
|
3
|
+
import { Server } from '../srpc/server.js';
|
|
4
|
+
import { OpenStreamFunc, Stream } from '../srpc/stream.js';
|
|
5
|
+
import { Pushable } from 'it-pushable';
|
|
6
|
+
import { Source, Sink } from 'it-stream-types';
|
|
7
|
+
export declare type RpcStreamCaller = (request: Observable<Packet>) => Observable<Packet>;
|
|
8
|
+
export declare function buildRpcStreamOpenStream(componentId: string, caller: RpcStreamCaller): OpenStreamFunc;
|
|
9
|
+
export declare type RpcStreamGetter = (componentId: string) => Promise<Server>;
|
|
10
|
+
export declare function handleRpcStream(stream: Observable<Packet>, getter: RpcStreamGetter): AsyncIterable<Packet>;
|
|
11
|
+
export declare class RpcStream implements Stream {
|
|
12
|
+
readonly source: Source<Uint8Array>;
|
|
13
|
+
readonly sink: Sink<Uint8Array>;
|
|
14
|
+
private readonly _packetSink;
|
|
15
|
+
private readonly _source;
|
|
16
|
+
constructor(packetSink: Pushable<Packet>, packetSource: Observable<Packet>);
|
|
17
|
+
private _createSink;
|
|
18
|
+
private _subscribePacketSource;
|
|
19
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { from as obsFrom } from 'rxjs';
|
|
2
|
+
import { pushable } from 'it-pushable';
|
|
3
|
+
// buildRpcStreamOpenStream builds a OpenStream func with a RpcStream.
|
|
4
|
+
export function buildRpcStreamOpenStream(componentId, caller) {
|
|
5
|
+
return async () => {
|
|
6
|
+
const packetSink = pushable({ objectMode: true });
|
|
7
|
+
const packetObs = obsFrom(packetSink);
|
|
8
|
+
const packetSource = caller(packetObs);
|
|
9
|
+
// write the component id
|
|
10
|
+
packetSink.push({
|
|
11
|
+
body: {
|
|
12
|
+
$case: 'init',
|
|
13
|
+
init: { componentId },
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
// build & return the stream
|
|
17
|
+
return new RpcStream(packetSink, packetSource);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// handleRpcStream handles an incoming RPC stream (remote is the initiator).
|
|
21
|
+
export async function* handleRpcStream(stream, getter) {
|
|
22
|
+
// read the component id
|
|
23
|
+
const initPromise = new Promise((resolve, reject) => {
|
|
24
|
+
const subscription = stream.subscribe({
|
|
25
|
+
next(value) {
|
|
26
|
+
resolve(value);
|
|
27
|
+
subscription.unsubscribe();
|
|
28
|
+
},
|
|
29
|
+
error(err) {
|
|
30
|
+
reject(err);
|
|
31
|
+
},
|
|
32
|
+
complete() {
|
|
33
|
+
reject(new Error('no packet received'));
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
// read the init packet
|
|
38
|
+
const initPacket = await initPromise;
|
|
39
|
+
if (initPacket?.body?.$case !== 'init') {
|
|
40
|
+
throw new Error('expected init packet');
|
|
41
|
+
}
|
|
42
|
+
// lookup the server for the component id.
|
|
43
|
+
const server = await getter(initPacket.body.init.componentId);
|
|
44
|
+
// build the outgoing packet sink & the packet source
|
|
45
|
+
const packetSink = pushable({ objectMode: true });
|
|
46
|
+
// handle the stream
|
|
47
|
+
const rpcStream = new RpcStream(packetSink, stream);
|
|
48
|
+
server.handleDuplex(rpcStream);
|
|
49
|
+
// return the outgoing packet sink
|
|
50
|
+
return packetSink;
|
|
51
|
+
}
|
|
52
|
+
// RpcStream implements the Stream on top of a RPC call.
|
|
53
|
+
export class RpcStream {
|
|
54
|
+
constructor(packetSink, packetSource) {
|
|
55
|
+
this._packetSink = packetSink;
|
|
56
|
+
this.sink = this._createSink();
|
|
57
|
+
const source = pushable({ objectMode: true });
|
|
58
|
+
this.source = source;
|
|
59
|
+
this._source = source;
|
|
60
|
+
this._subscribePacketSource(packetSource);
|
|
61
|
+
}
|
|
62
|
+
// _createSink initializes the sink field.
|
|
63
|
+
_createSink() {
|
|
64
|
+
return async (source) => {
|
|
65
|
+
try {
|
|
66
|
+
for await (const msg of source) {
|
|
67
|
+
this._packetSink.push({
|
|
68
|
+
body: { $case: 'data', data: msg }
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
this._packetSink.end();
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
this._packetSink.end(err);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// _subscribePacketSource starts the subscription to the response data.
|
|
79
|
+
_subscribePacketSource(packetSource) {
|
|
80
|
+
packetSource.subscribe({
|
|
81
|
+
next: (value) => {
|
|
82
|
+
if (value?.body?.$case === 'data') {
|
|
83
|
+
this._source.push(value.body.data);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
error: (err) => {
|
|
87
|
+
this._source.end(err);
|
|
88
|
+
},
|
|
89
|
+
complete: () => {
|
|
90
|
+
this._source.end();
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import Long from 'long';
|
|
2
|
+
import * as _m0 from 'protobufjs/minimal';
|
|
3
|
+
export declare const protobufPackage = "rpcstream";
|
|
4
|
+
/** Packet is a packet encapsulating data for a RPC stream. */
|
|
5
|
+
export interface Packet {
|
|
6
|
+
body?: {
|
|
7
|
+
$case: 'init';
|
|
8
|
+
init: RpcStreamInit;
|
|
9
|
+
} | {
|
|
10
|
+
$case: 'data';
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** RpcStreamInit is the first message in a RPC stream. */
|
|
15
|
+
export interface RpcStreamInit {
|
|
16
|
+
/** ComponentId is the identifier of the component making the request. */
|
|
17
|
+
componentId: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const Packet: {
|
|
20
|
+
encode(message: Packet, writer?: _m0.Writer): _m0.Writer;
|
|
21
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): Packet;
|
|
22
|
+
fromJSON(object: any): Packet;
|
|
23
|
+
toJSON(message: Packet): unknown;
|
|
24
|
+
fromPartial<I extends {
|
|
25
|
+
body?: ({
|
|
26
|
+
init?: {
|
|
27
|
+
componentId?: string | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
} & {
|
|
30
|
+
$case: "init";
|
|
31
|
+
}) | ({
|
|
32
|
+
data?: Uint8Array | undefined;
|
|
33
|
+
} & {
|
|
34
|
+
$case: "data";
|
|
35
|
+
}) | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
body?: ({
|
|
38
|
+
init?: {
|
|
39
|
+
componentId?: string | undefined;
|
|
40
|
+
} | undefined;
|
|
41
|
+
} & {
|
|
42
|
+
$case: "init";
|
|
43
|
+
} & {
|
|
44
|
+
init?: ({
|
|
45
|
+
componentId?: string | undefined;
|
|
46
|
+
} & {
|
|
47
|
+
componentId?: string | undefined;
|
|
48
|
+
} & Record<Exclude<keyof I["body"]["init"], "componentId">, never>) | undefined;
|
|
49
|
+
$case: "init";
|
|
50
|
+
} & Record<Exclude<keyof I["body"], "$case" | "init">, never>) | ({
|
|
51
|
+
data?: Uint8Array | undefined;
|
|
52
|
+
} & {
|
|
53
|
+
$case: "data";
|
|
54
|
+
} & {
|
|
55
|
+
data?: Uint8Array | undefined;
|
|
56
|
+
$case: "data";
|
|
57
|
+
} & Record<Exclude<keyof I["body"], "$case" | "data">, never>) | undefined;
|
|
58
|
+
} & Record<Exclude<keyof I, "body">, never>>(object: I): Packet;
|
|
59
|
+
};
|
|
60
|
+
export declare const RpcStreamInit: {
|
|
61
|
+
encode(message: RpcStreamInit, writer?: _m0.Writer): _m0.Writer;
|
|
62
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): RpcStreamInit;
|
|
63
|
+
fromJSON(object: any): RpcStreamInit;
|
|
64
|
+
toJSON(message: RpcStreamInit): unknown;
|
|
65
|
+
fromPartial<I extends {
|
|
66
|
+
componentId?: string | undefined;
|
|
67
|
+
} & {
|
|
68
|
+
componentId?: string | undefined;
|
|
69
|
+
} & Record<Exclude<keyof I, "componentId">, never>>(object: I): RpcStreamInit;
|
|
70
|
+
};
|
|
71
|
+
declare type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
72
|
+
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 {
|
|
73
|
+
$case: string;
|
|
74
|
+
} ? {
|
|
75
|
+
[K in keyof Omit<T, '$case'>]?: DeepPartial<T[K]>;
|
|
76
|
+
} & {
|
|
77
|
+
$case: T['$case'];
|
|
78
|
+
} : T extends {} ? {
|
|
79
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
80
|
+
} : Partial<T>;
|
|
81
|
+
declare type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
82
|
+
export declare type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
|
83
|
+
[K in keyof P]: Exact<P[K], I[K]>;
|
|
84
|
+
} & Record<Exclude<keyof I, KeysOfUnion<P>>, never>;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import Long from 'long';
|
|
3
|
+
import * as _m0 from 'protobufjs/minimal';
|
|
4
|
+
export const protobufPackage = 'rpcstream';
|
|
5
|
+
function createBasePacket() {
|
|
6
|
+
return { body: undefined };
|
|
7
|
+
}
|
|
8
|
+
export const Packet = {
|
|
9
|
+
encode(message, writer = _m0.Writer.create()) {
|
|
10
|
+
if (message.body?.$case === 'init') {
|
|
11
|
+
RpcStreamInit.encode(message.body.init, writer.uint32(10).fork()).ldelim();
|
|
12
|
+
}
|
|
13
|
+
if (message.body?.$case === 'data') {
|
|
14
|
+
writer.uint32(18).bytes(message.body.data);
|
|
15
|
+
}
|
|
16
|
+
return writer;
|
|
17
|
+
},
|
|
18
|
+
decode(input, length) {
|
|
19
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
20
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
|
21
|
+
const message = createBasePacket();
|
|
22
|
+
while (reader.pos < end) {
|
|
23
|
+
const tag = reader.uint32();
|
|
24
|
+
switch (tag >>> 3) {
|
|
25
|
+
case 1:
|
|
26
|
+
message.body = {
|
|
27
|
+
$case: 'init',
|
|
28
|
+
init: RpcStreamInit.decode(reader, reader.uint32()),
|
|
29
|
+
};
|
|
30
|
+
break;
|
|
31
|
+
case 2:
|
|
32
|
+
message.body = { $case: 'data', data: reader.bytes() };
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
reader.skipType(tag & 7);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return message;
|
|
40
|
+
},
|
|
41
|
+
fromJSON(object) {
|
|
42
|
+
return {
|
|
43
|
+
body: isSet(object.init)
|
|
44
|
+
? { $case: 'init', init: RpcStreamInit.fromJSON(object.init) }
|
|
45
|
+
: isSet(object.data)
|
|
46
|
+
? { $case: 'data', data: bytesFromBase64(object.data) }
|
|
47
|
+
: undefined,
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
toJSON(message) {
|
|
51
|
+
const obj = {};
|
|
52
|
+
message.body?.$case === 'init' &&
|
|
53
|
+
(obj.init = message.body?.init
|
|
54
|
+
? RpcStreamInit.toJSON(message.body?.init)
|
|
55
|
+
: undefined);
|
|
56
|
+
message.body?.$case === 'data' &&
|
|
57
|
+
(obj.data =
|
|
58
|
+
message.body?.data !== undefined
|
|
59
|
+
? base64FromBytes(message.body?.data)
|
|
60
|
+
: undefined);
|
|
61
|
+
return obj;
|
|
62
|
+
},
|
|
63
|
+
fromPartial(object) {
|
|
64
|
+
const message = createBasePacket();
|
|
65
|
+
if (object.body?.$case === 'init' &&
|
|
66
|
+
object.body?.init !== undefined &&
|
|
67
|
+
object.body?.init !== null) {
|
|
68
|
+
message.body = {
|
|
69
|
+
$case: 'init',
|
|
70
|
+
init: RpcStreamInit.fromPartial(object.body.init),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (object.body?.$case === 'data' &&
|
|
74
|
+
object.body?.data !== undefined &&
|
|
75
|
+
object.body?.data !== null) {
|
|
76
|
+
message.body = { $case: 'data', data: object.body.data };
|
|
77
|
+
}
|
|
78
|
+
return message;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
function createBaseRpcStreamInit() {
|
|
82
|
+
return { componentId: '' };
|
|
83
|
+
}
|
|
84
|
+
export const RpcStreamInit = {
|
|
85
|
+
encode(message, writer = _m0.Writer.create()) {
|
|
86
|
+
if (message.componentId !== '') {
|
|
87
|
+
writer.uint32(10).string(message.componentId);
|
|
88
|
+
}
|
|
89
|
+
return writer;
|
|
90
|
+
},
|
|
91
|
+
decode(input, length) {
|
|
92
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
93
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
|
94
|
+
const message = createBaseRpcStreamInit();
|
|
95
|
+
while (reader.pos < end) {
|
|
96
|
+
const tag = reader.uint32();
|
|
97
|
+
switch (tag >>> 3) {
|
|
98
|
+
case 1:
|
|
99
|
+
message.componentId = reader.string();
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
reader.skipType(tag & 7);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return message;
|
|
107
|
+
},
|
|
108
|
+
fromJSON(object) {
|
|
109
|
+
return {
|
|
110
|
+
componentId: isSet(object.componentId) ? String(object.componentId) : '',
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
toJSON(message) {
|
|
114
|
+
const obj = {};
|
|
115
|
+
message.componentId !== undefined && (obj.componentId = message.componentId);
|
|
116
|
+
return obj;
|
|
117
|
+
},
|
|
118
|
+
fromPartial(object) {
|
|
119
|
+
const message = createBaseRpcStreamInit();
|
|
120
|
+
message.componentId = object.componentId ?? '';
|
|
121
|
+
return message;
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
var globalThis = (() => {
|
|
125
|
+
if (typeof globalThis !== 'undefined')
|
|
126
|
+
return globalThis;
|
|
127
|
+
if (typeof self !== 'undefined')
|
|
128
|
+
return self;
|
|
129
|
+
if (typeof window !== 'undefined')
|
|
130
|
+
return window;
|
|
131
|
+
if (typeof global !== 'undefined')
|
|
132
|
+
return global;
|
|
133
|
+
throw 'Unable to locate global object';
|
|
134
|
+
})();
|
|
135
|
+
const atob = globalThis.atob ||
|
|
136
|
+
((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary'));
|
|
137
|
+
function bytesFromBase64(b64) {
|
|
138
|
+
const bin = atob(b64);
|
|
139
|
+
const arr = new Uint8Array(bin.length);
|
|
140
|
+
for (let i = 0; i < bin.length; ++i) {
|
|
141
|
+
arr[i] = bin.charCodeAt(i);
|
|
142
|
+
}
|
|
143
|
+
return arr;
|
|
144
|
+
}
|
|
145
|
+
const btoa = globalThis.btoa ||
|
|
146
|
+
((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64'));
|
|
147
|
+
function base64FromBytes(arr) {
|
|
148
|
+
const bin = [];
|
|
149
|
+
arr.forEach((byte) => {
|
|
150
|
+
bin.push(String.fromCharCode(byte));
|
|
151
|
+
});
|
|
152
|
+
return btoa(bin.join(''));
|
|
153
|
+
}
|
|
154
|
+
if (_m0.util.Long !== Long) {
|
|
155
|
+
_m0.util.Long = Long;
|
|
156
|
+
_m0.configure();
|
|
157
|
+
}
|
|
158
|
+
function isSet(value) {
|
|
159
|
+
return value !== null && value !== undefined;
|
|
160
|
+
}
|
|
@@ -2,14 +2,6 @@ import { EventIterator } from 'event-iterator';
|
|
|
2
2
|
import { DuplexConn } from './conn-duplex.js';
|
|
3
3
|
// BroadcastChannelIterable is a AsyncIterable wrapper for BroadcastChannel.
|
|
4
4
|
export class BroadcastChannelIterable {
|
|
5
|
-
// readChannel is the incoming broadcast channel
|
|
6
|
-
readChannel;
|
|
7
|
-
// writeChannel is the outgoing broadcast channel
|
|
8
|
-
writeChannel;
|
|
9
|
-
// sink is the sink for incoming messages.
|
|
10
|
-
sink;
|
|
11
|
-
// source is the source for outgoing messages.
|
|
12
|
-
source;
|
|
13
5
|
constructor(readChannel, writeChannel) {
|
|
14
6
|
this.readChannel = readChannel;
|
|
15
7
|
this.writeChannel = writeChannel;
|
|
@@ -52,8 +44,6 @@ export function newBroadcastChannelIterable(readName, writeName) {
|
|
|
52
44
|
//
|
|
53
45
|
// expects Uint8Array objects over the BroadcastChannel.
|
|
54
46
|
export class BroadcastChannelConn extends DuplexConn {
|
|
55
|
-
// broadcastChannel is the broadcast channel iterable
|
|
56
|
-
broadcastChannel;
|
|
57
47
|
constructor(readChannel, writeChannel, server, connParams) {
|
|
58
48
|
const broadcastChannel = new BroadcastChannelIterable(readChannel, writeChannel);
|
|
59
49
|
super(broadcastChannel, server, connParams);
|
package/dist/srpc/client.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { Observable } from 'rxjs';
|
|
|
2
2
|
import type { TsProtoRpc } from './ts-proto-rpc.js';
|
|
3
3
|
import type { OpenStreamFunc } from './stream.js';
|
|
4
4
|
export declare class Client implements TsProtoRpc {
|
|
5
|
-
private
|
|
6
|
-
private
|
|
7
|
-
constructor(
|
|
8
|
-
|
|
9
|
-
private
|
|
5
|
+
private openStreamFn;
|
|
6
|
+
private _openStreamFn?;
|
|
7
|
+
constructor(openStreamFn?: OpenStreamFunc);
|
|
8
|
+
setOpenStreamFn(openStreamFn?: OpenStreamFunc): Promise<OpenStreamFunc>;
|
|
9
|
+
private initOpenStreamFn;
|
|
10
10
|
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
11
11
|
clientStreamingRequest(service: string, method: string, data: Observable<Uint8Array>): Promise<Uint8Array>;
|
|
12
12
|
serverStreamingRequest(service: string, method: string, data: Uint8Array): Observable<Uint8Array>;
|
package/dist/srpc/client.js
CHANGED
|
@@ -19,35 +19,31 @@ function writeClientStream(call, data) {
|
|
|
19
19
|
}
|
|
20
20
|
// Client implements the ts-proto Rpc interface with the drpcproto protocol.
|
|
21
21
|
export class Client {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// _openConnFn resolves openConnFn.
|
|
25
|
-
_openConnFn;
|
|
26
|
-
constructor(openConnFn) {
|
|
27
|
-
this.openConnFn = this.setOpenConnFn(openConnFn);
|
|
22
|
+
constructor(openStreamFn) {
|
|
23
|
+
this.openStreamFn = this.setOpenStreamFn(openStreamFn);
|
|
28
24
|
}
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
if (this.
|
|
32
|
-
if (
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
25
|
+
// setOpenStreamFn updates the openStreamFn for the Client.
|
|
26
|
+
setOpenStreamFn(openStreamFn) {
|
|
27
|
+
if (this._openStreamFn) {
|
|
28
|
+
if (openStreamFn) {
|
|
29
|
+
this._openStreamFn(openStreamFn);
|
|
30
|
+
this._openStreamFn = undefined;
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
else {
|
|
38
|
-
if (
|
|
39
|
-
this.
|
|
34
|
+
if (openStreamFn) {
|
|
35
|
+
this.openStreamFn = Promise.resolve(openStreamFn);
|
|
40
36
|
}
|
|
41
37
|
else {
|
|
42
|
-
this.
|
|
38
|
+
this.initOpenStreamFn();
|
|
43
39
|
}
|
|
44
40
|
}
|
|
45
|
-
return this.
|
|
41
|
+
return this.openStreamFn;
|
|
46
42
|
}
|
|
47
|
-
//
|
|
48
|
-
|
|
43
|
+
// initOpenStreamFn creates the empty Promise for openStreamFn.
|
|
44
|
+
initOpenStreamFn() {
|
|
49
45
|
const openPromise = new Promise((resolve, reject) => {
|
|
50
|
-
this.
|
|
46
|
+
this._openStreamFn = (conn, err) => {
|
|
51
47
|
if (err) {
|
|
52
48
|
reject(err);
|
|
53
49
|
}
|
|
@@ -56,8 +52,8 @@ export class Client {
|
|
|
56
52
|
}
|
|
57
53
|
};
|
|
58
54
|
});
|
|
59
|
-
this.
|
|
60
|
-
return this.
|
|
55
|
+
this.openStreamFn = openPromise;
|
|
56
|
+
return this.openStreamFn;
|
|
61
57
|
}
|
|
62
58
|
// request starts a non-streaming request.
|
|
63
59
|
async request(service, method, data) {
|
|
@@ -84,7 +80,7 @@ export class Client {
|
|
|
84
80
|
}
|
|
85
81
|
// serverStreamingRequest starts a server-side streaming request.
|
|
86
82
|
serverStreamingRequest(service, method, data) {
|
|
87
|
-
const pushServerData = pushable();
|
|
83
|
+
const pushServerData = pushable({ objectMode: true });
|
|
88
84
|
const serverData = observableFrom(pushServerData);
|
|
89
85
|
this.startRpc(service, method, data)
|
|
90
86
|
.then(async (call) => {
|
|
@@ -103,7 +99,7 @@ export class Client {
|
|
|
103
99
|
}
|
|
104
100
|
// bidirectionalStreamingRequest starts a two-way streaming request.
|
|
105
101
|
bidirectionalStreamingRequest(service, method, data) {
|
|
106
|
-
const pushServerData = pushable();
|
|
102
|
+
const pushServerData = pushable({ objectMode: true });
|
|
107
103
|
const serverData = observableFrom(pushServerData);
|
|
108
104
|
this.startRpc(service, method, null)
|
|
109
105
|
.then(async (call) => {
|
|
@@ -135,8 +131,8 @@ export class Client {
|
|
|
135
131
|
// throws any error starting the rpc call
|
|
136
132
|
// if data == null and data.length == 0, sends a separate data packet.
|
|
137
133
|
async startRpc(rpcService, rpcMethod, data) {
|
|
138
|
-
const
|
|
139
|
-
const conn = await
|
|
134
|
+
const openStreamFn = await this.openStreamFn;
|
|
135
|
+
const conn = await openStreamFn();
|
|
140
136
|
const call = new ClientRPC(rpcService, rpcMethod);
|
|
141
137
|
pipe(conn, parseLengthPrefixTransform(), decodePacketSource, call, encodePacketSource, prependLengthPrefixTransform(), conn);
|
|
142
138
|
await call.writeCallStart(data || undefined);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Source, Sink } from 'it-stream-types';
|
|
2
|
-
import type { CallData, CallStart } from './rpcproto.js';
|
|
3
|
-
import { Packet } from './rpcproto.js';
|
|
2
|
+
import type { CallData, CallStart } from './rpcproto.pb.js';
|
|
3
|
+
import { Packet } from './rpcproto.pb.js';
|
|
4
4
|
export declare class CommonRPC {
|
|
5
5
|
sink: Sink<Packet>;
|
|
6
6
|
source: AsyncIterable<Packet>;
|