@rivetkit/engine-runner 2.0.25 → 2.0.26

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
@@ -40,8 +40,6 @@ export function stringifyToServerTunnelMessageKind(
40
40
  kind: protocol.ToServerTunnelMessageKind,
41
41
  ): string {
42
42
  switch (kind.tag) {
43
- case "DeprecatedTunnelAck":
44
- return "DeprecatedTunnelAck";
45
43
  case "ToServerResponseStart": {
46
44
  const { status, headers, body, stream } = kind.val;
47
45
  const bodyStr = body === null ? "null" : stringifyArrayBuffer(body);
@@ -82,8 +80,6 @@ export function stringifyToClientTunnelMessageKind(
82
80
  kind: protocol.ToClientTunnelMessageKind,
83
81
  ): string {
84
82
  switch (kind.tag) {
85
- case "DeprecatedTunnelAck":
86
- return "DeprecatedTunnelAck";
87
83
  case "ToClientRequestStart": {
88
84
  const { actorId, method, path, headers, body, stream } = kind.val;
89
85
  const bodyStr = body === null ? "null" : stringifyArrayBuffer(body);
@@ -119,7 +115,7 @@ export function stringifyToClientTunnelMessageKind(
119
115
  export function stringifyCommand(command: protocol.Command): string {
120
116
  switch (command.tag) {
121
117
  case "CommandStartActor": {
122
- const { actorId, generation, config, hibernatingRequests } =
118
+ const { generation, config, hibernatingRequests } =
123
119
  command.val;
124
120
  const keyStr = config.key === null ? "null" : `"${config.key}"`;
125
121
  const inputStr =
@@ -130,11 +126,11 @@ export function stringifyCommand(command: protocol.Command): string {
130
126
  hibernatingRequests.length > 0
131
127
  ? `[${hibernatingRequests.map((hr) => `{gatewayId: ${idToStr(hr.gatewayId)}, requestId: ${idToStr(hr.requestId)}}`).join(", ")}]`
132
128
  : "[]";
133
- return `CommandStartActor{actorId: "${actorId}", generation: ${generation}, config: {name: "${config.name}", key: ${keyStr}, createTs: ${stringifyBigInt(config.createTs)}, input: ${inputStr}}, hibernatingRequests: ${hibernatingRequestsStr}}`;
129
+ return `CommandStartActor{generation: ${generation}, config: {name: "${config.name}", key: ${keyStr}, createTs: ${stringifyBigInt(config.createTs)}, input: ${inputStr}}, hibernatingRequests: ${hibernatingRequestsStr}}`;
134
130
  }
135
131
  case "CommandStopActor": {
136
- const { actorId, generation } = command.val;
137
- return `CommandStopActor{actorId: "${actorId}", generation: ${generation}}`;
132
+ const { generation } = command.val;
133
+ return `CommandStopActor{generation: ${generation}}`;
138
134
  }
139
135
  }
140
136
  }
@@ -146,7 +142,7 @@ export function stringifyCommand(command: protocol.Command): string {
146
142
  export function stringifyCommandWrapper(
147
143
  wrapper: protocol.CommandWrapper,
148
144
  ): string {
149
- return `CommandWrapper{index: ${stringifyBigInt(wrapper.index)}, inner: ${stringifyCommand(wrapper.inner)}}`;
145
+ return `CommandWrapper{actorId: "${wrapper.checkpoint.actorId}", index: ${stringifyBigInt(wrapper.checkpoint.index)}, inner: ${stringifyCommand(wrapper.inner)}}`;
150
146
  }
151
147
 
152
148
  /**
@@ -193,7 +189,7 @@ export function stringifyEvent(event: protocol.Event): string {
193
189
  * Handles ArrayBuffers, BigInts, and Maps that can't be JSON.stringified
194
190
  */
195
191
  export function stringifyEventWrapper(wrapper: protocol.EventWrapper): string {
196
- return `EventWrapper{index: ${stringifyBigInt(wrapper.index)}, inner: ${stringifyEvent(wrapper.inner)}}`;
192
+ return `EventWrapper{actorId: ${wrapper.checkpoint.actorId}, index: ${stringifyBigInt(wrapper.checkpoint.index)}, inner: ${stringifyEvent(wrapper.inner)}}`;
197
193
  }
198
194
 
199
195
  /**
@@ -207,34 +203,33 @@ export function stringifyToServer(message: protocol.ToServer): string {
207
203
  name,
208
204
  version,
209
205
  totalSlots,
210
- lastCommandIdx,
211
206
  prepopulateActorNames,
212
207
  metadata,
213
208
  } = message.val;
214
- const lastCommandIdxStr =
215
- lastCommandIdx === null
216
- ? "null"
217
- : stringifyBigInt(lastCommandIdx);
218
209
  const prepopulateActorNamesStr =
219
210
  prepopulateActorNames === null
220
211
  ? "null"
221
212
  : `Map(${prepopulateActorNames.size})`;
222
213
  const metadataStr = metadata === null ? "null" : `"${metadata}"`;
223
- return `ToServerInit{name: "${name}", version: ${version}, totalSlots: ${totalSlots}, lastCommandIdx: ${lastCommandIdxStr}, prepopulateActorNames: ${prepopulateActorNamesStr}, metadata: ${metadataStr}}`;
214
+ return `ToServerInit{name: "${name}", version: ${version}, totalSlots: ${totalSlots}, prepopulateActorNames: ${prepopulateActorNamesStr}, metadata: ${metadataStr}}`;
224
215
  }
225
216
  case "ToServerEvents": {
226
217
  const events = message.val;
227
218
  return `ToServerEvents{count: ${events.length}, events: [${events.map((e) => stringifyEventWrapper(e)).join(", ")}]}`;
228
219
  }
229
220
  case "ToServerAckCommands": {
230
- const { lastCommandIdx } = message.val;
231
- return `ToServerAckCommands{lastCommandIdx: ${stringifyBigInt(lastCommandIdx)}}`;
221
+ const { lastCommandCheckpoints } = message.val;
222
+ const checkpointsStr =
223
+ lastCommandCheckpoints.length > 0
224
+ ? `[${lastCommandCheckpoints.map((cp) => `{actorId: "${cp.actorId}", index: ${stringifyBigInt(cp.index)}}`).join(", ")}]`
225
+ : "[]";
226
+ return `ToServerAckCommands{lastCommandCheckpoints: ${checkpointsStr}}`;
232
227
  }
233
228
  case "ToServerStopping":
234
229
  return "ToServerStopping";
235
- case "ToServerPing": {
230
+ case "ToServerPong": {
236
231
  const { ts } = message.val;
237
- return `ToServerPing{ts: ${stringifyBigInt(ts)}}`;
232
+ return `ToServerPong{ts: ${stringifyBigInt(ts)}}`;
238
233
  }
239
234
  case "ToServerKvRequest": {
240
235
  const { actorId, requestId, data } = message.val;
@@ -255,19 +250,24 @@ export function stringifyToServer(message: protocol.ToServer): string {
255
250
  export function stringifyToClient(message: protocol.ToClient): string {
256
251
  switch (message.tag) {
257
252
  case "ToClientInit": {
258
- const { runnerId, lastEventIdx, metadata } = message.val;
253
+ const { runnerId, metadata } = message.val;
259
254
  const metadataStr = `{runnerLostThreshold: ${stringifyBigInt(metadata.runnerLostThreshold)}}`;
260
- return `ToClientInit{runnerId: "${runnerId}", lastEventIdx: ${stringifyBigInt(lastEventIdx)}, metadata: ${metadataStr}}`;
255
+ return `ToClientInit{runnerId: "${runnerId}", metadata: ${metadataStr}}`;
261
256
  }
262
- case "ToClientClose":
263
- return "ToClientClose";
257
+ case "ToClientPing":
258
+ const { ts } = message.val;
259
+ return `ToClientPing{ts: ${stringifyBigInt(ts)}}`;
264
260
  case "ToClientCommands": {
265
261
  const commands = message.val;
266
262
  return `ToClientCommands{count: ${commands.length}, commands: [${commands.map((c) => stringifyCommandWrapper(c)).join(", ")}]}`;
267
263
  }
268
264
  case "ToClientAckEvents": {
269
- const { lastEventIdx } = message.val;
270
- return `ToClientAckEvents{lastEventIdx: ${stringifyBigInt(lastEventIdx)}}`;
265
+ const { lastEventCheckpoints } = message.val;
266
+ const checkpointsStr =
267
+ lastEventCheckpoints.length > 0
268
+ ? `[${lastEventCheckpoints.map((cp) => `{actorId: "${cp.actorId}", index: ${stringifyBigInt(cp.index)}}`).join(", ")}]`
269
+ : "[]";
270
+ return `ToClientAckEvents{lastEventCheckpoints: ${checkpointsStr}}`;
271
271
  }
272
272
  case "ToClientKvResponse": {
273
273
  const { requestId, data } = message.val;
package/src/tunnel.ts CHANGED
@@ -10,12 +10,12 @@ import {
10
10
  stringify as uuidstringify,
11
11
  v4 as uuidv4,
12
12
  } from "uuid";
13
- import type { Runner, RunnerActor } from "./mod";
13
+ import { RunnerShutdownError, type Runner, type RunnerActor } from "./mod";
14
14
  import {
15
15
  stringifyToClientTunnelMessageKind,
16
16
  stringifyToServerTunnelMessageKind,
17
17
  } from "./stringify";
18
- import { arraysEqual, idToStr, unreachable } from "./utils";
18
+ import { arraysEqual, idToStr, stringifyError, unreachable } from "./utils";
19
19
  import {
20
20
  HIBERNATABLE_SYMBOL,
21
21
  WebSocketTunnelAdapter,
@@ -41,12 +41,6 @@ export interface HibernatingWebSocketMetadata {
41
41
  headers: Record<string, string>;
42
42
  }
43
43
 
44
- class RunnerShutdownError extends Error {
45
- constructor() {
46
- super("Runner shut down");
47
- }
48
- }
49
-
50
44
  export class Tunnel {
51
45
  #runner: Runner;
52
46
 
@@ -226,7 +220,7 @@ export class Tunnel {
226
220
  this.log?.error({
227
221
  msg: "error creating websocket during restore",
228
222
  requestId: requestIdStr,
229
- err,
223
+ error: stringifyError(err),
230
224
  });
231
225
 
232
226
  // Close the WebSocket on error
@@ -291,7 +285,7 @@ export class Tunnel {
291
285
  this.log?.error({
292
286
  msg: "error creating stale websocket during restore",
293
287
  requestId: requestIdStr,
294
- err,
288
+ error: stringifyError(err),
295
289
  });
296
290
  });
297
291
 
@@ -671,9 +665,6 @@ export class Tunnel {
671
665
  message.messageKind.val,
672
666
  );
673
667
  break;
674
- case "DeprecatedTunnelAck":
675
- // Ignore deprecated tunnel ack messages
676
- break;
677
668
  default:
678
669
  unreachable(message.messageKind);
679
670
  }
package/src/utils.ts CHANGED
@@ -157,3 +157,19 @@ export function idToStr(id: ArrayBuffer): string {
157
157
  .map((byte) => byte.toString(16).padStart(2, "0"))
158
158
  .join("");
159
159
  }
160
+
161
+ export function stringifyError(error: unknown): string {
162
+ if (error instanceof Error) {
163
+ return `${error.name}: ${error.message}${error.stack ? `\n${error.stack}` : ""}`;
164
+ } else if (typeof error === "string") {
165
+ return error;
166
+ } else if (typeof error === "object" && error !== null) {
167
+ try {
168
+ return `${JSON.stringify(error)}`;
169
+ } catch {
170
+ return `[object ${error.constructor?.name || "Object"}]`;
171
+ }
172
+ } else {
173
+ return String(error);
174
+ }
175
+ }