starpc 0.18.2 → 0.19.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.
Files changed (55) hide show
  1. package/dist/e2e/mock/mock.pb.js +10 -6
  2. package/dist/echo/echo.pb.js +11 -7
  3. package/dist/rpcstream/pushable-sink.d.ts +0 -0
  4. package/dist/rpcstream/pushable-sink.js +1 -0
  5. package/dist/rpcstream/rpcstream.js +1 -1
  6. package/dist/rpcstream/rpcstream.pb.js +45 -25
  7. package/dist/srpc/client.js +3 -4
  8. package/dist/srpc/common-rpc.js +1 -1
  9. package/dist/srpc/conn.d.ts +1 -1
  10. package/dist/srpc/conn.js +16 -6
  11. package/dist/srpc/errors.d.ts +1 -0
  12. package/dist/srpc/errors.js +23 -0
  13. package/dist/srpc/index.d.ts +4 -2
  14. package/dist/srpc/index.js +4 -2
  15. package/dist/srpc/pushable.d.ts +2 -0
  16. package/dist/srpc/pushable.js +23 -0
  17. package/dist/srpc/rpcproto.pb.js +69 -31
  18. package/dist/srpc/server.d.ts +3 -4
  19. package/dist/srpc/server.js +11 -12
  20. package/e2e/mock/mock.pb.go +1 -1
  21. package/e2e/mock/mock.pb.ts +12 -6
  22. package/e2e/mock/mock_srpc.pb.go +1 -1
  23. package/e2e/mock/mock_vtproto.pb.go +13 -5
  24. package/echo/echo.pb.go +1 -1
  25. package/echo/echo.pb.ts +13 -7
  26. package/echo/echo_srpc.pb.go +1 -1
  27. package/echo/echo_vtproto.pb.go +13 -5
  28. package/go.mod +3 -3
  29. package/go.sum +6 -6
  30. package/package.json +18 -18
  31. package/srpc/client-prefix.go +7 -0
  32. package/srpc/client-set.go +18 -3
  33. package/srpc/client.go +19 -3
  34. package/srpc/client.ts +3 -9
  35. package/srpc/common-rpc.ts +1 -1
  36. package/srpc/conn.ts +22 -8
  37. package/srpc/errors.go +2 -0
  38. package/srpc/errors.ts +24 -0
  39. package/srpc/index.ts +9 -2
  40. package/srpc/message.go +12 -0
  41. package/srpc/muxed-conn.go +1 -1
  42. package/srpc/packet-rw.go +18 -15
  43. package/srpc/packet.go +19 -0
  44. package/srpc/pushable.ts +23 -0
  45. package/srpc/raw-stream-rwc.go +153 -0
  46. package/srpc/rpcproto.pb.go +1 -1
  47. package/srpc/rpcproto.pb.ts +89 -34
  48. package/srpc/rpcproto_vtproto.pb.go +35 -13
  49. package/srpc/server-pipe.go +1 -1
  50. package/srpc/server-rpc.go +9 -0
  51. package/srpc/server.go +2 -1
  52. package/srpc/server.ts +11 -13
  53. package/srpc/stream-rwc.go +85 -0
  54. package/srpc/stream.ts +1 -0
  55. package/srpc/writer.go +2 -0
@@ -1,6 +1,6 @@
1
1
  // Code generated by protoc-gen-go. DO NOT EDIT.
2
2
  // versions:
3
- // protoc-gen-go v1.28.1-devel
3
+ // protoc-gen-go v1.30.0-devel
4
4
  // protoc v3.21.9
5
5
  // source: github.com/aperturerobotics/starpc/e2e/mock/mock.proto
6
6
 
@@ -25,19 +25,25 @@ export const MockMsg = {
25
25
  },
26
26
 
27
27
  decode(input: _m0.Reader | Uint8Array, length?: number): MockMsg {
28
- const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input)
28
+ const reader =
29
+ input instanceof _m0.Reader ? input : _m0.Reader.create(input)
29
30
  let end = length === undefined ? reader.len : reader.pos + length
30
31
  const message = createBaseMockMsg()
31
32
  while (reader.pos < end) {
32
33
  const tag = reader.uint32()
33
34
  switch (tag >>> 3) {
34
35
  case 1:
36
+ if (tag != 10) {
37
+ break
38
+ }
39
+
35
40
  message.body = reader.string()
36
- break
37
- default:
38
- reader.skipType(tag & 7)
39
- break
41
+ continue
42
+ }
43
+ if ((tag & 7) == 4 || tag == 0) {
44
+ break
40
45
  }
46
+ reader.skipType(tag & 7)
41
47
  }
42
48
  return message
43
49
  },
@@ -119,7 +125,7 @@ export class MockClientImpl implements Mock {
119
125
  data,
120
126
  abortSignal || undefined
121
127
  )
122
- return promise.then((data) => MockMsg.decode(new _m0.Reader(data)))
128
+ return promise.then((data) => MockMsg.decode(_m0.Reader.create(data)))
123
129
  }
124
130
  }
125
131
 
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-srpc. DO NOT EDIT.
2
- // protoc-gen-srpc version: v0.16.1
2
+ // protoc-gen-srpc version: v0.18.1
3
3
  // source: github.com/aperturerobotics/starpc/e2e/mock/mock.proto
4
4
 
5
5
  package e2e_mock
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-go-vtproto. DO NOT EDIT.
2
- // protoc-gen-go-vtproto version: v0.3.1-0.20220817155510-0ae748fd2007
2
+ // protoc-gen-go-vtproto version: v0.4.0
3
3
  // source: github.com/aperturerobotics/starpc/e2e/mock/mock.proto
4
4
 
5
5
  package e2e_mock
@@ -34,14 +34,14 @@ func (m *MockMsg) CloneVT() *MockMsg {
34
34
  return r
35
35
  }
36
36
 
37
- func (m *MockMsg) CloneGenericVT() proto.Message {
37
+ func (m *MockMsg) CloneMessageVT() proto.Message {
38
38
  return m.CloneVT()
39
39
  }
40
40
 
41
41
  func (this *MockMsg) EqualVT(that *MockMsg) bool {
42
- if this == nil {
43
- return that == nil
44
- } else if that == nil {
42
+ if this == that {
43
+ return true
44
+ } else if this == nil || that == nil {
45
45
  return false
46
46
  }
47
47
  if this.Body != that.Body {
@@ -50,6 +50,13 @@ func (this *MockMsg) EqualVT(that *MockMsg) bool {
50
50
  return string(this.unknownFields) == string(that.unknownFields)
51
51
  }
52
52
 
53
+ func (this *MockMsg) EqualMessageVT(thatMsg proto.Message) bool {
54
+ that, ok := thatMsg.(*MockMsg)
55
+ if !ok {
56
+ return false
57
+ }
58
+ return this.EqualVT(that)
59
+ }
53
60
  func (m *MockMsg) MarshalVT() (dAtA []byte, err error) {
54
61
  if m == nil {
55
62
  return nil, nil
@@ -204,6 +211,7 @@ func (m *MockMsg) UnmarshalVT(dAtA []byte) error {
204
211
  }
205
212
  return nil
206
213
  }
214
+
207
215
  func skip(dAtA []byte) (n int, err error) {
208
216
  l := len(dAtA)
209
217
  iNdEx := 0
package/echo/echo.pb.go CHANGED
@@ -1,6 +1,6 @@
1
1
  // Code generated by protoc-gen-go. DO NOT EDIT.
2
2
  // versions:
3
- // protoc-gen-go v1.28.1-devel
3
+ // protoc-gen-go v1.30.0-devel
4
4
  // protoc v3.21.9
5
5
  // source: github.com/aperturerobotics/starpc/echo/echo.proto
6
6
 
package/echo/echo.pb.ts CHANGED
@@ -26,19 +26,25 @@ export const EchoMsg = {
26
26
  },
27
27
 
28
28
  decode(input: _m0.Reader | Uint8Array, length?: number): EchoMsg {
29
- const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input)
29
+ const reader =
30
+ input instanceof _m0.Reader ? input : _m0.Reader.create(input)
30
31
  let end = length === undefined ? reader.len : reader.pos + length
31
32
  const message = createBaseEchoMsg()
32
33
  while (reader.pos < end) {
33
34
  const tag = reader.uint32()
34
35
  switch (tag >>> 3) {
35
36
  case 1:
37
+ if (tag != 10) {
38
+ break
39
+ }
40
+
36
41
  message.body = reader.string()
37
- break
38
- default:
39
- reader.skipType(tag & 7)
40
- break
42
+ continue
43
+ }
44
+ if ((tag & 7) == 4 || tag == 0) {
45
+ break
41
46
  }
47
+ reader.skipType(tag & 7)
42
48
  }
43
49
  return message
44
50
  },
@@ -144,7 +150,7 @@ export class EchoerClientImpl implements Echoer {
144
150
  data,
145
151
  abortSignal || undefined
146
152
  )
147
- return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)))
153
+ return promise.then((data) => EchoMsg.decode(_m0.Reader.create(data)))
148
154
  }
149
155
 
150
156
  EchoServerStream(
@@ -172,7 +178,7 @@ export class EchoerClientImpl implements Echoer {
172
178
  data,
173
179
  abortSignal || undefined
174
180
  )
175
- return promise.then((data) => EchoMsg.decode(new _m0.Reader(data)))
181
+ return promise.then((data) => EchoMsg.decode(_m0.Reader.create(data)))
176
182
  }
177
183
 
178
184
  EchoBidiStream(
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-srpc. DO NOT EDIT.
2
- // protoc-gen-srpc version: v0.16.1
2
+ // protoc-gen-srpc version: v0.18.1
3
3
  // source: github.com/aperturerobotics/starpc/echo/echo.proto
4
4
 
5
5
  package echo
@@ -1,5 +1,5 @@
1
1
  // Code generated by protoc-gen-go-vtproto. DO NOT EDIT.
2
- // protoc-gen-go-vtproto version: v0.3.1-0.20220817155510-0ae748fd2007
2
+ // protoc-gen-go-vtproto version: v0.4.0
3
3
  // source: github.com/aperturerobotics/starpc/echo/echo.proto
4
4
 
5
5
  package echo
@@ -34,14 +34,14 @@ func (m *EchoMsg) CloneVT() *EchoMsg {
34
34
  return r
35
35
  }
36
36
 
37
- func (m *EchoMsg) CloneGenericVT() proto.Message {
37
+ func (m *EchoMsg) CloneMessageVT() proto.Message {
38
38
  return m.CloneVT()
39
39
  }
40
40
 
41
41
  func (this *EchoMsg) EqualVT(that *EchoMsg) bool {
42
- if this == nil {
43
- return that == nil
44
- } else if that == nil {
42
+ if this == that {
43
+ return true
44
+ } else if this == nil || that == nil {
45
45
  return false
46
46
  }
47
47
  if this.Body != that.Body {
@@ -50,6 +50,13 @@ func (this *EchoMsg) EqualVT(that *EchoMsg) bool {
50
50
  return string(this.unknownFields) == string(that.unknownFields)
51
51
  }
52
52
 
53
+ func (this *EchoMsg) EqualMessageVT(thatMsg proto.Message) bool {
54
+ that, ok := thatMsg.(*EchoMsg)
55
+ if !ok {
56
+ return false
57
+ }
58
+ return this.EqualVT(that)
59
+ }
53
60
  func (m *EchoMsg) MarshalVT() (dAtA []byte, err error) {
54
61
  if m == nil {
55
62
  return nil, nil
@@ -204,6 +211,7 @@ func (m *EchoMsg) UnmarshalVT(dAtA []byte) error {
204
211
  }
205
212
  return nil
206
213
  }
214
+
207
215
  func skip(dAtA []byte) (n int, err error) {
208
216
  l := len(dAtA)
209
217
  iNdEx := 0
package/go.mod CHANGED
@@ -4,13 +4,13 @@ go 1.18
4
4
 
5
5
  require (
6
6
  github.com/pkg/errors v0.9.1 // latest
7
- google.golang.org/protobuf v1.28.1 // latest
7
+ google.golang.org/protobuf v1.30.0 // latest
8
8
  nhooyr.io/websocket v1.8.8-0.20221213223501-14fb98eba64e // master
9
9
  )
10
10
 
11
11
  require (
12
- github.com/aperturerobotics/util v1.0.5 // latest
13
- github.com/libp2p/go-libp2p v0.26.1 // latest
12
+ github.com/aperturerobotics/util v1.0.6-0.20230323123147-d1b8fef6a782 // latest
13
+ github.com/libp2p/go-libp2p v0.26.1-0.20230320233358-9e208249b588 // latest
14
14
  github.com/libp2p/go-yamux/v4 v4.0.1-0.20220919134236-1c09f2ab3ec1 // master
15
15
  github.com/sirupsen/logrus v1.9.0 // latest
16
16
  )
package/go.sum CHANGED
@@ -1,5 +1,5 @@
1
- github.com/aperturerobotics/util v1.0.5 h1:gxDjQ31MHXthwkiRuG6LiwwU2g+E1neIuuBGI71QsP0=
2
- github.com/aperturerobotics/util v1.0.5/go.mod h1:45zfYCir2T5/KE+O9CyYdZPrsXZtOEAuA4UU79rRMN4=
1
+ github.com/aperturerobotics/util v1.0.6-0.20230323123147-d1b8fef6a782 h1:kKuKxMVd1N+aT9+hQQaIc5n2AkD6smFTSw6/Jl4N8NA=
2
+ github.com/aperturerobotics/util v1.0.6-0.20230323123147-d1b8fef6a782/go.mod h1:VB5a5FURpm7EujJsErIY8UZrhrLPN/bj84H8FxN0gD4=
3
3
  github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4
4
  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5
5
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -48,8 +48,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
48
48
  github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
49
49
  github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
50
50
  github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
51
- github.com/libp2p/go-libp2p v0.26.1 h1:I9bHj5KteIB1tsBWLT25TTttx5xSjun3ph/q/8Xax/k=
52
- github.com/libp2p/go-libp2p v0.26.1/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ=
51
+ github.com/libp2p/go-libp2p v0.26.1-0.20230320233358-9e208249b588 h1:hY4aHvA59tTkxKZxSyHWnhbQ+/ULgYwaNW1GLqJy2YU=
52
+ github.com/libp2p/go-libp2p v0.26.1-0.20230320233358-9e208249b588/go.mod h1:HKQUKIQ5NhzabNMWq9Wczcs5Ksdx4LQ/ISAq4MRqBHQ=
53
53
  github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
54
54
  github.com/libp2p/go-yamux/v4 v4.0.1-0.20220919134236-1c09f2ab3ec1 h1:fxyHejZvFIBqlznQDuHUkw9BThYKyoT3DclP/C2g8Wc=
55
55
  github.com/libp2p/go-yamux/v4 v4.0.1-0.20220919134236-1c09f2ab3ec1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
@@ -110,8 +110,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
110
110
  golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
111
111
  golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
112
112
  google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
113
- google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
114
- google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
113
+ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
114
+ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
115
115
  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
116
116
  gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
117
117
  gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starpc",
3
- "version": "0.18.2",
3
+ "version": "0.19.0",
4
4
  "description": "Streaming protobuf RPC service protocol over any two-way channel.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -60,38 +60,38 @@
60
60
  "singleQuote": true
61
61
  },
62
62
  "devDependencies": {
63
- "@aperturerobotics/ts-common": "^0.3.1",
64
- "@typescript-eslint/eslint-plugin": "^5.54.0",
65
- "@typescript-eslint/parser": "^5.54.0",
63
+ "@aperturerobotics/ts-common": "^0.4.2",
64
+ "@typescript-eslint/eslint-plugin": "^5.57.0",
65
+ "@typescript-eslint/parser": "^5.57.0",
66
66
  "bufferutil": "^4.0.7",
67
67
  "depcheck": "^1.4.3",
68
- "esbuild": "^0.17.1",
69
- "eslint": "^8.35.0",
70
- "eslint-config-prettier": "^8.6.0",
71
- "prettier": "^2.8.3",
72
- "rimraf": "^4.1.0",
73
- "ts-proto": "^1.138.0",
74
- "typescript": "^4.9.5",
68
+ "esbuild": "^0.17.15",
69
+ "eslint": "^8.37.0",
70
+ "eslint-config-prettier": "^8.8.0",
71
+ "prettier": "^2.8.7",
72
+ "rimraf": "^4.4.0",
73
+ "ts-proto": "^1.146.0",
74
+ "typescript": "^5.0.3",
75
75
  "utf-8-validate": "^6.0.3"
76
76
  },
77
77
  "dependencies": {
78
- "@chainsafe/libp2p-yamux": "^3.0.6",
79
- "@libp2p/interface-connection": "^3.0.7",
78
+ "@chainsafe/libp2p-yamux": "^3.0.7",
79
+ "@libp2p/interface-connection": "^3.1.1",
80
80
  "@libp2p/interface-stream-muxer": "^3.0.4",
81
81
  "event-iterator": "^2.0.0",
82
82
  "is-promise": "^4.0.0",
83
83
  "isomorphic-ws": "^5.0.0",
84
- "it-first": "^2.0.0",
85
- "it-length-prefixed": "^8.0.4",
86
- "it-pipe": "^2.0.5",
84
+ "it-first": "^2.0.1",
85
+ "it-length-prefixed": "^8.0.0",
86
+ "it-pipe": "^2.0.0",
87
87
  "it-pushable": "^3.1.2",
88
88
  "it-stream-types": "^1.0.5",
89
89
  "it-ws": "^5.0.6",
90
90
  "long": "^5.2.1",
91
91
  "memoize-one": "^6.0.0",
92
92
  "patch-package": "^6.5.1",
93
- "protobufjs": "^7.1.2",
93
+ "protobufjs": "^7.2.0",
94
94
  "uint8arraylist": "^2.4.3",
95
- "ws": "^8.12.0"
95
+ "ws": "^8.13.0"
96
96
  }
97
97
  }
@@ -54,5 +54,12 @@ func (i *PrefixClient) stripCheckServiceIDPrefix(service string) (string, error)
54
54
  return service, nil
55
55
  }
56
56
 
57
+ // NewRawStream opens a new raw stream with the remote.
58
+ // Implements OpenStreamFunc.
59
+ // msgHandler must not be called concurrently.
60
+ func (i *PrefixClient) NewRawStream(ctx context.Context, msgHandler PacketDataHandler, closeHandler CloseHandler) (Writer, error) {
61
+ return i.client.NewRawStream(ctx, msgHandler, closeHandler)
62
+ }
63
+
57
64
  // _ is a type assertion
58
65
  var _ Client = ((*PrefixClient)(nil))
@@ -2,8 +2,6 @@ package srpc
2
2
 
3
3
  import (
4
4
  "context"
5
-
6
- "github.com/pkg/errors"
7
5
  )
8
6
 
9
7
  // ClientSet wraps a list of clients into one Client.
@@ -43,6 +41,23 @@ func (c *ClientSet) NewStream(
43
41
  return strm, err
44
42
  }
45
43
 
44
+ // NewRawStream opens a new raw stream with the remote.
45
+ // Implements OpenStreamFunc.
46
+ // msgHandler must not be called concurrently.
47
+ func (c *ClientSet) NewRawStream(
48
+ ctx context.Context,
49
+ msgHandler PacketDataHandler,
50
+ closeHandler CloseHandler,
51
+ ) (Writer, error) {
52
+ for _, client := range c.clients {
53
+ if client == nil {
54
+ continue
55
+ }
56
+ return client.NewRawStream(ctx, msgHandler, closeHandler)
57
+ }
58
+ return nil, ErrNoAvailableClients
59
+ }
60
+
46
61
  // execCall executes the call conditionally retrying against subsequent client handles.
47
62
  func (c *ClientSet) execCall(ctx context.Context, doCall func(client Client) error) error {
48
63
  var any bool
@@ -70,7 +85,7 @@ func (c *ClientSet) execCall(ctx context.Context, doCall func(client Client) err
70
85
  }
71
86
 
72
87
  if !any {
73
- return errors.New("no available rpc clients")
88
+ return ErrNoAvailableClients
74
89
  }
75
90
 
76
91
  return ErrUnimplemented
package/srpc/client.go CHANGED
@@ -14,13 +14,18 @@ type Client interface {
14
14
  // NewStream starts a streaming RPC with the remote & returns the stream.
15
15
  // firstMsg is optional.
16
16
  NewStream(ctx context.Context, service, method string, firstMsg Message) (Stream, error)
17
+
18
+ // NewRawStream opens a new raw stream with the remote.
19
+ // Implements OpenStreamFunc.
20
+ // msgHandler must not be called concurrently.
21
+ NewRawStream(ctx context.Context, msgHandler PacketDataHandler, closeHandler CloseHandler) (Writer, error)
17
22
  }
18
23
 
19
24
  // OpenStreamFunc opens a stream with a remote.
20
25
  // msgHandler must not be called concurrently.
21
26
  type OpenStreamFunc = func(
22
27
  ctx context.Context,
23
- msgHandler PacketHandler,
28
+ msgHandler PacketDataHandler,
24
29
  closeHandler CloseHandler,
25
30
  ) (Writer, error)
26
31
 
@@ -47,7 +52,7 @@ func (c *client) ExecCall(ctx context.Context, service, method string, in, out M
47
52
  clientRPC := NewClientRPC(ctx, service, method)
48
53
  defer clientRPC.Close()
49
54
 
50
- writer, err := c.openStream(ctx, clientRPC.HandlePacket, clientRPC.HandleStreamClose)
55
+ writer, err := c.openStream(ctx, clientRPC.HandlePacketData, clientRPC.HandleStreamClose)
51
56
  if err != nil {
52
57
  return err
53
58
  }
@@ -79,7 +84,7 @@ func (c *client) NewStream(ctx context.Context, service, method string, firstMsg
79
84
  }
80
85
 
81
86
  clientRPC := NewClientRPC(ctx, service, method)
82
- writer, err := c.openStream(ctx, clientRPC.HandlePacket, clientRPC.HandleStreamClose)
87
+ writer, err := c.openStream(ctx, clientRPC.HandlePacketData, clientRPC.HandleStreamClose)
83
88
  if err != nil {
84
89
  return nil, err
85
90
  }
@@ -90,5 +95,16 @@ func (c *client) NewStream(ctx context.Context, service, method string, firstMsg
90
95
  return NewMsgStream(ctx, clientRPC, clientRPC.ctxCancel), nil
91
96
  }
92
97
 
98
+ // NewRawStream opens a new raw stream with the remote.
99
+ // Implements OpenStreamFunc.
100
+ // msgHandler must not be called concurrently.
101
+ func (c *client) NewRawStream(
102
+ ctx context.Context,
103
+ msgHandler PacketDataHandler,
104
+ closeHandler CloseHandler,
105
+ ) (Writer, error) {
106
+ return c.openStream(ctx, msgHandler, closeHandler)
107
+ }
108
+
93
109
  // _ is a type assertion
94
110
  var _ Client = ((*client)(nil))
package/srpc/client.ts CHANGED
@@ -9,10 +9,7 @@ import { writeToPushable } from './pushable.js'
9
9
  import {
10
10
  decodePacketSource,
11
11
  encodePacketSource,
12
- parseLengthPrefixTransform,
13
- prependLengthPrefixTransform,
14
12
  } from './packet.js'
15
- import { combineUint8ArrayListTransform } from './array-list.js'
16
13
  import { OpenStreamCtr } from './open-stream-ctr.js'
17
14
 
18
15
  // Client implements the ts-proto Rpc interface with the drpcproto protocol.
@@ -117,20 +114,17 @@ export class Client implements TsProtoRpc {
117
114
  throw new Error(ERR_RPC_ABORT)
118
115
  }
119
116
  const openStreamFn = await this.openStreamCtr.wait()
120
- const conn = await openStreamFn()
117
+ const stream = await openStreamFn()
121
118
  const call = new ClientRPC(rpcService, rpcMethod)
122
119
  abortSignal?.addEventListener('abort', () => {
123
120
  call.close(new Error(ERR_RPC_ABORT))
124
121
  })
125
122
  pipe(
126
- conn,
127
- parseLengthPrefixTransform(),
128
- combineUint8ArrayListTransform(),
123
+ stream,
129
124
  decodePacketSource,
130
125
  call,
131
126
  encodePacketSource,
132
- prependLengthPrefixTransform(),
133
- conn
127
+ stream
134
128
  )
135
129
  await call.writeCallStart(data || undefined)
136
130
  return call
@@ -113,7 +113,7 @@ export class CommonRPC {
113
113
  asError = new Error('error handling packet')
114
114
  }
115
115
  this.close(asError)
116
- throw asError
116
+ // throw asError
117
117
  }
118
118
  }
119
119
 
package/srpc/conn.ts CHANGED
@@ -8,10 +8,13 @@ import type { Duplex } from 'it-stream-types'
8
8
  import { yamux } from '@chainsafe/libp2p-yamux'
9
9
  import { Uint8ArrayList } from 'uint8arraylist'
10
10
  import isPromise from 'is-promise'
11
+ import { pushable, Pushable } from 'it-pushable'
11
12
 
12
13
  import type { OpenStreamFunc, Stream as SRPCStream } from './stream.js'
13
14
  import { Client } from './client.js'
14
15
  import { combineUint8ArrayListTransform } from './array-list.js'
16
+ import { parseLengthPrefixTransform, prependLengthPrefixTransform } from './packet.js'
17
+ import { buildPushableSink } from './pushable.js'
15
18
 
16
19
  // ConnParams are parameters that can be passed to the Conn constructor.
17
20
  export interface ConnParams {
@@ -25,17 +28,25 @@ export interface ConnParams {
25
28
  // StreamHandler handles incoming streams.
26
29
  // Implemented by Server.
27
30
  export interface StreamHandler {
28
- // handleStream handles an incoming stream.
29
- handleStream(strm: SRPCStream): void
31
+ // handlePacketStream handles an incoming Uint8Array duplex.
32
+ // the stream has one Uint8Array per packet w/o length prefix.
33
+ handlePacketStream(strm: SRPCStream): void
30
34
  }
31
35
 
32
36
  // streamToSRPCStream converts a Stream to a SRPCStream.
37
+ // uses length-prefix for packet framing
33
38
  export function streamToSRPCStream(
34
39
  stream: Duplex<Uint8ArrayList, Uint8ArrayList | Uint8Array>
35
40
  ): SRPCStream {
41
+ const pushSink: Pushable<Uint8Array> = pushable({ objectMode: true })
42
+ pipe(pushSink, prependLengthPrefixTransform(), stream.sink)
36
43
  return {
37
- source: pipe(stream, combineUint8ArrayListTransform()),
38
- sink: stream.sink,
44
+ source: pipe(
45
+ stream,
46
+ parseLengthPrefixTransform(),
47
+ combineUint8ArrayListTransform(),
48
+ ),
49
+ sink: buildPushableSink(pushSink),
39
50
  }
40
51
  }
41
52
 
@@ -85,9 +96,12 @@ export class Conn implements Duplex<Uint8Array> {
85
96
 
86
97
  // openStream implements the client open stream function.
87
98
  public async openStream(): Promise<SRPCStream> {
88
- const stream = this.muxer.newStream()
89
- if (isPromise(stream)) {
90
- return streamToSRPCStream(await stream)
99
+ const streamPromise = this.muxer.newStream()
100
+ let stream: Stream
101
+ if (isPromise(streamPromise)) {
102
+ stream = await streamPromise
103
+ } else {
104
+ stream = streamPromise
91
105
  }
92
106
  return streamToSRPCStream(stream)
93
107
  }
@@ -103,6 +117,6 @@ export class Conn implements Duplex<Uint8Array> {
103
117
  if (!server) {
104
118
  return strm.abort(new Error('server not implemented'))
105
119
  }
106
- server.handleStream(streamToSRPCStream(strm))
120
+ server.handlePacketStream(streamToSRPCStream(strm))
107
121
  }
108
122
  }
package/srpc/errors.go CHANGED
@@ -17,4 +17,6 @@ var (
17
17
  ErrEmptyMethodID = errors.New("method id empty")
18
18
  // ErrEmptyServiceID is returned if the service id was empty.
19
19
  ErrEmptyServiceID = errors.New("service id empty")
20
+ // ErrNoAvailableClients is returned if no clients were available.
21
+ ErrNoAvailableClients = errors.New("no available rpc clients")
20
22
  )
package/srpc/errors.ts CHANGED
@@ -9,3 +9,27 @@ export function isAbortError(err: unknown): boolean {
9
9
  const message = (err as Error).message
10
10
  return message === ERR_RPC_ABORT
11
11
  }
12
+
13
+ // castToError casts an object to an Error.
14
+ // if err is a string, uses it as the message.
15
+ // if err is undefined, returns new Error(defaultMsg)
16
+ export function castToError(err: any, defaultMsg?: string): Error {
17
+ defaultMsg = defaultMsg || 'error'
18
+ if (!err) {
19
+ return new Error(defaultMsg)
20
+ }
21
+ if (typeof err === 'string') {
22
+ return new Error(err)
23
+ }
24
+ const asError = err as Error
25
+ if (asError.message) {
26
+ return asError
27
+ }
28
+ if (err.toString) {
29
+ const errString = err.toString()
30
+ if (errString) {
31
+ return new Error(errString)
32
+ }
33
+ }
34
+ return new Error(defaultMsg)
35
+ }
package/srpc/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { PacketHandler, Stream, OpenStreamFunc } from './stream.js'
2
- export { ERR_RPC_ABORT, isAbortError } from './errors.js'
2
+ export { ERR_RPC_ABORT, isAbortError, castToError } from './errors.js'
3
3
  export { Client } from './client.js'
4
4
  export { Server } from './server.js'
5
5
  export { Conn, ConnParams } from './conn.js'
@@ -25,6 +25,13 @@ export {
25
25
  memoProto,
26
26
  memoProtoDecode,
27
27
  } from './message.js'
28
+ export {
29
+ parseLengthPrefixTransform,
30
+ prependLengthPrefixTransform,
31
+ decodePacketSource,
32
+ encodePacketSource,
33
+ } from './packet.js'
34
+ export { combineUint8ArrayListTransform } from './array-list.js'
28
35
  export { ValueCtr } from './value-ctr.js'
29
36
  export { OpenStreamCtr } from './open-stream-ctr.js'
30
- export { writeToPushable } from './pushable'
37
+ export { writeToPushable, buildPushableSink } from './pushable.js'
package/srpc/message.go CHANGED
@@ -7,6 +7,8 @@ type Message interface {
7
7
  }
8
8
 
9
9
  // RawMessage is a raw protobuf message container.
10
+ //
11
+ // The empty value is valid with copy=false.
10
12
  type RawMessage struct {
11
13
  data []byte
12
14
  copy bool
@@ -41,6 +43,16 @@ func (m *RawMessage) SetData(data []byte) {
41
43
  }
42
44
  }
43
45
 
46
+ // Clear sets the length of the data buffer to 0 without releasing it.
47
+ func (m *RawMessage) Clear() {
48
+ m.data = m.data[:0]
49
+ }
50
+
51
+ // Reset releases the data buffer.
52
+ func (m *RawMessage) Reset() {
53
+ m.data = nil
54
+ }
55
+
44
56
  func (m *RawMessage) MarshalVT() ([]byte, error) {
45
57
  if !m.copy {
46
58
  return m.data, nil
@@ -72,7 +72,7 @@ func NewClientWithMuxedConn(conn network.MuxedConn) Client {
72
72
 
73
73
  // NewOpenStreamWithMuxedConn constructs a OpenStream func with a MuxedConn.
74
74
  func NewOpenStreamWithMuxedConn(conn network.MuxedConn) OpenStreamFunc {
75
- return func(ctx context.Context, msgHandler PacketHandler, closeHandler CloseHandler) (Writer, error) {
75
+ return func(ctx context.Context, msgHandler PacketDataHandler, closeHandler CloseHandler) (Writer, error) {
76
76
  mstrm, err := conn.OpenStream(ctx)
77
77
  if err != nil {
78
78
  return nil, err