@replit/river 0.17.3 → 0.18.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 -3
- package/dist/{chunk-7WY3Z5ZN.js → chunk-CLY7AQ25.js} +169 -95
- package/dist/{chunk-4C2OXQJB.js → chunk-TIFNW5GQ.js} +62 -65
- package/dist/{chunk-F3LFO3GU.js → chunk-UEKU6XRG.js} +1 -1
- package/dist/chunk-YITXOAPA.js +72 -0
- package/dist/{chunk-Q7OSVPZ5.js → chunk-ZPPKYJI7.js} +1 -1
- package/dist/{connection-713c8c66.d.ts → connection-32bf6608.d.ts} +1 -1
- package/dist/{connection-b79329de.d.ts → connection-df5f32ee.d.ts} +1 -1
- package/dist/{index-80f87385.d.ts → index-314e676a.d.ts} +4 -86
- package/dist/index-6118cd48.d.ts +117 -0
- package/dist/logging/index.cjs +63 -27
- package/dist/logging/index.d.cts +2 -34
- package/dist/logging/index.d.ts +2 -34
- package/dist/logging/index.js +7 -7
- package/dist/{procedures-79a5f07e.d.ts → procedures-74a10937.d.ts} +4 -3
- package/dist/router/index.cjs +63 -66
- package/dist/router/index.d.cts +43 -42
- package/dist/router/index.d.ts +43 -42
- package/dist/router/index.js +2 -2
- package/dist/transport/impls/uds/client.cjs +152 -84
- package/dist/transport/impls/uds/client.d.cts +3 -2
- package/dist/transport/impls/uds/client.d.ts +3 -2
- package/dist/transport/impls/uds/client.js +7 -4
- package/dist/transport/impls/uds/server.cjs +116 -65
- package/dist/transport/impls/uds/server.d.cts +3 -2
- package/dist/transport/impls/uds/server.d.ts +3 -2
- package/dist/transport/impls/uds/server.js +3 -3
- package/dist/transport/impls/ws/client.cjs +156 -87
- package/dist/transport/impls/ws/client.d.cts +3 -2
- package/dist/transport/impls/ws/client.d.ts +3 -2
- package/dist/transport/impls/ws/client.js +11 -7
- package/dist/transport/impls/ws/server.cjs +116 -65
- package/dist/transport/impls/ws/server.d.cts +4 -3
- package/dist/transport/impls/ws/server.d.ts +4 -3
- package/dist/transport/impls/ws/server.js +3 -3
- package/dist/transport/index.cjs +170 -96
- package/dist/transport/index.d.cts +2 -1
- package/dist/transport/index.d.ts +2 -1
- package/dist/transport/index.js +2 -2
- package/dist/util/testHelpers.cjs +65 -32
- package/dist/util/testHelpers.d.cts +8 -7
- package/dist/util/testHelpers.d.ts +8 -7
- package/dist/util/testHelpers.js +20 -18
- package/package.json +1 -1
- package/dist/chunk-H4BYJELI.js +0 -37
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-VH3NGOXQ.js";
|
|
7
7
|
import {
|
|
8
8
|
log
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YITXOAPA.js";
|
|
10
10
|
|
|
11
11
|
// router/services.ts
|
|
12
12
|
import { Type } from "@sinclair/typebox";
|
|
@@ -637,46 +637,25 @@ var createClient = (transport, serverId, providedClientOptions = {}) => {
|
|
|
637
637
|
);
|
|
638
638
|
}
|
|
639
639
|
const [input] = opts.args;
|
|
640
|
-
log?.info(
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
640
|
+
log?.info(`invoked ${procType} ${serviceName}.${procName}`, {
|
|
641
|
+
clientId: transport.clientId,
|
|
642
|
+
partialTransportMessage: {
|
|
643
|
+
procedureName: procName,
|
|
644
|
+
serviceName,
|
|
645
|
+
payload: input
|
|
646
|
+
}
|
|
647
|
+
});
|
|
645
648
|
if (options.connectOnInvoke && !transport.connections.has(serverId)) {
|
|
646
649
|
void transport.connect(serverId);
|
|
647
650
|
}
|
|
648
651
|
if (procType === "rpc") {
|
|
649
|
-
return handleRpc(
|
|
650
|
-
transport,
|
|
651
|
-
serverId,
|
|
652
|
-
input,
|
|
653
|
-
serviceName,
|
|
654
|
-
procName
|
|
655
|
-
);
|
|
652
|
+
return handleRpc(transport, serverId, input, serviceName, procName);
|
|
656
653
|
} else if (procType === "stream") {
|
|
657
|
-
return handleStream(
|
|
658
|
-
transport,
|
|
659
|
-
serverId,
|
|
660
|
-
input,
|
|
661
|
-
serviceName,
|
|
662
|
-
procName
|
|
663
|
-
);
|
|
654
|
+
return handleStream(transport, serverId, input, serviceName, procName);
|
|
664
655
|
} else if (procType === "subscribe") {
|
|
665
|
-
return handleSubscribe(
|
|
666
|
-
transport,
|
|
667
|
-
serverId,
|
|
668
|
-
input,
|
|
669
|
-
serviceName,
|
|
670
|
-
procName
|
|
671
|
-
);
|
|
656
|
+
return handleSubscribe(transport, serverId, input, serviceName, procName);
|
|
672
657
|
} else if (procType === "upload") {
|
|
673
|
-
return handleUpload(
|
|
674
|
-
transport,
|
|
675
|
-
serverId,
|
|
676
|
-
input,
|
|
677
|
-
serviceName,
|
|
678
|
-
procName
|
|
679
|
-
);
|
|
658
|
+
return handleUpload(transport, serverId, input, serviceName, procName);
|
|
680
659
|
} else {
|
|
681
660
|
throw new Error(`invalid river call, unknown procedure type ${procType}`);
|
|
682
661
|
}
|
|
@@ -950,9 +929,10 @@ var RiverServer = class {
|
|
|
950
929
|
}
|
|
951
930
|
onMessage = async (message) => {
|
|
952
931
|
if (message.to !== this.transport.clientId) {
|
|
953
|
-
log?.info(
|
|
954
|
-
|
|
955
|
-
|
|
932
|
+
log?.info(`got msg with destination that isn't this server, ignoring`, {
|
|
933
|
+
clientId: this.transport.clientId,
|
|
934
|
+
fullTransportMessage: message
|
|
935
|
+
});
|
|
956
936
|
return;
|
|
957
937
|
}
|
|
958
938
|
let procStream = this.streamMap.get(message.streamId);
|
|
@@ -969,7 +949,8 @@ var RiverServer = class {
|
|
|
969
949
|
return;
|
|
970
950
|
const disconnectedClientId = evt.session.to;
|
|
971
951
|
log?.info(
|
|
972
|
-
|
|
952
|
+
`got session disconnect from ${disconnectedClientId}, cleaning up streams`,
|
|
953
|
+
evt.session.loggingMetadata
|
|
973
954
|
);
|
|
974
955
|
const streamsFromThisClient = this.clientStreams.get(disconnectedClientId);
|
|
975
956
|
if (!streamsFromThisClient)
|
|
@@ -989,37 +970,43 @@ var RiverServer = class {
|
|
|
989
970
|
createNewProcStream(message) {
|
|
990
971
|
if (!isStreamOpen(message.controlFlags)) {
|
|
991
972
|
log?.error(
|
|
992
|
-
|
|
973
|
+
`can't create a new procedure stream from a message that doesn't have the stream open bit set`,
|
|
974
|
+
{ clientId: this.transport.clientId, fullTransportMessage: message }
|
|
993
975
|
);
|
|
994
|
-
log?.debug(` -> ${JSON.stringify(message)}`);
|
|
995
976
|
return;
|
|
996
977
|
}
|
|
997
978
|
if (!message.procedureName || !message.serviceName) {
|
|
998
|
-
log?.warn(
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
979
|
+
log?.warn(`missing procedure or service name in stream open message`, {
|
|
980
|
+
clientId: this.transport.clientId,
|
|
981
|
+
fullTransportMessage: message
|
|
982
|
+
});
|
|
1002
983
|
return;
|
|
1003
984
|
}
|
|
1004
985
|
if (!(message.serviceName in this.services)) {
|
|
1005
|
-
log?.warn(
|
|
1006
|
-
|
|
1007
|
-
|
|
986
|
+
log?.warn(`couldn't find service ${message.serviceName}`, {
|
|
987
|
+
clientId: this.transport.clientId,
|
|
988
|
+
fullTransportMessage: message
|
|
989
|
+
});
|
|
1008
990
|
return;
|
|
1009
991
|
}
|
|
1010
992
|
const service = this.services[message.serviceName];
|
|
1011
993
|
const serviceContext = this.getContext(service, message.serviceName);
|
|
1012
994
|
if (!(message.procedureName in service.procedures)) {
|
|
1013
995
|
log?.warn(
|
|
1014
|
-
|
|
996
|
+
`couldn't find a matching procedure for ${message.serviceName}.${message.procedureName}`,
|
|
997
|
+
{
|
|
998
|
+
clientId: this.transport.clientId,
|
|
999
|
+
fullTransportMessage: message
|
|
1000
|
+
}
|
|
1015
1001
|
);
|
|
1016
1002
|
return;
|
|
1017
1003
|
}
|
|
1018
1004
|
const session = this.transport.sessions.get(message.from);
|
|
1019
1005
|
if (!session) {
|
|
1020
|
-
log?.warn(
|
|
1021
|
-
|
|
1022
|
-
|
|
1006
|
+
log?.warn(`couldn't find session for ${message.from}`, {
|
|
1007
|
+
clientId: this.transport.clientId,
|
|
1008
|
+
fullTransportMessage: message
|
|
1009
|
+
});
|
|
1023
1010
|
return;
|
|
1024
1011
|
}
|
|
1025
1012
|
const procedure = service.procedures[message.procedureName];
|
|
@@ -1062,7 +1049,8 @@ var RiverServer = class {
|
|
|
1062
1049
|
const errorHandler = (err) => {
|
|
1063
1050
|
const errorMsg = coerceErrorString(err);
|
|
1064
1051
|
log?.error(
|
|
1065
|
-
|
|
1052
|
+
`procedure ${message.serviceName}.${message.procedureName} threw an uncaught error: ${errorMsg}`,
|
|
1053
|
+
session.loggingMetadata
|
|
1066
1054
|
);
|
|
1067
1055
|
outgoing.push(
|
|
1068
1056
|
Err({
|
|
@@ -1105,12 +1093,19 @@ var RiverServer = class {
|
|
|
1105
1093
|
if (initMessage.done) {
|
|
1106
1094
|
return;
|
|
1107
1095
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1096
|
+
try {
|
|
1097
|
+
const dispose = await procedure.handler(
|
|
1098
|
+
serviceContextWithTransportInfo,
|
|
1099
|
+
initMessage.value,
|
|
1100
|
+
incoming,
|
|
1101
|
+
outgoing
|
|
1102
|
+
);
|
|
1103
|
+
if (dispose) {
|
|
1104
|
+
disposables.push(dispose);
|
|
1105
|
+
}
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
errorHandler(err);
|
|
1108
|
+
}
|
|
1114
1109
|
})();
|
|
1115
1110
|
} else {
|
|
1116
1111
|
inputHandler = procedure.handler(serviceContextWithTransportInfo, incoming, outgoing).catch(errorHandler);
|
|
@@ -1174,7 +1169,8 @@ var RiverServer = class {
|
|
|
1174
1169
|
break;
|
|
1175
1170
|
default:
|
|
1176
1171
|
log?.warn(
|
|
1177
|
-
|
|
1172
|
+
`got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`,
|
|
1173
|
+
{ ...session.loggingMetadata, fullTransportMessage: message }
|
|
1178
1174
|
);
|
|
1179
1175
|
return;
|
|
1180
1176
|
}
|
|
@@ -1202,9 +1198,8 @@ var RiverServer = class {
|
|
|
1202
1198
|
procStream.incoming.push(message.payload);
|
|
1203
1199
|
} else if (!Value.Check(ControlMessagePayloadSchema, message.payload)) {
|
|
1204
1200
|
log?.error(
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
)}`
|
|
1201
|
+
`procedure ${serviceName}.${procedureName} received invalid payload`,
|
|
1202
|
+
{ clientId: this.transport.clientId, fullTransportMessage: message }
|
|
1208
1203
|
);
|
|
1209
1204
|
}
|
|
1210
1205
|
if (isStreamClose(message.controlFlags)) {
|
|
@@ -1218,11 +1213,13 @@ var RiverServer = class {
|
|
|
1218
1213
|
}
|
|
1219
1214
|
}
|
|
1220
1215
|
}
|
|
1221
|
-
getContext(service,
|
|
1216
|
+
getContext(service, serviceName) {
|
|
1222
1217
|
const context = this.contextMap.get(service);
|
|
1223
1218
|
if (!context) {
|
|
1224
|
-
const err =
|
|
1225
|
-
log?.error(err
|
|
1219
|
+
const err = `no context found for ${serviceName}`;
|
|
1220
|
+
log?.error(err, {
|
|
1221
|
+
clientId: this.transport.clientId
|
|
1222
|
+
});
|
|
1226
1223
|
throw new Error(err);
|
|
1227
1224
|
}
|
|
1228
1225
|
return context;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// logging/log.ts
|
|
2
|
+
var LoggingLevels = {
|
|
3
|
+
debug: -1,
|
|
4
|
+
info: 0,
|
|
5
|
+
warn: 1,
|
|
6
|
+
error: 2
|
|
7
|
+
};
|
|
8
|
+
var BaseLogger = class {
|
|
9
|
+
minLevel;
|
|
10
|
+
output;
|
|
11
|
+
constructor(output, minLevel = "info") {
|
|
12
|
+
this.minLevel = minLevel;
|
|
13
|
+
this.output = output;
|
|
14
|
+
}
|
|
15
|
+
debug(msg, metadata) {
|
|
16
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.debug) {
|
|
17
|
+
this.output(msg, metadata ?? {}, "debug");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
info(msg, metadata) {
|
|
21
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.info) {
|
|
22
|
+
this.output(msg, metadata ?? {}, "info");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
warn(msg, metadata) {
|
|
26
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.warn) {
|
|
27
|
+
this.output(msg, metadata ?? {}, "warn");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
error(msg, metadata) {
|
|
31
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.error) {
|
|
32
|
+
this.output(msg, metadata ?? {}, "error");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var stringLogger = (msg, _ctx, level) => {
|
|
37
|
+
console.log(`[river:${level}] ${msg}`);
|
|
38
|
+
};
|
|
39
|
+
var colorMap = {
|
|
40
|
+
debug: "\x1B[34m",
|
|
41
|
+
info: "\x1B[32m",
|
|
42
|
+
warn: "\x1B[33m",
|
|
43
|
+
error: "\x1B[31m"
|
|
44
|
+
};
|
|
45
|
+
var coloredStringLogger = (msg, _ctx, level) => {
|
|
46
|
+
const color = colorMap[level];
|
|
47
|
+
console.log(`[river:${color}${level}\x1B[0m] ${msg}`);
|
|
48
|
+
};
|
|
49
|
+
var jsonLogger = (msg, ctx, level) => {
|
|
50
|
+
console.log(JSON.stringify({ msg, ctx, level }));
|
|
51
|
+
};
|
|
52
|
+
var log = void 0;
|
|
53
|
+
function bindLogger(fn, level) {
|
|
54
|
+
if (!fn) {
|
|
55
|
+
log = void 0;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (fn instanceof BaseLogger) {
|
|
59
|
+
log = fn;
|
|
60
|
+
return fn;
|
|
61
|
+
}
|
|
62
|
+
log = new BaseLogger(fn, level);
|
|
63
|
+
return log;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
stringLogger,
|
|
68
|
+
coloredStringLogger,
|
|
69
|
+
jsonLogger,
|
|
70
|
+
log,
|
|
71
|
+
bindLogger
|
|
72
|
+
};
|
|
@@ -1,88 +1,5 @@
|
|
|
1
1
|
import { C as Codec } from './types-3e5768ec.js';
|
|
2
|
-
import
|
|
3
|
-
import { TSchema } from '@sinclair/typebox';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Generic Typebox schema for a transport message.
|
|
7
|
-
* @template T The type of the payload.
|
|
8
|
-
* @param {T} t The payload schema.
|
|
9
|
-
* @returns The transport message schema.
|
|
10
|
-
*/
|
|
11
|
-
declare const TransportMessageSchema: <T extends TSchema>(t: T) => _sinclair_typebox.TObject<{
|
|
12
|
-
id: _sinclair_typebox.TString;
|
|
13
|
-
from: _sinclair_typebox.TString;
|
|
14
|
-
to: _sinclair_typebox.TString;
|
|
15
|
-
seq: _sinclair_typebox.TInteger;
|
|
16
|
-
ack: _sinclair_typebox.TInteger;
|
|
17
|
-
serviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
18
|
-
procedureName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
19
|
-
streamId: _sinclair_typebox.TString;
|
|
20
|
-
controlFlags: _sinclair_typebox.TInteger;
|
|
21
|
-
payload: T;
|
|
22
|
-
}>;
|
|
23
|
-
/**
|
|
24
|
-
* Defines the schema for an opaque transport message that is agnostic to any
|
|
25
|
-
* procedure/service.
|
|
26
|
-
* @returns The transport message schema.
|
|
27
|
-
*/
|
|
28
|
-
declare const OpaqueTransportMessageSchema: _sinclair_typebox.TObject<{
|
|
29
|
-
id: _sinclair_typebox.TString;
|
|
30
|
-
from: _sinclair_typebox.TString;
|
|
31
|
-
to: _sinclair_typebox.TString;
|
|
32
|
-
seq: _sinclair_typebox.TInteger;
|
|
33
|
-
ack: _sinclair_typebox.TInteger;
|
|
34
|
-
serviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
35
|
-
procedureName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
36
|
-
streamId: _sinclair_typebox.TString;
|
|
37
|
-
controlFlags: _sinclair_typebox.TInteger;
|
|
38
|
-
payload: _sinclair_typebox.TUnknown;
|
|
39
|
-
}>;
|
|
40
|
-
/**
|
|
41
|
-
* Represents a transport message. This is the same type as {@link TransportMessageSchema} but
|
|
42
|
-
* we can't statically infer generics from generic Typebox schemas so we have to define it again here.
|
|
43
|
-
*
|
|
44
|
-
* TypeScript can't enforce types when a bitmask is involved, so these are the semantics of
|
|
45
|
-
* `controlFlags`:
|
|
46
|
-
* * If `controlFlags & StreamOpenBit == StreamOpenBit`, `streamId` must be set to a unique value
|
|
47
|
-
* (suggestion: use `nanoid`).
|
|
48
|
-
* * If `controlFlags & StreamOpenBit == StreamOpenBit`, `serviceName` and `procedureName` must be set.
|
|
49
|
-
* * If `controlFlags & StreamClosedBit == StreamClosedBit` and the kind is `stream` or `subscription`,
|
|
50
|
-
* `payload` should be discarded (usually contains a control message).
|
|
51
|
-
* * If `controlFlags & AckBit == AckBit`, the message is an explicit acknowledgement message and doesn't
|
|
52
|
-
* contain any payload that is relevant to the application so should not be delivered.
|
|
53
|
-
* @template Payload The type of the payload.
|
|
54
|
-
*/
|
|
55
|
-
interface TransportMessage<Payload = Record<string, unknown>> {
|
|
56
|
-
id: string;
|
|
57
|
-
from: string;
|
|
58
|
-
to: string;
|
|
59
|
-
seq: number;
|
|
60
|
-
ack: number;
|
|
61
|
-
serviceName?: string;
|
|
62
|
-
procedureName?: string;
|
|
63
|
-
streamId: string;
|
|
64
|
-
controlFlags: number;
|
|
65
|
-
payload: Payload;
|
|
66
|
-
}
|
|
67
|
-
type PartialTransportMessage<Payload extends Record<string, unknown> = Record<string, unknown>> = Omit<TransportMessage<Payload>, 'id' | 'from' | 'to' | 'seq' | 'ack'>;
|
|
68
|
-
/**
|
|
69
|
-
* A type alias for a transport message with an opaque payload.
|
|
70
|
-
* @template T - The type of the opaque payload.
|
|
71
|
-
*/
|
|
72
|
-
type OpaqueTransportMessage = TransportMessage<unknown>;
|
|
73
|
-
type TransportClientId = string;
|
|
74
|
-
/**
|
|
75
|
-
* Checks if the given control flag (usually found in msg.controlFlag) is a stream open message.
|
|
76
|
-
* @param controlFlag - The control flag to check.
|
|
77
|
-
* @returns True if the control flag contains the StreamOpenBit, false otherwise.
|
|
78
|
-
*/
|
|
79
|
-
declare function isStreamOpen(controlFlag: number): boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Checks if the given control flag (usually found in msg.controlFlag) is a stream close message.
|
|
82
|
-
* @param controlFlag - The control flag to check.
|
|
83
|
-
* @returns True if the control flag contains the StreamCloseBit, false otherwise.
|
|
84
|
-
*/
|
|
85
|
-
declare function isStreamClose(controlFlag: number): boolean;
|
|
2
|
+
import { T as TransportClientId, M as MessageMetadata, P as PartialTransportMessage, a as TransportMessage, O as OpaqueTransportMessage } from './index-6118cd48.js';
|
|
86
3
|
|
|
87
4
|
/**
|
|
88
5
|
* A connection is the actual raw underlying transport connection.
|
|
@@ -198,6 +115,7 @@ declare class Session<ConnType extends Connection> {
|
|
|
198
115
|
*/
|
|
199
116
|
private heartbeat;
|
|
200
117
|
constructor(conn: ConnType | undefined, from: TransportClientId, to: TransportClientId, options: SessionOptions);
|
|
118
|
+
get loggingMetadata(): Omit<MessageMetadata, 'parsedMsg'>;
|
|
201
119
|
/**
|
|
202
120
|
* Sends a message over the session's connection.
|
|
203
121
|
* If the connection is not ready or the message fails to send, the message can be buffered for retry unless skipped.
|
|
@@ -218,7 +136,7 @@ declare class Session<ConnType extends Connection> {
|
|
|
218
136
|
close(): void;
|
|
219
137
|
get connected(): boolean;
|
|
220
138
|
get nextExpectedSeq(): number;
|
|
221
|
-
constructMsg<Payload
|
|
139
|
+
constructMsg<Payload>(partialMsg: PartialTransportMessage<Payload>): TransportMessage<Payload>;
|
|
222
140
|
inspectSendBuffer(): ReadonlyArray<OpaqueTransportMessage>;
|
|
223
141
|
}
|
|
224
142
|
|
|
@@ -499,4 +417,4 @@ declare abstract class ServerTransport<ConnType extends Connection> extends Tran
|
|
|
499
417
|
receiveHandshakeRequestMessage(data: Uint8Array, conn: ConnType): Session<ConnType> | false;
|
|
500
418
|
}
|
|
501
419
|
|
|
502
|
-
export { Connection as C, EventMap as E,
|
|
420
|
+
export { Connection as C, EventMap as E, ProvidedClientTransportOptions as P, SessionOptions as S, Transport as T, Session as a, ClientTransport as b, ServerTransport as c, ProvidedTransportOptions as d, TransportStatus as e, EventTypes as f, EventHandler as g, ProtocolError as h, ProtocolErrorType as i };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
import { TSchema } from '@sinclair/typebox';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic Typebox schema for a transport message.
|
|
6
|
+
* @template T The type of the payload.
|
|
7
|
+
* @param {T} t The payload schema.
|
|
8
|
+
* @returns The transport message schema.
|
|
9
|
+
*/
|
|
10
|
+
declare const TransportMessageSchema: <T extends TSchema>(t: T) => _sinclair_typebox.TObject<{
|
|
11
|
+
id: _sinclair_typebox.TString;
|
|
12
|
+
from: _sinclair_typebox.TString;
|
|
13
|
+
to: _sinclair_typebox.TString;
|
|
14
|
+
seq: _sinclair_typebox.TInteger;
|
|
15
|
+
ack: _sinclair_typebox.TInteger;
|
|
16
|
+
serviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
17
|
+
procedureName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
18
|
+
streamId: _sinclair_typebox.TString;
|
|
19
|
+
controlFlags: _sinclair_typebox.TInteger;
|
|
20
|
+
payload: T;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Defines the schema for an opaque transport message that is agnostic to any
|
|
24
|
+
* procedure/service.
|
|
25
|
+
* @returns The transport message schema.
|
|
26
|
+
*/
|
|
27
|
+
declare const OpaqueTransportMessageSchema: _sinclair_typebox.TObject<{
|
|
28
|
+
id: _sinclair_typebox.TString;
|
|
29
|
+
from: _sinclair_typebox.TString;
|
|
30
|
+
to: _sinclair_typebox.TString;
|
|
31
|
+
seq: _sinclair_typebox.TInteger;
|
|
32
|
+
ack: _sinclair_typebox.TInteger;
|
|
33
|
+
serviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
34
|
+
procedureName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
35
|
+
streamId: _sinclair_typebox.TString;
|
|
36
|
+
controlFlags: _sinclair_typebox.TInteger;
|
|
37
|
+
payload: _sinclair_typebox.TUnknown;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Represents a transport message. This is the same type as {@link TransportMessageSchema} but
|
|
41
|
+
* we can't statically infer generics from generic Typebox schemas so we have to define it again here.
|
|
42
|
+
*
|
|
43
|
+
* TypeScript can't enforce types when a bitmask is involved, so these are the semantics of
|
|
44
|
+
* `controlFlags`:
|
|
45
|
+
* * If `controlFlags & StreamOpenBit == StreamOpenBit`, `streamId` must be set to a unique value
|
|
46
|
+
* (suggestion: use `nanoid`).
|
|
47
|
+
* * If `controlFlags & StreamOpenBit == StreamOpenBit`, `serviceName` and `procedureName` must be set.
|
|
48
|
+
* * If `controlFlags & StreamClosedBit == StreamClosedBit` and the kind is `stream` or `subscription`,
|
|
49
|
+
* `payload` should be discarded (usually contains a control message).
|
|
50
|
+
* * If `controlFlags & AckBit == AckBit`, the message is an explicit acknowledgement message and doesn't
|
|
51
|
+
* contain any payload that is relevant to the application so should not be delivered.
|
|
52
|
+
* @template Payload The type of the payload.
|
|
53
|
+
*/
|
|
54
|
+
interface TransportMessage<Payload = unknown> {
|
|
55
|
+
id: string;
|
|
56
|
+
from: string;
|
|
57
|
+
to: string;
|
|
58
|
+
seq: number;
|
|
59
|
+
ack: number;
|
|
60
|
+
serviceName?: string;
|
|
61
|
+
procedureName?: string;
|
|
62
|
+
streamId: string;
|
|
63
|
+
controlFlags: number;
|
|
64
|
+
payload: Payload;
|
|
65
|
+
}
|
|
66
|
+
type PartialTransportMessage<Payload = unknown> = Omit<TransportMessage<Payload>, 'id' | 'from' | 'to' | 'seq' | 'ack'>;
|
|
67
|
+
/**
|
|
68
|
+
* A type alias for a transport message with an opaque payload.
|
|
69
|
+
* @template T - The type of the opaque payload.
|
|
70
|
+
*/
|
|
71
|
+
type OpaqueTransportMessage = TransportMessage;
|
|
72
|
+
type TransportClientId = string;
|
|
73
|
+
/**
|
|
74
|
+
* Checks if the given control flag (usually found in msg.controlFlag) is a stream open message.
|
|
75
|
+
* @param controlFlag - The control flag to check.
|
|
76
|
+
* @returns True if the control flag contains the StreamOpenBit, false otherwise.
|
|
77
|
+
*/
|
|
78
|
+
declare function isStreamOpen(controlFlag: number): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Checks if the given control flag (usually found in msg.controlFlag) is a stream close message.
|
|
81
|
+
* @param controlFlag - The control flag to check.
|
|
82
|
+
* @returns True if the control flag contains the StreamCloseBit, false otherwise.
|
|
83
|
+
*/
|
|
84
|
+
declare function isStreamClose(controlFlag: number): boolean;
|
|
85
|
+
|
|
86
|
+
declare const LoggingLevels: {
|
|
87
|
+
readonly debug: -1;
|
|
88
|
+
readonly info: 0;
|
|
89
|
+
readonly warn: 1;
|
|
90
|
+
readonly error: 2;
|
|
91
|
+
};
|
|
92
|
+
type LoggingLevel = keyof typeof LoggingLevels;
|
|
93
|
+
type LogFn = (msg: string, ctx: MessageMetadata, level: LoggingLevel) => void;
|
|
94
|
+
type MessageMetadata = Record<string, unknown> & Partial<{
|
|
95
|
+
protocolVersion: string;
|
|
96
|
+
clientId: string;
|
|
97
|
+
connectedTo: string;
|
|
98
|
+
sessionId: string;
|
|
99
|
+
connId: string;
|
|
100
|
+
fullTransportMessage: OpaqueTransportMessage;
|
|
101
|
+
partialTransportMessage: Partial<PartialTransportMessage>;
|
|
102
|
+
}>;
|
|
103
|
+
declare class BaseLogger {
|
|
104
|
+
minLevel: LoggingLevel;
|
|
105
|
+
private output;
|
|
106
|
+
constructor(output: LogFn, minLevel?: LoggingLevel);
|
|
107
|
+
debug(msg: string, metadata?: MessageMetadata): void;
|
|
108
|
+
info(msg: string, metadata?: MessageMetadata): void;
|
|
109
|
+
warn(msg: string, metadata?: MessageMetadata): void;
|
|
110
|
+
error(msg: string, metadata?: MessageMetadata): void;
|
|
111
|
+
}
|
|
112
|
+
declare const stringLogger: LogFn;
|
|
113
|
+
declare const coloredStringLogger: LogFn;
|
|
114
|
+
declare const jsonLogger: LogFn;
|
|
115
|
+
declare function bindLogger(fn: LogFn | BaseLogger | undefined, level?: LoggingLevel): BaseLogger | undefined;
|
|
116
|
+
|
|
117
|
+
export { LogFn as L, MessageMetadata as M, OpaqueTransportMessage as O, PartialTransportMessage as P, TransportClientId as T, TransportMessage as a, TransportMessageSchema as b, OpaqueTransportMessageSchema as c, isStreamClose as d, coloredStringLogger as e, bindLogger as f, isStreamOpen as i, jsonLogger as j, stringLogger as s };
|
package/dist/logging/index.cjs
CHANGED
|
@@ -21,44 +21,80 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var logging_exports = {};
|
|
22
22
|
__export(logging_exports, {
|
|
23
23
|
bindLogger: () => bindLogger,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
coloredStringLogger: () => coloredStringLogger,
|
|
25
|
+
jsonLogger: () => jsonLogger,
|
|
26
|
+
stringLogger: () => stringLogger
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(logging_exports);
|
|
29
|
+
|
|
30
|
+
// logging/log.ts
|
|
29
31
|
var LoggingLevels = {
|
|
30
32
|
debug: -1,
|
|
31
33
|
info: 0,
|
|
32
34
|
warn: 1,
|
|
33
35
|
error: 2
|
|
34
36
|
};
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
var BaseLogger = class {
|
|
38
|
+
minLevel;
|
|
39
|
+
output;
|
|
40
|
+
constructor(output, minLevel = "info") {
|
|
41
|
+
this.minLevel = minLevel;
|
|
42
|
+
this.output = output;
|
|
43
|
+
}
|
|
44
|
+
debug(msg, metadata) {
|
|
45
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.debug) {
|
|
46
|
+
this.output(msg, metadata ?? {}, "debug");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
info(msg, metadata) {
|
|
50
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.info) {
|
|
51
|
+
this.output(msg, metadata ?? {}, "info");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
warn(msg, metadata) {
|
|
55
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.warn) {
|
|
56
|
+
this.output(msg, metadata ?? {}, "warn");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
error(msg, metadata) {
|
|
60
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.error) {
|
|
61
|
+
this.output(msg, metadata ?? {}, "error");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var stringLogger = (msg, _ctx, level) => {
|
|
66
|
+
console.log(`[river:${level}] ${msg}`);
|
|
67
|
+
};
|
|
68
|
+
var colorMap = {
|
|
69
|
+
debug: "\x1B[34m",
|
|
70
|
+
info: "\x1B[32m",
|
|
71
|
+
warn: "\x1B[33m",
|
|
72
|
+
error: "\x1B[31m"
|
|
73
|
+
};
|
|
74
|
+
var coloredStringLogger = (msg, _ctx, level) => {
|
|
75
|
+
const color = colorMap[level];
|
|
76
|
+
console.log(`[river:${color}${level}\x1B[0m] ${msg}`);
|
|
77
|
+
};
|
|
78
|
+
var jsonLogger = (msg, ctx, level) => {
|
|
79
|
+
console.log(JSON.stringify({ msg, ctx, level }));
|
|
80
|
+
};
|
|
81
|
+
var log = void 0;
|
|
82
|
+
function bindLogger(fn, level) {
|
|
83
|
+
if (!fn) {
|
|
84
|
+
log = void 0;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (fn instanceof BaseLogger) {
|
|
88
|
+
log = fn;
|
|
89
|
+
return fn;
|
|
56
90
|
}
|
|
91
|
+
log = new BaseLogger(fn, level);
|
|
92
|
+
return log;
|
|
57
93
|
}
|
|
58
94
|
// Annotate the CommonJS export names for ESM import in node:
|
|
59
95
|
0 && (module.exports = {
|
|
60
96
|
bindLogger,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
97
|
+
coloredStringLogger,
|
|
98
|
+
jsonLogger,
|
|
99
|
+
stringLogger
|
|
64
100
|
});
|