@replit/river 0.12.6 → 0.13.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/README.md +4 -1
- package/dist/{builder-c593de11.d.ts → builder-169fbf7f.d.ts} +16 -7
- package/dist/{chunk-AFLZ6INU.js → chunk-CBRQM65K.js} +29 -10
- package/dist/{chunk-IIBVKYDB.js → chunk-CDH7QSB4.js} +39 -1
- package/dist/{chunk-XFFS4UOD.js → chunk-MGGIUH5O.js} +7 -7
- package/dist/{chunk-VLBVQX5H.js → chunk-NPXAAD7M.js} +1 -1
- package/dist/{chunk-4SDJ5VN4.js → chunk-R2IMXRVU.js} +150 -116
- package/dist/{connection-ba37d174.d.ts → connection-ab681c08.d.ts} +1 -1
- package/dist/{messageFraming-b200ef25.d.ts → connection-dd789651.d.ts} +17 -2
- package/dist/{index-54e0f99c.d.ts → index-21c1b21d.d.ts} +29 -13
- package/dist/router/index.cjs +31 -13
- package/dist/router/index.d.cts +5 -5
- package/dist/router/index.d.ts +5 -5
- package/dist/router/index.js +2 -2
- package/dist/transport/impls/uds/client.cjs +143 -121
- package/dist/transport/impls/uds/client.d.cts +2 -3
- package/dist/transport/impls/uds/client.d.ts +2 -3
- package/dist/transport/impls/uds/client.js +5 -6
- package/dist/transport/impls/uds/server.cjs +151 -127
- package/dist/transport/impls/uds/server.d.cts +2 -3
- package/dist/transport/impls/uds/server.d.ts +2 -3
- package/dist/transport/impls/uds/server.js +4 -5
- package/dist/transport/impls/ws/client.cjs +147 -123
- package/dist/transport/impls/ws/client.d.cts +4 -4
- package/dist/transport/impls/ws/client.d.ts +4 -4
- package/dist/transport/impls/ws/client.js +7 -7
- package/dist/transport/impls/ws/server.cjs +151 -127
- package/dist/transport/impls/ws/server.d.cts +2 -2
- package/dist/transport/impls/ws/server.d.ts +2 -2
- package/dist/transport/impls/ws/server.js +4 -4
- package/dist/transport/index.cjs +202 -167
- package/dist/transport/index.d.cts +1 -1
- package/dist/transport/index.d.ts +1 -1
- package/dist/transport/index.js +3 -3
- package/dist/util/testHelpers.cjs +294 -16
- package/dist/util/testHelpers.d.cts +2 -2
- package/dist/util/testHelpers.d.ts +2 -2
- package/dist/util/testHelpers.js +30 -8
- package/package.json +1 -9
- package/dist/chunk-PBPXYLI6.js +0 -44
- package/dist/chunk-Q7GL34DZ.js +0 -47
- package/dist/connection-1f9971d8.d.ts +0 -17
- package/dist/connection-24d878ac.d.ts +0 -18
- package/dist/transport/impls/stdio/client.cjs +0 -904
- package/dist/transport/impls/stdio/client.d.cts +0 -27
- package/dist/transport/impls/stdio/client.d.ts +0 -27
- package/dist/transport/impls/stdio/client.js +0 -42
- package/dist/transport/impls/stdio/server.cjs +0 -879
- package/dist/transport/impls/stdio/server.d.cts +0 -25
- package/dist/transport/impls/stdio/server.d.ts +0 -25
- package/dist/transport/impls/stdio/server.js +0 -33
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ It's like tRPC/gRPC but with
|
|
|
8
8
|
- result types and error handling
|
|
9
9
|
- snappy DX (no code-generation)
|
|
10
10
|
- transparent reconnect support for long-lived sessions
|
|
11
|
-
- over any transport (WebSockets
|
|
11
|
+
- over any transport (WebSockets and Unix Domain Socket out of the box)
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
@@ -47,6 +47,7 @@ import { Type } from '@sinclair/typebox';
|
|
|
47
47
|
|
|
48
48
|
export const ExampleServiceConstructor = () =>
|
|
49
49
|
ServiceBuilder.create('example')
|
|
50
|
+
// initializer for shared state
|
|
50
51
|
.initialState({
|
|
51
52
|
count: 0,
|
|
52
53
|
})
|
|
@@ -55,7 +56,9 @@ export const ExampleServiceConstructor = () =>
|
|
|
55
56
|
input: Type.Object({ n: Type.Number() }),
|
|
56
57
|
output: Type.Object({ result: Type.Number() }),
|
|
57
58
|
errors: Type.Never(),
|
|
59
|
+
// note that a handler is unique per user RPC
|
|
58
60
|
async handler(ctx, { n }) {
|
|
61
|
+
// access and mutate shared state
|
|
59
62
|
ctx.state.count += n;
|
|
60
63
|
return Ok({ result: ctx.state.count });
|
|
61
64
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TObject, TUnion, TString, TSchema, TNever, TLiteral, Static } from '@sinclair/typebox';
|
|
2
2
|
import { Pushable } from 'it-pushable';
|
|
3
|
+
import { b as TransportClientId, d as Session, C as Connection } from './index-21c1b21d.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* The context for services/procedures. This is used only on
|
|
@@ -21,6 +22,7 @@ import { Pushable } from 'it-pushable';
|
|
|
21
22
|
* }
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
25
|
+
|
|
24
26
|
interface ServiceContext {
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
@@ -29,6 +31,13 @@ interface ServiceContext {
|
|
|
29
31
|
type ServiceContextWithState<State> = ServiceContext & {
|
|
30
32
|
state: State;
|
|
31
33
|
};
|
|
34
|
+
type ServiceContextWithTransportInfo<State> = ServiceContext & {
|
|
35
|
+
state: State;
|
|
36
|
+
to: TransportClientId;
|
|
37
|
+
from: TransportClientId;
|
|
38
|
+
streamId: string;
|
|
39
|
+
session: Session<Connection>;
|
|
40
|
+
};
|
|
32
41
|
|
|
33
42
|
type TLiteralString = TLiteral<string>;
|
|
34
43
|
type RiverErrorSchema = TObject<{
|
|
@@ -145,39 +154,39 @@ type Procedure<State, Ty extends ValidProcType, I extends PayloadType, O extends
|
|
|
145
154
|
input: I;
|
|
146
155
|
output: O;
|
|
147
156
|
errors: E;
|
|
148
|
-
handler: (context:
|
|
157
|
+
handler: (context: ServiceContextWithTransportInfo<State>, input: Static<I>) => Promise<Result<Static<O>, Static<E>>>;
|
|
149
158
|
type: Ty;
|
|
150
159
|
} : never : Ty extends 'upload' ? Init extends PayloadType ? {
|
|
151
160
|
init: Init;
|
|
152
161
|
input: I;
|
|
153
162
|
output: O;
|
|
154
163
|
errors: E;
|
|
155
|
-
handler: (context:
|
|
164
|
+
handler: (context: ServiceContextWithTransportInfo<State>, init: Static<Init>, input: AsyncIterableIterator<Static<I>>) => Promise<Result<Static<O>, Static<E>>>;
|
|
156
165
|
type: Ty;
|
|
157
166
|
} : {
|
|
158
167
|
input: I;
|
|
159
168
|
output: O;
|
|
160
169
|
errors: E;
|
|
161
|
-
handler: (context:
|
|
170
|
+
handler: (context: ServiceContextWithTransportInfo<State>, input: AsyncIterableIterator<Static<I>>) => Promise<Result<Static<O>, Static<E>>>;
|
|
162
171
|
type: Ty;
|
|
163
172
|
} : Ty extends 'subscription' ? Init extends null ? {
|
|
164
173
|
input: I;
|
|
165
174
|
output: O;
|
|
166
175
|
errors: E;
|
|
167
|
-
handler: (context:
|
|
176
|
+
handler: (context: ServiceContextWithTransportInfo<State>, input: Static<I>, output: Pushable<Result<Static<O>, Static<E>>>) => Promise<void>;
|
|
168
177
|
type: Ty;
|
|
169
178
|
} : never : Ty extends 'stream' ? Init extends PayloadType ? {
|
|
170
179
|
init: Init;
|
|
171
180
|
input: I;
|
|
172
181
|
output: O;
|
|
173
182
|
errors: E;
|
|
174
|
-
handler: (context:
|
|
183
|
+
handler: (context: ServiceContextWithTransportInfo<State>, init: Static<Init>, input: AsyncIterableIterator<Static<I>>, output: Pushable<Result<Static<O>, Static<E>>>) => Promise<void>;
|
|
175
184
|
type: Ty;
|
|
176
185
|
} : {
|
|
177
186
|
input: I;
|
|
178
187
|
output: O;
|
|
179
188
|
errors: E;
|
|
180
|
-
handler: (context:
|
|
189
|
+
handler: (context: ServiceContextWithTransportInfo<State>, input: AsyncIterableIterator<Static<I>>, output: Pushable<Result<Static<O>, Static<E>>>) => Promise<void>;
|
|
181
190
|
type: Ty;
|
|
182
191
|
} : never;
|
|
183
192
|
type AnyProcedure = Procedure<object, ValidProcType, PayloadType, PayloadType, RiverError, PayloadType | null>;
|
|
@@ -230,4 +239,4 @@ declare class ServiceBuilder<T extends Service<string, object, ProcListing>> {
|
|
|
230
239
|
}>;
|
|
231
240
|
}
|
|
232
241
|
|
|
233
|
-
export { AnyService as A, Err as E, Ok as O, PayloadType as P, RiverError as R, ServiceContext as S, UNCAUGHT_ERROR as U, ValidProcType as V, Procedure as a, Result as b, RiverUncaughtSchema as c, ProcType as d, ProcInput as e, ProcOutput as f, ProcErrors as g, ProcHasInit as h, ProcInit as i, ServiceBuilder as j, ProcListing as k, Service as l, ProcHandler as m, ServiceContextWithState as n,
|
|
242
|
+
export { AnyService as A, Err as E, Ok as O, PayloadType as P, RiverError as R, ServiceContext as S, UNCAUGHT_ERROR as U, ValidProcType as V, Procedure as a, Result as b, RiverUncaughtSchema as c, ProcType as d, ProcInput as e, ProcOutput as f, ProcErrors as g, ProcHasInit as h, ProcInit as i, ServiceBuilder as j, ProcListing as k, Service as l, ProcHandler as m, ServiceContextWithState as n, ServiceContextWithTransportInfo as o, RiverErrorSchema as p, serializeService as s };
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
coerceErrorString,
|
|
4
4
|
isStreamClose,
|
|
5
5
|
isStreamOpen
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MGGIUH5O.js";
|
|
7
7
|
import {
|
|
8
8
|
log
|
|
9
9
|
} from "./chunk-H4BYJELI.js";
|
|
@@ -429,7 +429,8 @@ function _createRecursiveProxy(callback, path) {
|
|
|
429
429
|
});
|
|
430
430
|
return proxy;
|
|
431
431
|
}
|
|
432
|
-
var createClient = (transport
|
|
432
|
+
var createClient = (transport) => _createRecursiveProxy(async (opts) => {
|
|
433
|
+
const serverId = transport.connectedTo;
|
|
433
434
|
const [serviceName, procName, procType] = [...opts.path];
|
|
434
435
|
if (!(serviceName && procName && procType)) {
|
|
435
436
|
throw new Error(
|
|
@@ -781,7 +782,13 @@ var RiverServer = class {
|
|
|
781
782
|
);
|
|
782
783
|
return;
|
|
783
784
|
}
|
|
784
|
-
if (!message.
|
|
785
|
+
if (!message.procedureName || !message.serviceName) {
|
|
786
|
+
log?.warn(
|
|
787
|
+
`${this.transport.clientId} -- missing procedure or service name in stream open message`
|
|
788
|
+
);
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (!(message.serviceName in this.services)) {
|
|
785
792
|
log?.warn(
|
|
786
793
|
`${this.transport.clientId} -- couldn't find service ${message.serviceName}`
|
|
787
794
|
);
|
|
@@ -789,7 +796,7 @@ var RiverServer = class {
|
|
|
789
796
|
}
|
|
790
797
|
const service = this.services[message.serviceName];
|
|
791
798
|
const serviceContext = this.getContext(service);
|
|
792
|
-
if (!
|
|
799
|
+
if (!(message.procedureName in service.procedures)) {
|
|
793
800
|
log?.warn(
|
|
794
801
|
`${this.transport.clientId} -- couldn't find a matching procedure for ${message.serviceName}.${message.procedureName}`
|
|
795
802
|
);
|
|
@@ -835,6 +842,13 @@ var RiverServer = class {
|
|
|
835
842
|
};
|
|
836
843
|
let inputHandler;
|
|
837
844
|
const procHasInitMessage = "init" in procedure;
|
|
845
|
+
const serviceContextWithTransportInfo = {
|
|
846
|
+
...serviceContext,
|
|
847
|
+
to: message.to,
|
|
848
|
+
from: message.from,
|
|
849
|
+
streamId: message.streamId,
|
|
850
|
+
session
|
|
851
|
+
};
|
|
838
852
|
switch (procedure.type) {
|
|
839
853
|
case "rpc":
|
|
840
854
|
inputHandler = (async () => {
|
|
@@ -844,7 +858,7 @@ var RiverServer = class {
|
|
|
844
858
|
}
|
|
845
859
|
try {
|
|
846
860
|
const outputMessage = await procedure.handler(
|
|
847
|
-
|
|
861
|
+
serviceContextWithTransportInfo,
|
|
848
862
|
inputMessage.value
|
|
849
863
|
);
|
|
850
864
|
outgoing.push(outputMessage);
|
|
@@ -860,10 +874,15 @@ var RiverServer = class {
|
|
|
860
874
|
if (initMessage.done) {
|
|
861
875
|
return;
|
|
862
876
|
}
|
|
863
|
-
return procedure.handler(
|
|
877
|
+
return procedure.handler(
|
|
878
|
+
serviceContextWithTransportInfo,
|
|
879
|
+
initMessage.value,
|
|
880
|
+
incoming,
|
|
881
|
+
outgoing
|
|
882
|
+
).catch(errorHandler);
|
|
864
883
|
})();
|
|
865
884
|
} else {
|
|
866
|
-
inputHandler = procedure.handler(
|
|
885
|
+
inputHandler = procedure.handler(serviceContextWithTransportInfo, incoming, outgoing).catch(errorHandler);
|
|
867
886
|
}
|
|
868
887
|
break;
|
|
869
888
|
case "subscription":
|
|
@@ -874,7 +893,7 @@ var RiverServer = class {
|
|
|
874
893
|
}
|
|
875
894
|
try {
|
|
876
895
|
await procedure.handler(
|
|
877
|
-
|
|
896
|
+
serviceContextWithTransportInfo,
|
|
878
897
|
inputMessage.value,
|
|
879
898
|
outgoing
|
|
880
899
|
);
|
|
@@ -892,7 +911,7 @@ var RiverServer = class {
|
|
|
892
911
|
}
|
|
893
912
|
try {
|
|
894
913
|
const outputMessage = await procedure.handler(
|
|
895
|
-
|
|
914
|
+
serviceContextWithTransportInfo,
|
|
896
915
|
initMessage.value,
|
|
897
916
|
incoming
|
|
898
917
|
);
|
|
@@ -907,7 +926,7 @@ var RiverServer = class {
|
|
|
907
926
|
inputHandler = (async () => {
|
|
908
927
|
try {
|
|
909
928
|
const outputMessage = await procedure.handler(
|
|
910
|
-
|
|
929
|
+
serviceContextWithTransportInfo,
|
|
911
930
|
incoming
|
|
912
931
|
);
|
|
913
932
|
if (!this.disconnectedSessions.has(message.from)) {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Connection
|
|
3
|
+
} from "./chunk-R2IMXRVU.js";
|
|
4
|
+
|
|
1
5
|
// transport/transforms/messageFraming.ts
|
|
2
6
|
import { Transform } from "node:stream";
|
|
3
7
|
var Uint32LengthPrefixFraming = class extends Transform {
|
|
@@ -57,6 +61,40 @@ var MessageFramer = {
|
|
|
57
61
|
}
|
|
58
62
|
};
|
|
59
63
|
|
|
64
|
+
// transport/impls/uds/connection.ts
|
|
65
|
+
var UdsConnection = class extends Connection {
|
|
66
|
+
sock;
|
|
67
|
+
input;
|
|
68
|
+
framer;
|
|
69
|
+
constructor(sock) {
|
|
70
|
+
super();
|
|
71
|
+
this.framer = MessageFramer.createFramedStream();
|
|
72
|
+
this.sock = sock;
|
|
73
|
+
this.input = sock.pipe(this.framer);
|
|
74
|
+
}
|
|
75
|
+
addDataListener(cb) {
|
|
76
|
+
this.input.on("data", cb);
|
|
77
|
+
}
|
|
78
|
+
removeDataListener(cb) {
|
|
79
|
+
this.input.off("data", cb);
|
|
80
|
+
}
|
|
81
|
+
addCloseListener(cb) {
|
|
82
|
+
this.sock.on("close", cb);
|
|
83
|
+
}
|
|
84
|
+
addErrorListener(cb) {
|
|
85
|
+
this.sock.on("error", cb);
|
|
86
|
+
}
|
|
87
|
+
send(payload) {
|
|
88
|
+
if (this.framer.destroyed || !this.sock.writable)
|
|
89
|
+
return false;
|
|
90
|
+
return this.sock.write(MessageFramer.write(payload));
|
|
91
|
+
}
|
|
92
|
+
close() {
|
|
93
|
+
this.sock.destroy();
|
|
94
|
+
this.framer.destroy();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
60
98
|
export {
|
|
61
|
-
|
|
99
|
+
UdsConnection
|
|
62
100
|
};
|
|
@@ -7,8 +7,8 @@ var TransportMessageSchema = (t) => Type.Object({
|
|
|
7
7
|
to: Type.String(),
|
|
8
8
|
seq: Type.Integer(),
|
|
9
9
|
ack: Type.Integer(),
|
|
10
|
-
serviceName: Type.Optional(Type.
|
|
11
|
-
procedureName: Type.Optional(Type.
|
|
10
|
+
serviceName: Type.Optional(Type.String()),
|
|
11
|
+
procedureName: Type.Optional(Type.String()),
|
|
12
12
|
streamId: Type.String(),
|
|
13
13
|
controlFlags: Type.Integer(),
|
|
14
14
|
payload: t
|
|
@@ -22,7 +22,7 @@ var ControlMessageCloseSchema = Type.Object({
|
|
|
22
22
|
var PROTOCOL_VERSION = "v1";
|
|
23
23
|
var ControlMessageHandshakeRequestSchema = Type.Object({
|
|
24
24
|
type: Type.Literal("HANDSHAKE_REQ"),
|
|
25
|
-
protocolVersion: Type.
|
|
25
|
+
protocolVersion: Type.String(),
|
|
26
26
|
instanceId: Type.String()
|
|
27
27
|
});
|
|
28
28
|
var ControlMessageHandshakeResponseSchema = Type.Object({
|
|
@@ -47,7 +47,7 @@ var ControlMessagePayloadSchema = Type.Union([
|
|
|
47
47
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
48
48
|
Type.Unknown()
|
|
49
49
|
);
|
|
50
|
-
function
|
|
50
|
+
function handshakeRequestMessage(from, to, instanceId) {
|
|
51
51
|
return {
|
|
52
52
|
id: nanoid(),
|
|
53
53
|
from,
|
|
@@ -63,7 +63,7 @@ function bootRequestMessage(from, to, instanceId) {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function handshakeResponseMessage(from, instanceId, to, ok) {
|
|
67
67
|
return {
|
|
68
68
|
id: nanoid(),
|
|
69
69
|
from,
|
|
@@ -118,8 +118,8 @@ export {
|
|
|
118
118
|
ControlMessageHandshakeResponseSchema,
|
|
119
119
|
ControlMessagePayloadSchema,
|
|
120
120
|
OpaqueTransportMessageSchema,
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
handshakeRequestMessage,
|
|
122
|
+
handshakeResponseMessage,
|
|
123
123
|
isAck,
|
|
124
124
|
isStreamOpen,
|
|
125
125
|
isStreamClose,
|