@rivetkit/engine-runner 2.0.24-rc.1 → 2.0.25-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/dist/mod.cjs +1460 -812
- package/dist/mod.cjs.map +1 -1
- package/dist/mod.d.cts +263 -17
- package/dist/mod.d.ts +263 -17
- package/dist/mod.js +1454 -806
- package/dist/mod.js.map +1 -1
- package/package.json +2 -2
- package/src/actor.ts +196 -0
- package/src/mod.ts +409 -177
- package/src/stringify.ts +182 -12
- package/src/tunnel.ts +822 -428
- package/src/utils.ts +93 -0
- package/src/websocket-tunnel-adapter.ts +340 -357
- package/tests/utils.test.ts +194 -0
package/src/stringify.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as protocol from "@rivetkit/engine-runner-protocol";
|
|
2
|
+
import { idToStr } from "./utils";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Helper function to stringify ArrayBuffer for logging
|
|
@@ -24,6 +25,13 @@ function stringifyMap(map: ReadonlyMap<string, string>): string {
|
|
|
24
25
|
return `Map(${map.size}){${entries}}`;
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Helper function to stringify MessageId for logging
|
|
30
|
+
*/
|
|
31
|
+
function stringifyMessageId(messageId: protocol.MessageId): string {
|
|
32
|
+
return `MessageId{gatewayId: ${idToStr(messageId.gatewayId)}, requestId: ${idToStr(messageId.requestId)}, messageIndex: ${messageId.messageIndex}}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
/**
|
|
28
36
|
* Stringify ToServerTunnelMessageKind for logging
|
|
29
37
|
* Handles ArrayBuffers, BigInts, and Maps that can't be JSON.stringified
|
|
@@ -32,8 +40,8 @@ export function stringifyToServerTunnelMessageKind(
|
|
|
32
40
|
kind: protocol.ToServerTunnelMessageKind,
|
|
33
41
|
): string {
|
|
34
42
|
switch (kind.tag) {
|
|
35
|
-
case "
|
|
36
|
-
return "
|
|
43
|
+
case "DeprecatedTunnelAck":
|
|
44
|
+
return "DeprecatedTunnelAck";
|
|
37
45
|
case "ToServerResponseStart": {
|
|
38
46
|
const { status, headers, body, stream } = kind.val;
|
|
39
47
|
const bodyStr = body === null ? "null" : stringifyArrayBuffer(body);
|
|
@@ -46,8 +54,8 @@ export function stringifyToServerTunnelMessageKind(
|
|
|
46
54
|
case "ToServerResponseAbort":
|
|
47
55
|
return "ToServerResponseAbort";
|
|
48
56
|
case "ToServerWebSocketOpen": {
|
|
49
|
-
const { canHibernate
|
|
50
|
-
return `ToServerWebSocketOpen{canHibernate: ${canHibernate}
|
|
57
|
+
const { canHibernate } = kind.val;
|
|
58
|
+
return `ToServerWebSocketOpen{canHibernate: ${canHibernate}}`;
|
|
51
59
|
}
|
|
52
60
|
case "ToServerWebSocketMessage": {
|
|
53
61
|
const { data, binary } = kind.val;
|
|
@@ -58,10 +66,10 @@ export function stringifyToServerTunnelMessageKind(
|
|
|
58
66
|
return `ToServerWebSocketMessageAck{index: ${index}}`;
|
|
59
67
|
}
|
|
60
68
|
case "ToServerWebSocketClose": {
|
|
61
|
-
const { code, reason,
|
|
69
|
+
const { code, reason, hibernate } = kind.val;
|
|
62
70
|
const codeStr = code === null ? "null" : code.toString();
|
|
63
71
|
const reasonStr = reason === null ? "null" : `"${reason}"`;
|
|
64
|
-
return `ToServerWebSocketClose{code: ${codeStr}, reason: ${reasonStr},
|
|
72
|
+
return `ToServerWebSocketClose{code: ${codeStr}, reason: ${reasonStr}, hibernate: ${hibernate}}`;
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
}
|
|
@@ -74,8 +82,8 @@ export function stringifyToClientTunnelMessageKind(
|
|
|
74
82
|
kind: protocol.ToClientTunnelMessageKind,
|
|
75
83
|
): string {
|
|
76
84
|
switch (kind.tag) {
|
|
77
|
-
case "
|
|
78
|
-
return "
|
|
85
|
+
case "DeprecatedTunnelAck":
|
|
86
|
+
return "DeprecatedTunnelAck";
|
|
79
87
|
case "ToClientRequestStart": {
|
|
80
88
|
const { actorId, method, path, headers, body, stream } = kind.val;
|
|
81
89
|
const bodyStr = body === null ? "null" : stringifyArrayBuffer(body);
|
|
@@ -92,8 +100,8 @@ export function stringifyToClientTunnelMessageKind(
|
|
|
92
100
|
return `ToClientWebSocketOpen{actorId: "${actorId}", path: "${path}", headers: ${stringifyMap(headers)}}`;
|
|
93
101
|
}
|
|
94
102
|
case "ToClientWebSocketMessage": {
|
|
95
|
-
const {
|
|
96
|
-
return `ToClientWebSocketMessage{
|
|
103
|
+
const { data, binary } = kind.val;
|
|
104
|
+
return `ToClientWebSocketMessage{data: ${stringifyArrayBuffer(data)}, binary: ${binary}}`;
|
|
97
105
|
}
|
|
98
106
|
case "ToClientWebSocketClose": {
|
|
99
107
|
const { code, reason } = kind.val;
|
|
@@ -111,13 +119,18 @@ export function stringifyToClientTunnelMessageKind(
|
|
|
111
119
|
export function stringifyCommand(command: protocol.Command): string {
|
|
112
120
|
switch (command.tag) {
|
|
113
121
|
case "CommandStartActor": {
|
|
114
|
-
const { actorId, generation, config } =
|
|
122
|
+
const { actorId, generation, config, hibernatingRequests } =
|
|
123
|
+
command.val;
|
|
115
124
|
const keyStr = config.key === null ? "null" : `"${config.key}"`;
|
|
116
125
|
const inputStr =
|
|
117
126
|
config.input === null
|
|
118
127
|
? "null"
|
|
119
128
|
: stringifyArrayBuffer(config.input);
|
|
120
|
-
|
|
129
|
+
const hibernatingRequestsStr =
|
|
130
|
+
hibernatingRequests.length > 0
|
|
131
|
+
? `[${hibernatingRequests.map((hr) => `{gatewayId: ${idToStr(hr.gatewayId)}, requestId: ${idToStr(hr.requestId)}}`).join(", ")}]`
|
|
132
|
+
: "[]";
|
|
133
|
+
return `CommandStartActor{actorId: "${actorId}", generation: ${generation}, config: {name: "${config.name}", key: ${keyStr}, createTs: ${stringifyBigInt(config.createTs)}, input: ${inputStr}}, hibernatingRequests: ${hibernatingRequestsStr}}`;
|
|
121
134
|
}
|
|
122
135
|
case "CommandStopActor": {
|
|
123
136
|
const { actorId, generation } = command.val;
|
|
@@ -182,3 +195,160 @@ export function stringifyEvent(event: protocol.Event): string {
|
|
|
182
195
|
export function stringifyEventWrapper(wrapper: protocol.EventWrapper): string {
|
|
183
196
|
return `EventWrapper{index: ${stringifyBigInt(wrapper.index)}, inner: ${stringifyEvent(wrapper.inner)}}`;
|
|
184
197
|
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Stringify ToServer for logging
|
|
201
|
+
* Handles ArrayBuffers, BigInts, and Maps that can't be JSON.stringified
|
|
202
|
+
*/
|
|
203
|
+
export function stringifyToServer(message: protocol.ToServer): string {
|
|
204
|
+
switch (message.tag) {
|
|
205
|
+
case "ToServerInit": {
|
|
206
|
+
const {
|
|
207
|
+
name,
|
|
208
|
+
version,
|
|
209
|
+
totalSlots,
|
|
210
|
+
lastCommandIdx,
|
|
211
|
+
prepopulateActorNames,
|
|
212
|
+
metadata,
|
|
213
|
+
} = message.val;
|
|
214
|
+
const lastCommandIdxStr =
|
|
215
|
+
lastCommandIdx === null
|
|
216
|
+
? "null"
|
|
217
|
+
: stringifyBigInt(lastCommandIdx);
|
|
218
|
+
const prepopulateActorNamesStr =
|
|
219
|
+
prepopulateActorNames === null
|
|
220
|
+
? "null"
|
|
221
|
+
: `Map(${prepopulateActorNames.size})`;
|
|
222
|
+
const metadataStr = metadata === null ? "null" : `"${metadata}"`;
|
|
223
|
+
return `ToServerInit{name: "${name}", version: ${version}, totalSlots: ${totalSlots}, lastCommandIdx: ${lastCommandIdxStr}, prepopulateActorNames: ${prepopulateActorNamesStr}, metadata: ${metadataStr}}`;
|
|
224
|
+
}
|
|
225
|
+
case "ToServerEvents": {
|
|
226
|
+
const events = message.val;
|
|
227
|
+
return `ToServerEvents{count: ${events.length}, events: [${events.map((e) => stringifyEventWrapper(e)).join(", ")}]}`;
|
|
228
|
+
}
|
|
229
|
+
case "ToServerAckCommands": {
|
|
230
|
+
const { lastCommandIdx } = message.val;
|
|
231
|
+
return `ToServerAckCommands{lastCommandIdx: ${stringifyBigInt(lastCommandIdx)}}`;
|
|
232
|
+
}
|
|
233
|
+
case "ToServerStopping":
|
|
234
|
+
return "ToServerStopping";
|
|
235
|
+
case "ToServerPing": {
|
|
236
|
+
const { ts } = message.val;
|
|
237
|
+
return `ToServerPing{ts: ${stringifyBigInt(ts)}}`;
|
|
238
|
+
}
|
|
239
|
+
case "ToServerKvRequest": {
|
|
240
|
+
const { actorId, requestId, data } = message.val;
|
|
241
|
+
const dataStr = stringifyKvRequestData(data);
|
|
242
|
+
return `ToServerKvRequest{actorId: "${actorId}", requestId: ${requestId}, data: ${dataStr}}`;
|
|
243
|
+
}
|
|
244
|
+
case "ToServerTunnelMessage": {
|
|
245
|
+
const { messageId, messageKind } = message.val;
|
|
246
|
+
return `ToServerTunnelMessage{messageId: ${stringifyMessageId(messageId)}, messageKind: ${stringifyToServerTunnelMessageKind(messageKind)}}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Stringify ToClient for logging
|
|
253
|
+
* Handles ArrayBuffers, BigInts, and Maps that can't be JSON.stringified
|
|
254
|
+
*/
|
|
255
|
+
export function stringifyToClient(message: protocol.ToClient): string {
|
|
256
|
+
switch (message.tag) {
|
|
257
|
+
case "ToClientInit": {
|
|
258
|
+
const { runnerId, lastEventIdx, metadata } = message.val;
|
|
259
|
+
const metadataStr = `{runnerLostThreshold: ${stringifyBigInt(metadata.runnerLostThreshold)}}`;
|
|
260
|
+
return `ToClientInit{runnerId: "${runnerId}", lastEventIdx: ${stringifyBigInt(lastEventIdx)}, metadata: ${metadataStr}}`;
|
|
261
|
+
}
|
|
262
|
+
case "ToClientClose":
|
|
263
|
+
return "ToClientClose";
|
|
264
|
+
case "ToClientCommands": {
|
|
265
|
+
const commands = message.val;
|
|
266
|
+
return `ToClientCommands{count: ${commands.length}, commands: [${commands.map((c) => stringifyCommandWrapper(c)).join(", ")}]}`;
|
|
267
|
+
}
|
|
268
|
+
case "ToClientAckEvents": {
|
|
269
|
+
const { lastEventIdx } = message.val;
|
|
270
|
+
return `ToClientAckEvents{lastEventIdx: ${stringifyBigInt(lastEventIdx)}}`;
|
|
271
|
+
}
|
|
272
|
+
case "ToClientKvResponse": {
|
|
273
|
+
const { requestId, data } = message.val;
|
|
274
|
+
const dataStr = stringifyKvResponseData(data);
|
|
275
|
+
return `ToClientKvResponse{requestId: ${requestId}, data: ${dataStr}}`;
|
|
276
|
+
}
|
|
277
|
+
case "ToClientTunnelMessage": {
|
|
278
|
+
const { messageId, messageKind } = message.val;
|
|
279
|
+
return `ToClientTunnelMessage{messageId: ${stringifyMessageId(messageId)}, messageKind: ${stringifyToClientTunnelMessageKind(messageKind)}}`;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Stringify KvRequestData for logging
|
|
286
|
+
*/
|
|
287
|
+
function stringifyKvRequestData(data: protocol.KvRequestData): string {
|
|
288
|
+
switch (data.tag) {
|
|
289
|
+
case "KvGetRequest": {
|
|
290
|
+
const { keys } = data.val;
|
|
291
|
+
return `KvGetRequest{keys: ${keys.length}}`;
|
|
292
|
+
}
|
|
293
|
+
case "KvListRequest": {
|
|
294
|
+
const { query, reverse, limit } = data.val;
|
|
295
|
+
const reverseStr = reverse === null ? "null" : reverse.toString();
|
|
296
|
+
const limitStr = limit === null ? "null" : stringifyBigInt(limit);
|
|
297
|
+
return `KvListRequest{query: ${stringifyKvListQuery(query)}, reverse: ${reverseStr}, limit: ${limitStr}}`;
|
|
298
|
+
}
|
|
299
|
+
case "KvPutRequest": {
|
|
300
|
+
const { keys, values } = data.val;
|
|
301
|
+
return `KvPutRequest{keys: ${keys.length}, values: ${values.length}}`;
|
|
302
|
+
}
|
|
303
|
+
case "KvDeleteRequest": {
|
|
304
|
+
const { keys } = data.val;
|
|
305
|
+
return `KvDeleteRequest{keys: ${keys.length}}`;
|
|
306
|
+
}
|
|
307
|
+
case "KvDropRequest":
|
|
308
|
+
return "KvDropRequest";
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Stringify KvListQuery for logging
|
|
314
|
+
*/
|
|
315
|
+
function stringifyKvListQuery(query: protocol.KvListQuery): string {
|
|
316
|
+
switch (query.tag) {
|
|
317
|
+
case "KvListAllQuery":
|
|
318
|
+
return "KvListAllQuery";
|
|
319
|
+
case "KvListRangeQuery": {
|
|
320
|
+
const { start, end, exclusive } = query.val;
|
|
321
|
+
return `KvListRangeQuery{start: ${stringifyArrayBuffer(start)}, end: ${stringifyArrayBuffer(end)}, exclusive: ${exclusive}}`;
|
|
322
|
+
}
|
|
323
|
+
case "KvListPrefixQuery": {
|
|
324
|
+
const { key } = query.val;
|
|
325
|
+
return `KvListPrefixQuery{key: ${stringifyArrayBuffer(key)}}`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Stringify KvResponseData for logging
|
|
332
|
+
*/
|
|
333
|
+
function stringifyKvResponseData(data: protocol.KvResponseData): string {
|
|
334
|
+
switch (data.tag) {
|
|
335
|
+
case "KvErrorResponse": {
|
|
336
|
+
const { message } = data.val;
|
|
337
|
+
return `KvErrorResponse{message: "${message}"}`;
|
|
338
|
+
}
|
|
339
|
+
case "KvGetResponse": {
|
|
340
|
+
const { keys, values, metadata } = data.val;
|
|
341
|
+
return `KvGetResponse{keys: ${keys.length}, values: ${values.length}, metadata: ${metadata.length}}`;
|
|
342
|
+
}
|
|
343
|
+
case "KvListResponse": {
|
|
344
|
+
const { keys, values, metadata } = data.val;
|
|
345
|
+
return `KvListResponse{keys: ${keys.length}, values: ${values.length}, metadata: ${metadata.length}}`;
|
|
346
|
+
}
|
|
347
|
+
case "KvPutResponse":
|
|
348
|
+
return "KvPutResponse";
|
|
349
|
+
case "KvDeleteResponse":
|
|
350
|
+
return "KvDeleteResponse";
|
|
351
|
+
case "KvDropResponse":
|
|
352
|
+
return "KvDropResponse";
|
|
353
|
+
}
|
|
354
|
+
}
|