@replit/river 0.200.0-rc.9 → 0.200.2
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 +8 -8
- package/dist/{chunk-42Z2FQIU.js → chunk-6BH2CXVE.js} +21 -13
- package/dist/chunk-6BH2CXVE.js.map +1 -0
- package/dist/{chunk-4HT6P2ZG.js → chunk-A4JKES5A.js} +22 -30
- package/dist/chunk-A4JKES5A.js.map +1 -0
- package/dist/{chunk-4PVU7J25.js → chunk-AJGIY2UB.js} +1 -1
- package/dist/chunk-AJGIY2UB.js.map +1 -0
- package/dist/{chunk-EETL2L77.js → chunk-GJUUVID2.js} +14 -32
- package/dist/chunk-GJUUVID2.js.map +1 -0
- package/dist/{chunk-GR3AQKHL.js → chunk-HRKM7BIE.js} +14 -4
- package/dist/chunk-HRKM7BIE.js.map +1 -0
- package/dist/{chunk-ZXZE253M.js → chunk-PJB2Y2AV.js} +24 -37
- package/dist/chunk-PJB2Y2AV.js.map +1 -0
- package/dist/{chunk-I75XYO5W.js → chunk-QIDEN5PP.js} +82 -20
- package/dist/chunk-QIDEN5PP.js.map +1 -0
- package/dist/{chunk-VXYHC666.js → chunk-YTMS7OP6.js} +1 -1
- package/dist/chunk-YTMS7OP6.js.map +1 -0
- package/dist/chunk-Z4PX66JO.js +307 -0
- package/dist/chunk-Z4PX66JO.js.map +1 -0
- package/dist/{client-22a47343.d.ts → client-9292552a.d.ts} +3 -4
- package/dist/codec/index.cjs.map +1 -1
- package/dist/codec/index.js +1 -1
- package/dist/connection-94dea547.d.ts +32 -0
- package/dist/{context-b4aff18f.d.ts → context-69f37ac1.d.ts} +48 -43
- package/dist/logging/index.cjs.map +1 -1
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/{message-7d135e38.d.ts → message-57bb8187.d.ts} +5 -3
- package/dist/router/index.cjs +649 -709
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +22 -12
- package/dist/router/index.d.ts +22 -12
- package/dist/router/index.js +502 -404
- package/dist/router/index.js.map +1 -1
- package/dist/{server-dd6a9853.d.ts → server-8fdd7fb2.d.ts} +5 -5
- package/dist/{services-1b5ac5bc.d.ts → services-259f39a3.d.ts} +191 -194
- package/dist/transport/impls/ws/client.cjs +129 -62
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- 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/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +146 -70
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +6 -5
- package/dist/transport/impls/ws/server.d.ts +6 -5
- package/dist/transport/impls/ws/server.js +21 -9
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +138 -92
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +4 -4
- package/dist/transport/index.d.ts +4 -4
- package/dist/transport/index.js +7 -7
- package/dist/util/testHelpers.cjs +265 -327
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +36 -31
- package/dist/util/testHelpers.d.ts +36 -31
- package/dist/util/testHelpers.js +82 -52
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +4 -3
- package/dist/chunk-42Z2FQIU.js.map +0 -1
- package/dist/chunk-4HT6P2ZG.js.map +0 -1
- package/dist/chunk-4PVU7J25.js.map +0 -1
- package/dist/chunk-EETL2L77.js.map +0 -1
- package/dist/chunk-GR3AQKHL.js.map +0 -1
- package/dist/chunk-I75XYO5W.js.map +0 -1
- package/dist/chunk-MQ6ANR3H.js +0 -451
- package/dist/chunk-MQ6ANR3H.js.map +0 -1
- package/dist/chunk-VXYHC666.js.map +0 -1
- package/dist/chunk-ZXZE253M.js.map +0 -1
- package/dist/connection-260e45a8.d.ts +0 -11
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// router/errors.ts
|
|
2
|
+
import {
|
|
3
|
+
Kind,
|
|
4
|
+
Type
|
|
5
|
+
} from "@sinclair/typebox";
|
|
6
|
+
var UNCAUGHT_ERROR_CODE = "UNCAUGHT_ERROR";
|
|
7
|
+
var UNEXPECTED_DISCONNECT_CODE = "UNEXPECTED_DISCONNECT";
|
|
8
|
+
var INVALID_REQUEST_CODE = "INVALID_REQUEST";
|
|
9
|
+
var CANCEL_CODE = "CANCEL";
|
|
10
|
+
var ErrResultSchema = (t) => Type.Object({
|
|
11
|
+
ok: Type.Literal(false),
|
|
12
|
+
payload: t
|
|
13
|
+
});
|
|
14
|
+
var ReaderErrorSchema = Type.Union([
|
|
15
|
+
Type.Object({
|
|
16
|
+
code: Type.Literal(UNCAUGHT_ERROR_CODE),
|
|
17
|
+
message: Type.String()
|
|
18
|
+
}),
|
|
19
|
+
Type.Object({
|
|
20
|
+
code: Type.Literal(UNEXPECTED_DISCONNECT_CODE),
|
|
21
|
+
message: Type.String()
|
|
22
|
+
}),
|
|
23
|
+
Type.Object({
|
|
24
|
+
code: Type.Literal(INVALID_REQUEST_CODE),
|
|
25
|
+
message: Type.String()
|
|
26
|
+
}),
|
|
27
|
+
Type.Object({
|
|
28
|
+
code: Type.Literal(CANCEL_CODE),
|
|
29
|
+
message: Type.String()
|
|
30
|
+
})
|
|
31
|
+
]);
|
|
32
|
+
function isUnion(schema) {
|
|
33
|
+
return schema[Kind] === "Union";
|
|
34
|
+
}
|
|
35
|
+
function flattenErrorType(errType) {
|
|
36
|
+
if (!isUnion(errType)) {
|
|
37
|
+
return errType;
|
|
38
|
+
}
|
|
39
|
+
const flattenedTypes = [];
|
|
40
|
+
function flatten(type) {
|
|
41
|
+
if (isUnion(type)) {
|
|
42
|
+
for (const t of type.anyOf) {
|
|
43
|
+
flatten(t);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
flattenedTypes.push(type);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
flatten(errType);
|
|
50
|
+
return Type.Union(flattenedTypes);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// router/result.ts
|
|
54
|
+
import { Type as Type2 } from "@sinclair/typebox";
|
|
55
|
+
var AnyResultSchema = Type2.Union([
|
|
56
|
+
Type2.Object({
|
|
57
|
+
ok: Type2.Literal(false),
|
|
58
|
+
payload: Type2.Object({
|
|
59
|
+
code: Type2.String(),
|
|
60
|
+
message: Type2.String(),
|
|
61
|
+
extras: Type2.Optional(Type2.Unknown())
|
|
62
|
+
})
|
|
63
|
+
}),
|
|
64
|
+
Type2.Object({
|
|
65
|
+
ok: Type2.Literal(true),
|
|
66
|
+
payload: Type2.Unknown()
|
|
67
|
+
})
|
|
68
|
+
]);
|
|
69
|
+
function Ok(payload) {
|
|
70
|
+
return {
|
|
71
|
+
ok: true,
|
|
72
|
+
payload
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function Err(error) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
payload: error
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function unwrapOrThrow(result) {
|
|
82
|
+
if (result.ok) {
|
|
83
|
+
return result.payload;
|
|
84
|
+
}
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Cannot non-ok result, got: ${result.payload.code} - ${result.payload.message}`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// router/streams.ts
|
|
91
|
+
var ReadableBrokenError = {
|
|
92
|
+
code: "READABLE_BROKEN",
|
|
93
|
+
message: "Readable was broken before it is fully consumed"
|
|
94
|
+
};
|
|
95
|
+
function createPromiseWithResolvers() {
|
|
96
|
+
let resolve;
|
|
97
|
+
let reject;
|
|
98
|
+
const promise = new Promise((res, rej) => {
|
|
99
|
+
resolve = res;
|
|
100
|
+
reject = rej;
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
promise,
|
|
104
|
+
// @ts-expect-error promise callbacks are sync
|
|
105
|
+
resolve,
|
|
106
|
+
// @ts-expect-error promise callbacks are sync
|
|
107
|
+
reject
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
var ReadableImpl = class {
|
|
111
|
+
/**
|
|
112
|
+
* Whether the {@link Readable} is closed.
|
|
113
|
+
*
|
|
114
|
+
* Closed {@link Readable}s are done receiving values, but that doesn't affect
|
|
115
|
+
* any other aspect of the {@link Readable} such as it's consumability.
|
|
116
|
+
*/
|
|
117
|
+
closed = false;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the {@link Readable} is locked.
|
|
120
|
+
*
|
|
121
|
+
* @see {@link Readable}'s typedoc to understand locking
|
|
122
|
+
*/
|
|
123
|
+
locked = false;
|
|
124
|
+
/**
|
|
125
|
+
* Whether {@link break} was called.
|
|
126
|
+
*
|
|
127
|
+
* @see {@link break} for more information
|
|
128
|
+
*/
|
|
129
|
+
broken = false;
|
|
130
|
+
/**
|
|
131
|
+
* This flag allows us to avoid emitting a {@link ReadableBrokenError} after {@link break} was called
|
|
132
|
+
* in cases where the {@link queue} is fully consumed and {@link ReadableImpl} is {@link closed}. This is just an
|
|
133
|
+
* ergonomic feature to avoid emitting an error in our iteration when we don't have to.
|
|
134
|
+
*/
|
|
135
|
+
brokenWithValuesLeftToRead = false;
|
|
136
|
+
/**
|
|
137
|
+
* A list of values that have been pushed to the {@link ReadableImpl} but not yet emitted to the user.
|
|
138
|
+
*/
|
|
139
|
+
queue = [];
|
|
140
|
+
/**
|
|
141
|
+
* Used by methods in the class to signal to the iterator that it
|
|
142
|
+
* should check for the next value.
|
|
143
|
+
*/
|
|
144
|
+
next = null;
|
|
145
|
+
[Symbol.asyncIterator]() {
|
|
146
|
+
if (this.locked) {
|
|
147
|
+
throw new TypeError("Readable is already locked");
|
|
148
|
+
}
|
|
149
|
+
this.locked = true;
|
|
150
|
+
let didSignalBreak = false;
|
|
151
|
+
return {
|
|
152
|
+
next: async () => {
|
|
153
|
+
if (didSignalBreak) {
|
|
154
|
+
return {
|
|
155
|
+
done: true,
|
|
156
|
+
value: void 0
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
while (this.queue.length === 0) {
|
|
160
|
+
if (this.closed && !this.brokenWithValuesLeftToRead) {
|
|
161
|
+
return {
|
|
162
|
+
done: true,
|
|
163
|
+
value: void 0
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (this.broken) {
|
|
167
|
+
didSignalBreak = true;
|
|
168
|
+
return {
|
|
169
|
+
done: false,
|
|
170
|
+
value: Err(ReadableBrokenError)
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (!this.next) {
|
|
174
|
+
this.next = createPromiseWithResolvers();
|
|
175
|
+
}
|
|
176
|
+
await this.next.promise;
|
|
177
|
+
this.next = null;
|
|
178
|
+
}
|
|
179
|
+
const value = this.queue.shift();
|
|
180
|
+
return { done: false, value };
|
|
181
|
+
},
|
|
182
|
+
return: () => {
|
|
183
|
+
this.break();
|
|
184
|
+
return { done: true, value: void 0 };
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async collect() {
|
|
189
|
+
const array = [];
|
|
190
|
+
for await (const value of this) {
|
|
191
|
+
array.push(value);
|
|
192
|
+
}
|
|
193
|
+
return array;
|
|
194
|
+
}
|
|
195
|
+
break() {
|
|
196
|
+
if (this.broken) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.locked = true;
|
|
200
|
+
this.broken = true;
|
|
201
|
+
this.brokenWithValuesLeftToRead = this.queue.length > 0;
|
|
202
|
+
this.queue.length = 0;
|
|
203
|
+
this.next?.resolve();
|
|
204
|
+
}
|
|
205
|
+
isReadable() {
|
|
206
|
+
return !this.locked && !this.broken;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* @internal meant for use within river, not exposed as a public API
|
|
210
|
+
*
|
|
211
|
+
* Pushes a value to be read.
|
|
212
|
+
*/
|
|
213
|
+
_pushValue(value) {
|
|
214
|
+
if (this.broken) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (this.closed) {
|
|
218
|
+
throw new Error("Cannot push to closed Readable");
|
|
219
|
+
}
|
|
220
|
+
this.queue.push(value);
|
|
221
|
+
this.next?.resolve();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* @internal meant for use within river, not exposed as a public API
|
|
225
|
+
*
|
|
226
|
+
* Triggers the close of the {@link Readable}. Make sure to push all remaining
|
|
227
|
+
* values before calling this method.
|
|
228
|
+
*/
|
|
229
|
+
_triggerClose() {
|
|
230
|
+
if (this.closed) {
|
|
231
|
+
throw new Error("Unexpected closing multiple times");
|
|
232
|
+
}
|
|
233
|
+
this.closed = true;
|
|
234
|
+
this.next?.resolve();
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* @internal meant for use within river, not exposed as a public API
|
|
238
|
+
*/
|
|
239
|
+
_hasValuesInQueue() {
|
|
240
|
+
return this.queue.length > 0;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* @internal meant for use within river, not exposed as a public API
|
|
244
|
+
*/
|
|
245
|
+
isClosed() {
|
|
246
|
+
return this.closed;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
var WritableImpl = class {
|
|
250
|
+
/**
|
|
251
|
+
* Passed via constructor to pass on calls to {@link write}
|
|
252
|
+
*/
|
|
253
|
+
writeCb;
|
|
254
|
+
/**
|
|
255
|
+
* Passed via constructor to pass on calls to {@link close}
|
|
256
|
+
*/
|
|
257
|
+
closeCb;
|
|
258
|
+
/**
|
|
259
|
+
* Whether {@link close} was called, and {@link Writable} is not writable anymore.
|
|
260
|
+
*/
|
|
261
|
+
closed = false;
|
|
262
|
+
constructor(callbacks) {
|
|
263
|
+
this.writeCb = callbacks.writeCb;
|
|
264
|
+
this.closeCb = callbacks.closeCb;
|
|
265
|
+
}
|
|
266
|
+
write(value) {
|
|
267
|
+
if (this.closed) {
|
|
268
|
+
throw new Error("Cannot write to closed Writable");
|
|
269
|
+
}
|
|
270
|
+
this.writeCb(value);
|
|
271
|
+
}
|
|
272
|
+
isWritable() {
|
|
273
|
+
return !this.closed;
|
|
274
|
+
}
|
|
275
|
+
close() {
|
|
276
|
+
if (this.closed) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
this.closed = true;
|
|
280
|
+
this.writeCb = () => void 0;
|
|
281
|
+
this.closeCb();
|
|
282
|
+
this.closeCb = () => void 0;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* @internal meant for use within river, not exposed as a public API
|
|
286
|
+
*/
|
|
287
|
+
isClosed() {
|
|
288
|
+
return this.closed;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
export {
|
|
293
|
+
UNCAUGHT_ERROR_CODE,
|
|
294
|
+
UNEXPECTED_DISCONNECT_CODE,
|
|
295
|
+
INVALID_REQUEST_CODE,
|
|
296
|
+
CANCEL_CODE,
|
|
297
|
+
ErrResultSchema,
|
|
298
|
+
ReaderErrorSchema,
|
|
299
|
+
flattenErrorType,
|
|
300
|
+
AnyResultSchema,
|
|
301
|
+
Ok,
|
|
302
|
+
Err,
|
|
303
|
+
unwrapOrThrow,
|
|
304
|
+
ReadableImpl,
|
|
305
|
+
WritableImpl
|
|
306
|
+
};
|
|
307
|
+
//# sourceMappingURL=chunk-Z4PX66JO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../router/errors.ts","../router/result.ts","../router/streams.ts"],"sourcesContent":["import {\n Kind,\n TLiteral,\n TNever,\n TObject,\n TSchema,\n TString,\n TUnion,\n Type,\n} from '@sinclair/typebox';\n\n/**\n * {@link UNCAUGHT_ERROR_CODE} is the code that is used when an error is thrown\n * inside a procedure handler that's not required.\n */\nexport const UNCAUGHT_ERROR_CODE = 'UNCAUGHT_ERROR';\n/**\n * {@link UNEXPECTED_DISCONNECT_CODE} is the code used the stream's session\n * disconnect unexpetedly.\n */\nexport const UNEXPECTED_DISCONNECT_CODE = 'UNEXPECTED_DISCONNECT';\n/**\n * {@link INVALID_REQUEST_CODE} is the code used when a client's request is invalid.\n */\nexport const INVALID_REQUEST_CODE = 'INVALID_REQUEST';\n/**\n * {@link CANCEL_CODE} is the code used when either server or client cancels the stream.\n */\nexport const CANCEL_CODE = 'CANCEL';\n\ntype TLiteralString = TLiteral<string>;\n\nexport type BaseErrorSchemaType =\n | TObject<{\n code: TLiteralString;\n message: TLiteralString | TString;\n }>\n | TObject<{\n code: TLiteralString;\n message: TLiteralString | TString;\n extras: TSchema;\n }>;\n\n/**\n * Takes in a specific error schema and returns a result schema the error\n */\nexport const ErrResultSchema = <T extends ProcedureErrorSchemaType>(t: T) =>\n Type.Object({\n ok: Type.Literal(false),\n payload: t,\n });\n\n/**\n * {@link ReaderErrorSchema} is the schema for all the built-in river errors that\n * can be emitted to a reader (request reader on the server, and response reader\n * on the client).\n */\nexport const ReaderErrorSchema = Type.Union([\n Type.Object({\n code: Type.Literal(UNCAUGHT_ERROR_CODE),\n message: Type.String(),\n }),\n Type.Object({\n code: Type.Literal(UNEXPECTED_DISCONNECT_CODE),\n message: Type.String(),\n }),\n Type.Object({\n code: Type.Literal(INVALID_REQUEST_CODE),\n message: Type.String(),\n }),\n Type.Object({\n code: Type.Literal(CANCEL_CODE),\n message: Type.String(),\n }),\n]) satisfies ProcedureErrorSchemaType;\n\n/**\n * Represents an acceptable schema to pass to a procedure.\n * Just a type of a schema, not an actual schema.\n *\n */\nexport type ProcedureErrorSchemaType =\n | TNever\n | BaseErrorSchemaType\n | TUnion<Array<BaseErrorSchemaType>>;\n\n// arbitrarily nested unions\n// river doesn't accept this by default, use the `flattenErrorType` helper\ntype NestableProcedureErrorSchemaType =\n | BaseErrorSchemaType\n | TUnion<NestableProcedureErrorSchemaTypeArray>;\n\n// use an interface to defer the type definition to be evaluated lazily\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface NestableProcedureErrorSchemaTypeArray\n extends Array<NestableProcedureErrorSchemaType> {}\n\nfunction isUnion(schema: TSchema): schema is TUnion {\n return schema[Kind] === 'Union';\n}\n\ntype Flatten<T> = T extends BaseErrorSchemaType\n ? T\n : T extends TUnion<Array<infer U extends TSchema>>\n ? Flatten<U>\n : unknown;\n\n/**\n * In the case where API consumers for some god-forsaken reason want to use\n * arbitrarily nested unions, this helper flattens them to a single level.\n *\n * Note that loses some metadata information on the nested unions like\n * nested description fields, etc.\n *\n * @param errType - An arbitrarily union-nested error schema.\n * @returns The flattened error schema.\n */\nexport function flattenErrorType<T extends NestableProcedureErrorSchemaType>(\n errType: T,\n): Flatten<T>;\nexport function flattenErrorType(\n errType: NestableProcedureErrorSchemaType,\n): ProcedureErrorSchemaType {\n if (!isUnion(errType)) {\n return errType;\n }\n\n const flattenedTypes: Array<BaseErrorSchemaType> = [];\n function flatten(type: NestableProcedureErrorSchemaType) {\n if (isUnion(type)) {\n for (const t of type.anyOf) {\n flatten(t);\n }\n } else {\n flattenedTypes.push(type);\n }\n }\n\n flatten(errType);\n\n return Type.Union(flattenedTypes);\n}\n","import { Static, Type } from '@sinclair/typebox';\nimport { Client } from './client';\nimport { Readable } from './streams';\nimport { BaseErrorSchemaType } from './errors';\n\n/**\n * AnyResultSchema is a schema to validate any result.\n */\nexport const AnyResultSchema = Type.Union([\n Type.Object({\n ok: Type.Literal(false),\n payload: Type.Object({\n code: Type.String(),\n message: Type.String(),\n extras: Type.Optional(Type.Unknown()),\n }),\n }),\n\n Type.Object({\n ok: Type.Literal(true),\n payload: Type.Unknown(),\n }),\n]);\n\nexport interface OkResult<T> {\n ok: true;\n payload: T;\n}\nexport interface ErrResult<Err extends Static<BaseErrorSchemaType>> {\n ok: false;\n payload: Err;\n}\nexport type Result<T, Err extends Static<BaseErrorSchemaType>> =\n | OkResult<T>\n | ErrResult<Err>;\n\nexport function Ok<const T extends Array<unknown>>(p: T): OkResult<T>;\nexport function Ok<const T extends ReadonlyArray<unknown>>(p: T): OkResult<T>;\nexport function Ok<const T>(payload: T): OkResult<T>;\nexport function Ok<const T>(payload: T): OkResult<T> {\n return {\n ok: true,\n payload,\n };\n}\n\nexport function Err<const Err extends Static<BaseErrorSchemaType>>(\n error: Err,\n): ErrResult<Err> {\n return {\n ok: false,\n payload: error,\n };\n}\n\n/**\n * Refine a {@link Result} type to its returned payload.\n */\nexport type ResultUnwrapOk<R> = R extends Result<infer T, infer __E>\n ? T\n : never;\n\n/**\n * Unwrap a {@link Result} type and return the payload if successful,\n * otherwise throws an error.\n * @param result - The result to unwrap.\n * @throws Will throw an error if the result is not ok.\n */\nexport function unwrapOrThrow<T, Err extends Static<BaseErrorSchemaType>>(\n result: Result<T, Err>,\n): T {\n if (result.ok) {\n return result.payload;\n }\n\n throw new Error(\n `Cannot non-ok result, got: ${result.payload.code} - ${result.payload.message}`,\n );\n}\n\n/**\n * Refine a {@link Result} type to its error payload.\n */\nexport type ResultUnwrapErr<R> = R extends Result<infer __T, infer Err>\n ? Err\n : never;\n\n/**\n * Retrieve the response type for a procedure, represented as a {@link Result}\n * type.\n * Example:\n * ```\n * type Message = ResponseData<typeof client, 'serviceName', 'procedureName'>\n * ```\n */\nexport type ResponseData<\n RiverClient,\n ServiceName extends keyof RiverClient,\n ProcedureName extends keyof RiverClient[ServiceName],\n Procedure = RiverClient[ServiceName][ProcedureName],\n Fn extends (...args: never) => unknown = (...args: never) => unknown,\n> = RiverClient extends Client<infer __ServiceSchemaMap>\n ? Procedure extends object\n ? Procedure extends object & { rpc: infer RpcFn extends Fn }\n ? Awaited<ReturnType<RpcFn>>\n : Procedure extends object & { upload: infer UploadFn extends Fn }\n ? ReturnType<UploadFn> extends {\n finalize: (...args: never) => Promise<infer UploadOutputMessage>;\n }\n ? UploadOutputMessage\n : never\n : Procedure extends object & { stream: infer StreamFn extends Fn }\n ? ReturnType<StreamFn> extends {\n resReadable: Readable<\n infer StreamOutputMessage,\n Static<BaseErrorSchemaType>\n >;\n }\n ? StreamOutputMessage\n : never\n : Procedure extends object & {\n subscribe: infer SubscriptionFn extends Fn;\n }\n ? Awaited<ReturnType<SubscriptionFn>> extends {\n resReadable: Readable<\n infer SubscriptionOutputMessage,\n Static<BaseErrorSchemaType>\n >;\n }\n ? SubscriptionOutputMessage\n : never\n : never\n : never\n : never;\n","import { Static } from '@sinclair/typebox';\nimport { Err, Result } from './result';\nimport { BaseErrorSchemaType } from './errors';\n\nexport const ReadableBrokenError: Static<BaseErrorSchemaType> = {\n code: 'READABLE_BROKEN',\n message: 'Readable was broken before it is fully consumed',\n} as const;\n\n/**\n * Similar to {@link Result} but with an extra error to handle cases where {@link Readable.break} is called\n */\nexport type ReadableResult<T, E extends Static<BaseErrorSchemaType>> = Result<\n T,\n E | typeof ReadableBrokenError\n>;\n\n/**\n * A simple {@link AsyncIterator} used in {@link Readable}\n * that doesn't have a the extra \"return\" and \"throw\" methods, and\n * the doesn't have a \"done value\" (TReturn).\n */\nexport interface ReadableIterator<T, E extends Static<BaseErrorSchemaType>> {\n next(): Promise<\n | {\n done: false;\n value: ReadableResult<T, E>;\n }\n | {\n done: true;\n value: undefined;\n }\n >;\n}\n\n/**\n * A {@link Readable} is an abstraction from which data is consumed from {@link Writable} source.\n *\n * - On the server the argument passed the procedure handler for `upload` and `stream` implements a {@link Readable} interface\n * so you can read client's request data.\n * - On the client the returned value of `subscription` or `stream` invocation implements a {@link Readable} interface\n * so you can read server's response data.\n *\n * A {@link Readable} can only have one consumer (iterator or {@link collect}) for the {@link Readable}'s\n * lifetime, in essense, reading from a {@link Readable} locks it forever.\n */\nexport interface Readable<T, E extends Static<BaseErrorSchemaType>> {\n /**\n * {@link Readable} implements AsyncIterator API and can be consumed via\n * for-await-of loops. Iteration locks the Readable. Exiting the loop\n * will **not** release the lock and it'll be equivalent of calling\n * {@link break}.\n */\n [Symbol.asyncIterator](): ReadableIterator<T, E>;\n /**\n * {@link collect} locks the {@link Readable} and returns a promise that resolves\n * with an array of the content when the {@link Readable} is fully done. This could\n * be due to the {@link Writable} end of the pipe closing cleanly, the procedure invocation\n * is cancelled, or {@link break} is called.\n */\n collect(): Promise<Array<ReadableResult<T, E>>>;\n /**\n * {@link break} locks the {@link Readable} and discards any existing or future incoming data.\n *\n * If there is an existing reader waiting for the next value, {@link break} causes it to\n * resolve with a {@link ReadableBrokenError} error.\n */\n break(): undefined;\n /**\n * {@link isReadable} returns true if it's safe to read from the {@link Readable}, either\n * via iteration or {@link collect}. It returns false if the {@link Readable} is locked\n * by a consumer (iterator or {@link collect}) or readable was broken via {@link break}.\n */\n isReadable(): boolean;\n}\n\n/**\n * A {@link Writeable} is a an abstraction for a {@link Readable} destination to which data is written to.\n *\n * - On the server the argument passed the procedure handler for `subscription` and `stream` implements a {@link Writeable}\n * so you can write server's response data.\n * - On the client the returned value of `upload` or `stream` invocation implements a {@link Writeable}\n * so you can write client's request data.\n *\n * Once closed, a {@link Writeable} can't be re-opened.` `\n */\nexport interface Writable<T> {\n /**\n * {@link write} writes a value to the pipe. An error is thrown if writing to a closed {@link Writable}.\n */\n write(value: T): undefined;\n /**\n * {@link close} signals the closure of the {@link Writeable}, informing the {@link Readable} end that\n * all data has been transmitted and we've cleanly closed.\n *\n * Calling {@link close} multiple times is a no-op.\n */\n close(): undefined;\n /**\n * {@link isWritable} returns true if it's safe to call {@link write}, which\n * means that the {@link Writable} hasn't been closed due to {@link close} being called\n * on this {@link Writable} or the procedure invocation ending for any reason.\n */\n isWritable(): boolean;\n}\n\n/**\n * @internal\n *\n * @see {@link createPromiseWithResolvers}\n */\ninterface PromiseWithResolvers<T> {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason: unknown) => void;\n}\n\n/**\n * @internal\n *\n * Same as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers\n * but we support versions where it doesn't exist\n */\nfunction createPromiseWithResolvers<T>(): PromiseWithResolvers<T> {\n let resolve: (value: T) => void;\n let reject: (reason: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return {\n promise,\n // @ts-expect-error promise callbacks are sync\n resolve,\n // @ts-expect-error promise callbacks are sync\n reject,\n };\n}\n\n/**\n * @internal\n *\n * Internal implementation of a {@link Readable}.\n * This won't be exposed as an interface to river\n * consumers directly.\n */\nexport class ReadableImpl<T, E extends Static<BaseErrorSchemaType>>\n implements Readable<T, E>\n{\n /**\n * Whether the {@link Readable} is closed.\n *\n * Closed {@link Readable}s are done receiving values, but that doesn't affect\n * any other aspect of the {@link Readable} such as it's consumability.\n */\n private closed = false;\n /**\n * Whether the {@link Readable} is locked.\n *\n * @see {@link Readable}'s typedoc to understand locking\n */\n private locked = false;\n /**\n * Whether {@link break} was called.\n *\n * @see {@link break} for more information\n */\n private broken = false;\n /**\n * This flag allows us to avoid emitting a {@link ReadableBrokenError} after {@link break} was called\n * in cases where the {@link queue} is fully consumed and {@link ReadableImpl} is {@link closed}. This is just an\n * ergonomic feature to avoid emitting an error in our iteration when we don't have to.\n */\n private brokenWithValuesLeftToRead = false;\n /**\n * A list of values that have been pushed to the {@link ReadableImpl} but not yet emitted to the user.\n */\n private queue: Array<ReadableResult<T, E>> = [];\n /**\n * Used by methods in the class to signal to the iterator that it\n * should check for the next value.\n */\n private next: PromiseWithResolvers<void> | null = null;\n\n public [Symbol.asyncIterator]() {\n if (this.locked) {\n throw new TypeError('Readable is already locked');\n }\n\n this.locked = true;\n\n /**\n * First iteration with {@link break} signals an error, the following one signals end of iteration.\n * This variable is used to signal the end of iteration.\n */\n let didSignalBreak = false;\n\n return {\n next: async () => {\n if (didSignalBreak) {\n return {\n done: true,\n value: undefined,\n } as const;\n }\n\n /**\n * In a normal iteration case the while loop can be structured as a couple of if statements,\n * in other words the loop will run at most a couple of times:\n * - it will run 0 times if we have something in the queue to consume\n * - it will run 1 time if we have nothing in the queue and then get something in the queue\n * - it will run 2 times if we have nothing in the queue and then the readable closes or breaks\n *\n * However, in a degenerate case where something has the handle to the iterator and is calling `next`\n * eagerly multiple times this loop will come in handy by queuing them up and looping as needed.\n */\n while (this.queue.length === 0) {\n if (this.closed && !this.brokenWithValuesLeftToRead) {\n return {\n done: true,\n value: undefined,\n } as const;\n }\n\n if (this.broken) {\n didSignalBreak = true;\n\n return {\n done: false,\n value: Err(ReadableBrokenError),\n } as const;\n }\n\n if (!this.next) {\n this.next = createPromiseWithResolvers();\n }\n\n await this.next.promise;\n this.next = null;\n }\n\n // Unfortunately we have to use non-null assertion here, because T can be undefined\n // we already check for array length above anyway\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const value = this.queue.shift()!;\n\n return { done: false, value } as const;\n },\n return: () => {\n this.break();\n\n return { done: true, value: undefined } as const;\n },\n };\n }\n\n public async collect(): Promise<Array<ReadableResult<T, E>>> {\n const array: Array<ReadableResult<T, E>> = [];\n for await (const value of this) {\n array.push(value);\n }\n\n return array;\n }\n\n public break(): undefined {\n if (this.broken) {\n return;\n }\n\n this.locked = true;\n this.broken = true;\n this.brokenWithValuesLeftToRead = this.queue.length > 0;\n this.queue.length = 0;\n\n // if we have any iterators waiting for the next value,\n this.next?.resolve();\n }\n\n public isReadable(): boolean {\n return !this.locked && !this.broken;\n }\n\n /**\n * @internal meant for use within river, not exposed as a public API\n *\n * Pushes a value to be read.\n */\n public _pushValue(value: Result<T, E>): undefined {\n if (this.broken) {\n return;\n }\n\n if (this.closed) {\n throw new Error('Cannot push to closed Readable');\n }\n\n this.queue.push(value);\n this.next?.resolve();\n }\n\n /**\n * @internal meant for use within river, not exposed as a public API\n *\n * Triggers the close of the {@link Readable}. Make sure to push all remaining\n * values before calling this method.\n */\n public _triggerClose(): undefined {\n if (this.closed) {\n throw new Error('Unexpected closing multiple times');\n }\n\n this.closed = true;\n this.next?.resolve();\n }\n\n /**\n * @internal meant for use within river, not exposed as a public API\n */\n public _hasValuesInQueue(): boolean {\n return this.queue.length > 0;\n }\n\n /**\n * @internal meant for use within river, not exposed as a public API\n */\n public isClosed(): boolean {\n return this.closed;\n }\n}\n\n/**\n * Internal implementation of a {@link Writable}.\n * This won't be exposed as an interface to river\n * consumers directly.\n */\nexport class WritableImpl<T> implements Writable<T> {\n /**\n * Passed via constructor to pass on calls to {@link write}\n */\n private writeCb: (value: T) => void;\n\n /**\n * Passed via constructor to pass on calls to {@link close}\n */\n private closeCb: () => void;\n /**\n * Whether {@link close} was called, and {@link Writable} is not writable anymore.\n */\n private closed = false;\n\n constructor(callbacks: { writeCb: (value: T) => void; closeCb: () => void }) {\n this.writeCb = callbacks.writeCb;\n this.closeCb = callbacks.closeCb;\n }\n\n public write(value: T): undefined {\n if (this.closed) {\n throw new Error('Cannot write to closed Writable');\n }\n\n this.writeCb(value);\n }\n\n public isWritable(): boolean {\n return !this.closed;\n }\n\n public close(): undefined {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.writeCb = () => undefined;\n this.closeCb();\n this.closeCb = () => undefined;\n }\n\n /**\n * @internal meant for use within river, not exposed as a public API\n */\n public isClosed(): boolean {\n return this.closed;\n }\n}\n"],"mappings":"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","names":["Type"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Connection, T as Transport, n as ClientTransportOptions, L as LeakyBucketRateLimit,
|
|
2
|
-
import { c as TransportClientId,
|
|
1
|
+
import { C as Connection, T as Transport, n as ClientTransportOptions, L as LeakyBucketRateLimit, q as ClientHandshakeOptions, r as ClientSession, b as ProvidedClientTransportOptions, e as SessionNoConnection, f as SessionConnecting, g as SessionHandshaking, h as SessionConnected, s as SessionBackingOff } from './context-69f37ac1.js';
|
|
2
|
+
import { c as TransportClientId, b as OpaqueTransportMessage } from './message-57bb8187.js';
|
|
3
3
|
|
|
4
4
|
declare abstract class ClientTransport<ConnType extends Connection> extends Transport<ConnType> {
|
|
5
5
|
/**
|
|
@@ -29,8 +29,7 @@ declare abstract class ClientTransport<ConnType extends Connection> extends Tran
|
|
|
29
29
|
*/
|
|
30
30
|
protected abstract createNewOutgoingConnection(to: TransportClientId): Promise<ConnType>;
|
|
31
31
|
private tryReconnecting;
|
|
32
|
-
|
|
33
|
-
private createUnconnectedSession;
|
|
32
|
+
createUnconnectedSession(to: string): SessionNoConnection;
|
|
34
33
|
protected onConnectingFailed(session: SessionConnecting<ConnType>): SessionNoConnection;
|
|
35
34
|
protected onConnClosed(session: SessionHandshaking<ConnType> | SessionConnected<ConnType>): SessionNoConnection;
|
|
36
35
|
protected onConnectionEstablished(session: SessionConnecting<ConnType>, conn: ConnType): SessionHandshaking<ConnType>;
|
package/dist/codec/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../codec/index.ts","../../codec/binary.ts","../../codec/json.ts"],"sourcesContent":["export { BinaryCodec } from './binary';\nexport { NaiveJsonCodec } from './json';\nexport type { Codec } from './types';\n","import { decode, encode } from '@msgpack/msgpack';\nimport { Codec } from './types';\n\n/**\n * Binary codec, uses [msgpack](https://www.npmjs.com/package/@msgpack/msgpack) under the hood\n * @type {Codec}\n */\nexport const BinaryCodec: Codec = {\n toBuffer(obj) {\n return encode(obj, { ignoreUndefined: true });\n },\n fromBuffer: (buff: Uint8Array) => {\n try {\n const res = decode(buff);\n if (typeof res !== 'object') {\n return null;\n }\n\n return res;\n } catch {\n return null;\n }\n },\n};\n","import { Codec } from './types';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n// Convert Uint8Array to base64\nfunction uint8ArrayToBase64(uint8Array: Uint8Array) {\n let binary = '';\n uint8Array.forEach((byte) => {\n binary += String.fromCharCode(byte);\n });\n return btoa(binary);\n}\n\n// Convert base64 to Uint8Array\nfunction base64ToUint8Array(base64: string) {\n const binaryString = atob(base64);\n const uint8Array = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n uint8Array[i] = binaryString.charCodeAt(i);\n }\n return uint8Array;\n}\n\ninterface Base64EncodedValue {\n $t: string;\n}\n\n/**\n * Naive JSON codec implementation using JSON.stringify and JSON.parse.\n * @type {Codec}\n */\nexport const NaiveJsonCodec: Codec = {\n toBuffer: (obj: object) => {\n return encoder.encode(\n JSON.stringify(obj, function replacer<\n T extends object,\n >(this: T, key: keyof T) {\n const val = this[key];\n if (val instanceof Uint8Array) {\n return { $t: uint8ArrayToBase64(val) } satisfies Base64EncodedValue;\n } else {\n return val;\n }\n }),\n );\n },\n fromBuffer: (buff: Uint8Array) => {\n try {\n const parsed = JSON.parse(\n decoder.decode(buff),\n function reviver(_key, val: unknown) {\n if ((val as Base64EncodedValue | undefined)?.$t) {\n return base64ToUint8Array((val as Base64EncodedValue).$t);\n } else {\n return val;\n }\n },\n ) as unknown;\n\n if (typeof parsed === 'object') return parsed;\n return null;\n } catch {\n return null;\n }\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAA+B;AAOxB,IAAM,cAAqB;AAAA,EAChC,SAAS,KAAK;AACZ,eAAO,uBAAO,KAAK,EAAE,iBAAiB,KAAK,CAAC;AAAA,EAC9C;AAAA,EACA,YAAY,CAAC,SAAqB;AAChC,QAAI;AACF,YAAM,UAAM,uBAAO,IAAI;AACvB,UAAI,OAAO,QAAQ,UAAU;AAC3B,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACrBA,IAAM,UAAU,IAAI,YAAY;AAChC,IAAM,UAAU,IAAI,YAAY;AAGhC,SAAS,mBAAmB,YAAwB;AAClD,MAAI,SAAS;AACb,aAAW,QAAQ,CAAC,SAAS;AAC3B,cAAU,OAAO,aAAa,IAAI;AAAA,EACpC,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../codec/index.ts","../../codec/binary.ts","../../codec/json.ts"],"sourcesContent":["export { BinaryCodec } from './binary';\nexport { NaiveJsonCodec } from './json';\nexport type { Codec } from './types';\n","import { decode, encode } from '@msgpack/msgpack';\nimport { Codec } from './types';\n\n/**\n * Binary codec, uses [msgpack](https://www.npmjs.com/package/@msgpack/msgpack) under the hood\n * @type {Codec}\n */\nexport const BinaryCodec: Codec = {\n toBuffer(obj) {\n return encode(obj, { ignoreUndefined: true });\n },\n fromBuffer: (buff: Uint8Array) => {\n try {\n const res = decode(buff);\n if (typeof res !== 'object') {\n return null;\n }\n\n return res;\n } catch {\n return null;\n }\n },\n};\n","import { Codec } from './types';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n// Convert Uint8Array to base64\nfunction uint8ArrayToBase64(uint8Array: Uint8Array) {\n let binary = '';\n uint8Array.forEach((byte) => {\n binary += String.fromCharCode(byte);\n });\n\n return btoa(binary);\n}\n\n// Convert base64 to Uint8Array\nfunction base64ToUint8Array(base64: string) {\n const binaryString = atob(base64);\n const uint8Array = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n uint8Array[i] = binaryString.charCodeAt(i);\n }\n\n return uint8Array;\n}\n\ninterface Base64EncodedValue {\n $t: string;\n}\n\n/**\n * Naive JSON codec implementation using JSON.stringify and JSON.parse.\n * @type {Codec}\n */\nexport const NaiveJsonCodec: Codec = {\n toBuffer: (obj: object) => {\n return encoder.encode(\n JSON.stringify(obj, function replacer<\n T extends object,\n >(this: T, key: keyof T) {\n const val = this[key];\n if (val instanceof Uint8Array) {\n return { $t: uint8ArrayToBase64(val) } satisfies Base64EncodedValue;\n } else {\n return val;\n }\n }),\n );\n },\n fromBuffer: (buff: Uint8Array) => {\n try {\n const parsed = JSON.parse(\n decoder.decode(buff),\n function reviver(_key, val: unknown) {\n if ((val as Base64EncodedValue | undefined)?.$t) {\n return base64ToUint8Array((val as Base64EncodedValue).$t);\n } else {\n return val;\n }\n },\n ) as unknown;\n\n if (typeof parsed === 'object') return parsed;\n\n return null;\n } catch {\n return null;\n }\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAA+B;AAOxB,IAAM,cAAqB;AAAA,EAChC,SAAS,KAAK;AACZ,eAAO,uBAAO,KAAK,EAAE,iBAAiB,KAAK,CAAC;AAAA,EAC9C;AAAA,EACA,YAAY,CAAC,SAAqB;AAChC,QAAI;AACF,YAAM,UAAM,uBAAO,IAAI;AACvB,UAAI,OAAO,QAAQ,UAAU;AAC3B,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACrBA,IAAM,UAAU,IAAI,YAAY;AAChC,IAAM,UAAU,IAAI,YAAY;AAGhC,SAAS,mBAAmB,YAAwB;AAClD,MAAI,SAAS;AACb,aAAW,QAAQ,CAAC,SAAS;AAC3B,cAAU,OAAO,aAAa,IAAI;AAAA,EACpC,CAAC;AAED,SAAO,KAAK,MAAM;AACpB;AAGA,SAAS,mBAAmB,QAAgB;AAC1C,QAAM,eAAe,KAAK,MAAM;AAChC,QAAM,aAAa,IAAI,WAAW,aAAa,MAAM;AACrD,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,eAAW,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,EAC3C;AAEA,SAAO;AACT;AAUO,IAAM,iBAAwB;AAAA,EACnC,UAAU,CAAC,QAAgB;AACzB,WAAO,QAAQ;AAAA,MACb,KAAK,UAAU,KAAK,SAAS,SAElB,KAAc;AACvB,cAAM,MAAM,KAAK,GAAG;AACpB,YAAI,eAAe,YAAY;AAC7B,iBAAO,EAAE,IAAI,mBAAmB,GAAG,EAAE;AAAA,QACvC,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA,YAAY,CAAC,SAAqB;AAChC,QAAI;AACF,YAAM,SAAS,KAAK;AAAA,QAClB,QAAQ,OAAO,IAAI;AAAA,QACnB,SAAS,QAAQ,MAAM,KAAc;AACnC,cAAK,KAAwC,IAAI;AAC/C,mBAAO,mBAAoB,IAA2B,EAAE;AAAA,UAC1D,OAAO;AACL,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAEA,UAAI,OAAO,WAAW;AAAU,eAAO;AAEvC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
|
package/dist/codec/index.js
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { e as ProtocolVersion, b as OpaqueTransportMessage, f as Tags } from './message-57bb8187.js';
|
|
2
|
+
import * as _sinclair_typebox_errors from '@sinclair/typebox/errors';
|
|
3
|
+
import { C as Connection } from './context-69f37ac1.js';
|
|
4
|
+
import { W as WsLike } from './wslike-e0b32dd5.js';
|
|
5
|
+
|
|
6
|
+
interface ConnectionInfoExtras {
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
declare class WebSocketConnection extends Connection {
|
|
10
|
+
ws: WsLike;
|
|
11
|
+
extras?: ConnectionInfoExtras;
|
|
12
|
+
get loggingMetadata(): Partial<{
|
|
13
|
+
protocolVersion: ProtocolVersion;
|
|
14
|
+
clientId: string;
|
|
15
|
+
connectedTo: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
connId: string;
|
|
18
|
+
transportMessage: Partial<OpaqueTransportMessage>;
|
|
19
|
+
validationErrors: _sinclair_typebox_errors.ValueError[];
|
|
20
|
+
tags: Tags[];
|
|
21
|
+
telemetry: {
|
|
22
|
+
traceId: string;
|
|
23
|
+
spanId: string;
|
|
24
|
+
};
|
|
25
|
+
extras: unknown;
|
|
26
|
+
}>;
|
|
27
|
+
constructor(ws: WsLike, extras?: ConnectionInfoExtras);
|
|
28
|
+
send(payload: Uint8Array): boolean;
|
|
29
|
+
close(): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { WebSocketConnection as W };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as TelemetryInfo, M as MessageMetadata, c as TransportClientId, L as Logger, b as OpaqueTransportMessage, e as ProtocolVersion, P as PartialTransportMessage, a as TransportMessage, f as Tags, H as HandshakeErrorResponseCodes, h as LogFn, j as LoggingLevel, k as HandshakeErrorCustomHandlerFatalResponseCodes } from './message-57bb8187.js';
|
|
2
2
|
import { Static, TSchema } from '@sinclair/typebox';
|
|
3
3
|
import * as _sinclair_typebox_errors from '@sinclair/typebox/errors';
|
|
4
4
|
import { C as Codec } from './types-3e5768ec.js';
|
|
@@ -130,13 +130,13 @@ interface IdentifiedSessionProps extends CommonSessionProps {
|
|
|
130
130
|
ack: number;
|
|
131
131
|
sendBuffer: Array<OpaqueTransportMessage>;
|
|
132
132
|
telemetry: TelemetryInfo;
|
|
133
|
-
protocolVersion:
|
|
133
|
+
protocolVersion: ProtocolVersion;
|
|
134
134
|
}
|
|
135
135
|
declare abstract class IdentifiedSession extends CommonSession {
|
|
136
136
|
readonly id: SessionId;
|
|
137
137
|
readonly telemetry: TelemetryInfo;
|
|
138
138
|
readonly to: TransportClientId;
|
|
139
|
-
readonly protocolVersion:
|
|
139
|
+
readonly protocolVersion: ProtocolVersion;
|
|
140
140
|
/**
|
|
141
141
|
* Index of the message we will send next (excluding handshake)
|
|
142
142
|
*/
|
|
@@ -214,7 +214,7 @@ declare class SessionHandshaking<ConnType extends Connection> extends Identified
|
|
|
214
214
|
handshakeTimeout?: ReturnType<typeof setTimeout>;
|
|
215
215
|
constructor(props: SessionHandshakingProps<ConnType>);
|
|
216
216
|
get loggingMetadata(): {
|
|
217
|
-
protocolVersion?:
|
|
217
|
+
protocolVersion?: ProtocolVersion | undefined;
|
|
218
218
|
clientId?: string | undefined;
|
|
219
219
|
connectedTo?: string | undefined;
|
|
220
220
|
sessionId?: string | undefined;
|
|
@@ -226,6 +226,7 @@ declare class SessionHandshaking<ConnType extends Connection> extends Identified
|
|
|
226
226
|
traceId: string;
|
|
227
227
|
spanId: string;
|
|
228
228
|
} | undefined;
|
|
229
|
+
extras?: unknown;
|
|
229
230
|
};
|
|
230
231
|
onHandshakeData: (msg: Uint8Array) => void;
|
|
231
232
|
sendHandshake(msg: TransportMessage): boolean;
|
|
@@ -254,7 +255,7 @@ declare class SessionConnected<ConnType extends Connection> extends IdentifiedSe
|
|
|
254
255
|
send(msg: PartialTransportMessage): string;
|
|
255
256
|
constructor(props: SessionConnectedProps<ConnType>);
|
|
256
257
|
get loggingMetadata(): {
|
|
257
|
-
protocolVersion?:
|
|
258
|
+
protocolVersion?: ProtocolVersion | undefined;
|
|
258
259
|
clientId?: string | undefined;
|
|
259
260
|
connectedTo?: string | undefined;
|
|
260
261
|
sessionId?: string | undefined;
|
|
@@ -266,9 +267,11 @@ declare class SessionConnected<ConnType extends Connection> extends IdentifiedSe
|
|
|
266
267
|
traceId: string;
|
|
267
268
|
spanId: string;
|
|
268
269
|
} | undefined;
|
|
270
|
+
extras?: unknown;
|
|
269
271
|
};
|
|
270
272
|
startActiveHeartbeat(): void;
|
|
271
273
|
private sendHeartbeat;
|
|
274
|
+
closeConnection(): void;
|
|
272
275
|
onMessageData: (msg: Uint8Array) => void;
|
|
273
276
|
_handleStateExit(): void;
|
|
274
277
|
_handleClose(): void;
|
|
@@ -298,6 +301,7 @@ declare const ProtocolError: {
|
|
|
298
301
|
readonly RetriesExceeded: "conn_retry_exceeded";
|
|
299
302
|
readonly HandshakeFailed: "handshake_failed";
|
|
300
303
|
readonly MessageOrderingViolated: "message_ordering_violated";
|
|
304
|
+
readonly InvalidMessage: "invalid_message";
|
|
301
305
|
};
|
|
302
306
|
type ProtocolErrorType = (typeof ProtocolError)[keyof typeof ProtocolError];
|
|
303
307
|
interface EventMap {
|
|
@@ -405,6 +409,10 @@ type ProvidedServerTransportOptions = Partial<ServerTransportOptions>;
|
|
|
405
409
|
* @property {'closed'} closed - The transport is permanently closed and cannot be reopened.
|
|
406
410
|
*/
|
|
407
411
|
type TransportStatus = 'open' | 'closed';
|
|
412
|
+
interface DeleteSessionOptions {
|
|
413
|
+
unhealthy: boolean;
|
|
414
|
+
}
|
|
415
|
+
type SessionBoundSendFn = (msg: PartialTransportMessage) => string | undefined;
|
|
408
416
|
/**
|
|
409
417
|
* Transports manage the lifecycle (creation/deletion) of sessions
|
|
410
418
|
*
|
|
@@ -455,9 +463,9 @@ declare abstract class Transport<ConnType extends Connection> {
|
|
|
455
463
|
/**
|
|
456
464
|
* Called when a message is received by this transport.
|
|
457
465
|
* You generally shouldn't need to override this in downstream transport implementations.
|
|
458
|
-
* @param
|
|
466
|
+
* @param message The received message.
|
|
459
467
|
*/
|
|
460
|
-
protected handleMsg(
|
|
468
|
+
protected handleMsg(message: OpaqueTransportMessage): void;
|
|
461
469
|
/**
|
|
462
470
|
* Adds a listener to this transport.
|
|
463
471
|
* @param the type of event to listen for
|
|
@@ -470,13 +478,6 @@ declare abstract class Transport<ConnType extends Connection> {
|
|
|
470
478
|
* @param handler The message handler to remove.
|
|
471
479
|
*/
|
|
472
480
|
removeEventListener<K extends EventTypes, T extends EventHandler<K>>(type: K, handler: T): void;
|
|
473
|
-
/**
|
|
474
|
-
* Sends a message over this transport, delegating to the appropriate connection to actually
|
|
475
|
-
* send the message.
|
|
476
|
-
* @param msg The message to send.
|
|
477
|
-
* @returns The ID of the sent message or undefined if it wasn't sent
|
|
478
|
-
*/
|
|
479
|
-
abstract send(to: TransportClientId, msg: PartialTransportMessage): string;
|
|
480
481
|
protected protocolError(message: EventMap['protocolError']): void;
|
|
481
482
|
/**
|
|
482
483
|
* Default close implementation for transports. You should override this in the downstream
|
|
@@ -485,11 +486,21 @@ declare abstract class Transport<ConnType extends Connection> {
|
|
|
485
486
|
*/
|
|
486
487
|
close(): void;
|
|
487
488
|
getStatus(): TransportStatus;
|
|
488
|
-
protected
|
|
489
|
-
protected
|
|
489
|
+
protected createSession<S extends Session<ConnType>>(session: S): void;
|
|
490
|
+
protected updateSession<S extends Session<ConnType>>(session: S): void;
|
|
491
|
+
protected deleteSession(session: Session<ConnType>, options?: DeleteSessionOptions): void;
|
|
490
492
|
protected onSessionGracePeriodElapsed(session: Session<ConnType>): void;
|
|
491
493
|
protected onConnectingFailed(session: SessionConnecting<ConnType>): SessionNoConnection;
|
|
492
494
|
protected onConnClosed(session: SessionHandshaking<ConnType> | SessionConnected<ConnType>): SessionNoConnection;
|
|
495
|
+
/**
|
|
496
|
+
* Gets a send closure scoped to a specific session. Sending using the returned
|
|
497
|
+
* closure after the session has transitioned to a different state will be a noop.
|
|
498
|
+
*
|
|
499
|
+
* Session objects themselves can become stale as they transition between
|
|
500
|
+
* states. As stale sessions cannot be used again (and will throw), holding
|
|
501
|
+
* onto a session object is not recommended.
|
|
502
|
+
*/
|
|
503
|
+
getSessionBoundSendFn(to: TransportClientId, sessionId: SessionId): SessionBoundSendFn;
|
|
493
504
|
}
|
|
494
505
|
|
|
495
506
|
type ConstructHandshake<T extends TSchema> = () => Static<T> | Promise<Static<T>>;
|
|
@@ -587,40 +598,34 @@ type ProcedureHandlerContext<State> = ServiceContext & {
|
|
|
587
598
|
*/
|
|
588
599
|
from: TransportClientId;
|
|
589
600
|
/**
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* Important to note that this controller is owned by the handler, if you
|
|
594
|
-
* want to listen to aborts coming from the client, you should use the
|
|
595
|
-
* {@link clientAbortSignal}.
|
|
601
|
+
* This is used to cancel the procedure call from the handler and notify the client that the
|
|
602
|
+
* call was cancelled.
|
|
596
603
|
*
|
|
597
|
-
*
|
|
604
|
+
* Cancelling is not the same as closing procedure calls gracefully, please refer to
|
|
598
605
|
* the river documentation to understand the difference between the two concepts.
|
|
599
606
|
*/
|
|
600
|
-
|
|
607
|
+
cancel: () => void;
|
|
601
608
|
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
609
|
+
* This signal is a standard [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
|
|
610
|
+
* triggered when the procedure invocation is done. This signal tracks the invocation/request finishing
|
|
611
|
+
* for _any_ reason, for example:
|
|
612
|
+
* - client explicit cancellation
|
|
613
|
+
* - procedure handler explicit cancellation via {@link cancel}
|
|
614
|
+
* - client session disconnect
|
|
615
|
+
* - server cancellation due to client invalid payload
|
|
616
|
+
* - invocation finishes cleanly, this depends on the type of the procedure (i.e. rpc handler return, or in a stream after the client-side has closed the request writable and the server-side has closed the response writable)
|
|
605
617
|
*
|
|
606
|
-
*
|
|
607
|
-
* notified of aborts as part of the stream, but you may still want to use
|
|
608
|
-
* this signal as it is triggered immediately after an abort comes in,
|
|
609
|
-
* in readStreams some data may be buffered before the abort result shows up.
|
|
618
|
+
* You can use this to pass it on to asynchronous operations (such as fetch).
|
|
610
619
|
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
620
|
+
* You may also want to explicitly register callbacks on the
|
|
621
|
+
* ['abort' event](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/abort_event)
|
|
622
|
+
* as a way to cleanup after the request is finished.
|
|
613
623
|
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
|
|
617
|
-
clientAbortSignal: AbortSignal;
|
|
618
|
-
/**
|
|
619
|
-
* Lets you add a function that will run when the request is done, this can be
|
|
620
|
-
* due to an abort (from either side), error, or success. If the callback is
|
|
621
|
-
* added after the stream ended, it will run immediately.
|
|
624
|
+
* Note that (per standard AbortSignals) callbacks registered _after_ the procedure invocation
|
|
625
|
+
* is done are not triggered. In such cases, you can check the "aborted" property and cleanup
|
|
626
|
+
* immediately if needed.
|
|
622
627
|
*/
|
|
623
|
-
|
|
628
|
+
signal: AbortSignal;
|
|
624
629
|
};
|
|
625
630
|
|
|
626
|
-
export {
|
|
631
|
+
export { ServerTransportOptions as A, ServerSession as B, Connection as C, DeleteSessionOptions as D, EventMap as E, LeakyBucketRateLimit as L, ProvidedTransportOptions as P, Session as S, Transport as T, TransportStatus as a, ProvidedClientTransportOptions as b, ProvidedServerTransportOptions as c, SessionState as d, SessionNoConnection as e, SessionConnecting as f, SessionHandshaking as g, SessionConnected as h, EventTypes as i, EventHandler as j, ProtocolError as k, ProtocolErrorType as l, SessionOptions as m, ClientTransportOptions as n, SessionBoundSendFn as o, ServiceContext as p, ClientHandshakeOptions as q, ClientSession as r, SessionBackingOff as s, ParsedMetadata as t, ServerHandshakeOptions as u, ProcedureHandlerContext as v, createClientHandshakeOptions as w, createServerHandshakeOptions as x, CommonSession as y, CommonSessionProps as z };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../logging/index.ts","../../logging/log.ts"],"sourcesContent":["export { stringLogger, coloredStringLogger, jsonLogger } from './log';\nexport type { Logger, LogFn, MessageMetadata } from './log';\n","import { ValueError } from '@sinclair/typebox/value';\nimport { OpaqueTransportMessage } from '../transport/message';\n\nconst LoggingLevels = {\n debug: -1,\n info: 0,\n warn: 1,\n error: 2,\n} as const;\nexport type LoggingLevel = keyof typeof LoggingLevels;\n\nexport type LogFn = (\n msg: string,\n ctx?: MessageMetadata,\n level?: LoggingLevel,\n) => void;\nexport type Logger = {\n [key in LoggingLevel]: (msg: string, metadata?: MessageMetadata) => void;\n};\n\nexport type Tags =\n | 'invariant-violation'\n | 'state-transition'\n | 'invalid-request';\n\nconst cleanedLogFn = (log: LogFn) => {\n return (msg: string, metadata?: MessageMetadata) => {\n // skip cloning object if metadata has no transportMessage\n if (!metadata?.transportMessage) {\n log(msg, metadata);\n return;\n }\n\n // clone metadata and clean transportMessage\n const { payload, ...rest } = metadata.transportMessage;\n metadata.transportMessage = rest;\n log(msg, metadata);\n };\n};\n\nexport type MessageMetadata = Partial<{\n protocolVersion:
|
|
1
|
+
{"version":3,"sources":["../../logging/index.ts","../../logging/log.ts"],"sourcesContent":["export { stringLogger, coloredStringLogger, jsonLogger } from './log';\nexport type { Logger, LogFn, MessageMetadata } from './log';\n","import { ValueError } from '@sinclair/typebox/value';\nimport { OpaqueTransportMessage, ProtocolVersion } from '../transport/message';\n\nconst LoggingLevels = {\n debug: -1,\n info: 0,\n warn: 1,\n error: 2,\n} as const;\nexport type LoggingLevel = keyof typeof LoggingLevels;\n\nexport type LogFn = (\n msg: string,\n ctx?: MessageMetadata,\n level?: LoggingLevel,\n) => void;\nexport type Logger = {\n [key in LoggingLevel]: (msg: string, metadata?: MessageMetadata) => void;\n};\n\nexport type Tags =\n | 'invariant-violation'\n | 'state-transition'\n | 'invalid-request'\n | 'unhealthy-session';\n\nconst cleanedLogFn = (log: LogFn) => {\n return (msg: string, metadata?: MessageMetadata) => {\n // skip cloning object if metadata has no transportMessage\n if (!metadata?.transportMessage) {\n log(msg, metadata);\n\n return;\n }\n\n // clone metadata and clean transportMessage\n const { payload, ...rest } = metadata.transportMessage;\n metadata.transportMessage = rest;\n log(msg, metadata);\n };\n};\n\nexport type MessageMetadata = Partial<{\n protocolVersion: ProtocolVersion;\n clientId: string;\n connectedTo: string;\n sessionId: string;\n connId: string;\n transportMessage: Partial<OpaqueTransportMessage>;\n validationErrors: Array<ValueError>;\n tags: Array<Tags>;\n telemetry: {\n traceId: string;\n spanId: string;\n };\n extras: unknown;\n}>;\n\nexport class BaseLogger implements Logger {\n minLevel: LoggingLevel;\n private output: LogFn;\n\n constructor(output: LogFn, minLevel: LoggingLevel = 'info') {\n this.minLevel = minLevel;\n this.output = output;\n }\n\n debug(msg: string, metadata?: MessageMetadata) {\n if (LoggingLevels[this.minLevel] <= LoggingLevels.debug) {\n this.output(msg, metadata ?? {}, 'debug');\n }\n }\n\n info(msg: string, metadata?: MessageMetadata) {\n if (LoggingLevels[this.minLevel] <= LoggingLevels.info) {\n this.output(msg, metadata ?? {}, 'info');\n }\n }\n\n warn(msg: string, metadata?: MessageMetadata) {\n if (LoggingLevels[this.minLevel] <= LoggingLevels.warn) {\n this.output(msg, metadata ?? {}, 'warn');\n }\n }\n\n error(msg: string, metadata?: MessageMetadata) {\n if (LoggingLevels[this.minLevel] <= LoggingLevels.error) {\n this.output(msg, metadata ?? {}, 'error');\n }\n }\n}\n\nexport const stringLogger: LogFn = (msg, ctx, level = 'info') => {\n const from = ctx?.clientId ? `${ctx.clientId} -- ` : '';\n console.log(`[river:${level}] ${from}${msg}`);\n};\n\nconst colorMap = {\n debug: '\\u001b[34m',\n info: '\\u001b[32m',\n warn: '\\u001b[33m',\n error: '\\u001b[31m',\n};\n\nexport const coloredStringLogger: LogFn = (msg, ctx, level = 'info') => {\n const color = colorMap[level];\n const from = ctx?.clientId ? `${ctx.clientId} -- ` : '';\n console.log(`[river:${color}${level}\\u001b[0m] ${from}${msg}`);\n};\n\nexport const jsonLogger: LogFn = (msg, ctx, level) => {\n console.log(JSON.stringify({ msg, ctx, level }));\n};\n\nexport const createLogProxy = (log: Logger) => ({\n debug: cleanedLogFn(log.debug.bind(log)),\n info: cleanedLogFn(log.info.bind(log)),\n warn: cleanedLogFn(log.warn.bind(log)),\n error: cleanedLogFn(log.error.bind(log)),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4FO,IAAM,eAAsB,CAAC,KAAK,KAAK,QAAQ,WAAW;AAC/D,QAAM,OAAO,KAAK,WAAW,GAAG,IAAI,QAAQ,SAAS;AACrD,UAAQ,IAAI,UAAU,KAAK,KAAK,IAAI,GAAG,GAAG,EAAE;AAC9C;AAEA,IAAM,WAAW;AAAA,EACf,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEO,IAAM,sBAA6B,CAAC,KAAK,KAAK,QAAQ,WAAW;AACtE,QAAM,QAAQ,SAAS,KAAK;AAC5B,QAAM,OAAO,KAAK,WAAW,GAAG,IAAI,QAAQ,SAAS;AACrD,UAAQ,IAAI,UAAU,KAAK,GAAG,KAAK,YAAc,IAAI,GAAG,GAAG,EAAE;AAC/D;AAEO,IAAM,aAAoB,CAAC,KAAK,KAAK,UAAU;AACpD,UAAQ,IAAI,KAAK,UAAU,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC;AACjD;","names":[]}
|