@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/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 "TunnelAck":
36
- return "TunnelAck";
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, lastMsgIndex } = kind.val;
50
- return `ToServerWebSocketOpen{canHibernate: ${canHibernate}, lastMsgIndex: ${stringifyBigInt(lastMsgIndex)}}`;
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, retry } = kind.val;
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}, retry: ${retry}}`;
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 "TunnelAck":
78
- return "TunnelAck";
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 { index, data, binary } = kind.val;
96
- return `ToClientWebSocketMessage{index: ${index}, data: ${stringifyArrayBuffer(data)}, binary: ${binary}}`;
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 } = command.val;
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
- return `CommandStartActor{actorId: "${actorId}", generation: ${generation}, config: {name: "${config.name}", key: ${keyStr}, createTs: ${stringifyBigInt(config.createTs)}, input: ${inputStr}}}`;
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
+ }