rivetkit 2.3.30 → 3.0.0-preview.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.
Files changed (135) hide show
  1. package/dist/browser/client.d.ts +58 -9
  2. package/dist/browser/client.js +193 -20
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +1 -2
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/{chunk-5UUOECX2.cjs → chunk-3E2BPHQO.cjs} +10 -10
  7. package/dist/tsup/{chunk-5UUOECX2.cjs.map → chunk-3E2BPHQO.cjs.map} +1 -1
  8. package/dist/tsup/{chunk-I472KTIC.js → chunk-3MMTF3QA.js} +188 -28
  9. package/dist/tsup/chunk-3MMTF3QA.js.map +1 -0
  10. package/dist/tsup/{chunk-CORYIKDC.js → chunk-5OCN7VHH.js} +10 -11
  11. package/dist/tsup/chunk-5OCN7VHH.js.map +1 -0
  12. package/dist/tsup/{chunk-OJFVABRH.cjs → chunk-6DDQSAAT.cjs} +7 -7
  13. package/dist/tsup/{chunk-OJFVABRH.cjs.map → chunk-6DDQSAAT.cjs.map} +1 -1
  14. package/dist/tsup/{chunk-JI6GZ2C2.js → chunk-A2CF6PFH.js} +18 -1
  15. package/dist/tsup/chunk-A2CF6PFH.js.map +1 -0
  16. package/dist/tsup/{chunk-P2PHHJMH.cjs → chunk-CTQKKUZC.cjs} +327 -167
  17. package/dist/tsup/chunk-CTQKKUZC.cjs.map +1 -0
  18. package/dist/tsup/{chunk-H3SGQEHZ.js → chunk-DCDCHB5J.js} +2 -2
  19. package/dist/tsup/{chunk-EKAQ7HG2.js → chunk-DQ6K3VVV.js} +3 -3
  20. package/dist/tsup/{chunk-OUB7SGSA.js → chunk-H6W37YLT.js} +2 -2
  21. package/dist/tsup/{chunk-5SN6GAYX.cjs → chunk-HW2D5OFJ.cjs} +3 -3
  22. package/dist/tsup/{chunk-5SN6GAYX.cjs.map → chunk-HW2D5OFJ.cjs.map} +1 -1
  23. package/dist/tsup/{chunk-2BIRGEIU.cjs → chunk-IBEFA6CX.cjs} +10 -11
  24. package/dist/tsup/chunk-IBEFA6CX.cjs.map +1 -0
  25. package/dist/tsup/{chunk-GEUBEODU.cjs → chunk-JLBPBEWC.cjs} +3 -3
  26. package/dist/tsup/{chunk-GEUBEODU.cjs.map → chunk-JLBPBEWC.cjs.map} +1 -1
  27. package/dist/tsup/{chunk-4SNS3PYZ.js → chunk-KQ2WQDYT.js} +2 -2
  28. package/dist/tsup/{chunk-MYWZCDML.cjs → chunk-RTWH3AX3.cjs} +19 -2
  29. package/dist/tsup/chunk-RTWH3AX3.cjs.map +1 -0
  30. package/dist/tsup/{chunk-6LOYTFPZ.js → chunk-SJPPKBT3.js} +2 -2
  31. package/dist/tsup/{chunk-MXV26ZBB.js → chunk-TBJ4I3R3.js} +4 -4
  32. package/dist/tsup/{chunk-ZIIQQHC3.cjs → chunk-VCVV726P.cjs} +4 -4
  33. package/dist/tsup/{chunk-ZIIQQHC3.cjs.map → chunk-VCVV726P.cjs.map} +1 -1
  34. package/dist/tsup/{chunk-ABPZG7QV.cjs → chunk-XUO6G4H6.cjs} +3 -3
  35. package/dist/tsup/{chunk-ABPZG7QV.cjs.map → chunk-XUO6G4H6.cjs.map} +1 -1
  36. package/dist/tsup/client/mod.cjs +6 -6
  37. package/dist/tsup/client/mod.d.cts +15 -3
  38. package/dist/tsup/client/mod.d.ts +15 -3
  39. package/dist/tsup/client/mod.js +5 -5
  40. package/dist/tsup/common/log.cjs +2 -2
  41. package/dist/tsup/common/log.js +1 -1
  42. package/dist/tsup/common/websocket.cjs +3 -3
  43. package/dist/tsup/common/websocket.js +2 -2
  44. package/dist/tsup/{config-osdJqQwX.d.cts → config-8NgsxIcT.d.cts} +43 -12
  45. package/dist/tsup/{config-ey2I2zz5.d.ts → config-B2wlj9wx.d.cts} +7 -1
  46. package/dist/tsup/{config-ey2I2zz5.d.cts → config-B2wlj9wx.d.ts} +7 -1
  47. package/dist/tsup/{config-Cv6pjCt-.d.ts → config-DJ3KW-fe.d.ts} +43 -12
  48. package/dist/tsup/{context-CoVbKBuk.d.ts → context-BL8kUGjq.d.ts} +2 -2
  49. package/dist/tsup/{context-DpjrM7n7.d.cts → context-_RoE_YHL.d.cts} +2 -2
  50. package/dist/tsup/db/drizzle.cjs +2 -2
  51. package/dist/tsup/db/drizzle.d.cts +1 -1
  52. package/dist/tsup/db/drizzle.d.ts +1 -1
  53. package/dist/tsup/db/drizzle.js +1 -1
  54. package/dist/tsup/db/mod.cjs +3 -3
  55. package/dist/tsup/db/mod.d.cts +2 -2
  56. package/dist/tsup/db/mod.d.ts +2 -2
  57. package/dist/tsup/db/mod.js +2 -2
  58. package/dist/tsup/dynamic/mod.d.cts +2 -2
  59. package/dist/tsup/dynamic/mod.d.ts +2 -2
  60. package/dist/tsup/inspector/mod.cjs +5 -5
  61. package/dist/tsup/inspector/mod.js +4 -4
  62. package/dist/tsup/inspector/workflow.cjs +4 -4
  63. package/dist/tsup/inspector/workflow.js +3 -3
  64. package/dist/tsup/inspector-tab/mod.d.cts +3 -3
  65. package/dist/tsup/inspector-tab/mod.d.ts +3 -3
  66. package/dist/tsup/mod.cjs +254 -166
  67. package/dist/tsup/mod.cjs.map +1 -1
  68. package/dist/tsup/mod.d.cts +4 -4
  69. package/dist/tsup/mod.d.ts +4 -4
  70. package/dist/tsup/mod.js +168 -80
  71. package/dist/tsup/mod.js.map +1 -1
  72. package/dist/tsup/test/mod.cjs +7 -7
  73. package/dist/tsup/test/mod.d.cts +2 -2
  74. package/dist/tsup/test/mod.d.ts +2 -2
  75. package/dist/tsup/test/mod.js +5 -5
  76. package/dist/tsup/unstable/migrations.d.cts +1 -1
  77. package/dist/tsup/unstable/migrations.d.ts +1 -1
  78. package/dist/tsup/utils.cjs +2 -2
  79. package/dist/tsup/utils.js +1 -1
  80. package/dist/tsup/workflow/mod.cjs +17 -17
  81. package/dist/tsup/workflow/mod.d.cts +4 -4
  82. package/dist/tsup/workflow/mod.d.ts +4 -4
  83. package/dist/tsup/workflow/mod.js +5 -5
  84. package/package.json +9 -10
  85. package/src/actor/keys.ts +86 -0
  86. package/src/client/actor-conn.ts +92 -6
  87. package/src/client/actor-handle.ts +21 -3
  88. package/src/client/client.ts +6 -0
  89. package/src/client/config.ts +12 -1
  90. package/src/client/lifecycle-errors.ts +16 -1
  91. package/src/client/retry-budget.ts +78 -0
  92. package/src/client/utils.ts +13 -2
  93. package/src/common/database/config.ts +7 -1
  94. package/src/common/database/native-database.ts +17 -6
  95. package/src/common/router.ts +1 -1
  96. package/src/engine-api/actors.ts +3 -3
  97. package/src/engine-client/actor-websocket-client.ts +4 -2
  98. package/src/engine-client/api-endpoints.ts +44 -14
  99. package/src/engine-client/mod.ts +2 -2
  100. package/src/registry/config/envoy.ts +1 -1
  101. package/src/registry/config/index.ts +28 -31
  102. package/src/registry/index.ts +51 -19
  103. package/src/registry/napi-runtime.ts +3 -2
  104. package/src/registry/native.ts +126 -34
  105. package/src/registry/runtime.ts +27 -10
  106. package/src/registry/wasm-runtime.ts +6 -3
  107. package/src/utils/env-vars.ts +15 -10
  108. package/dist/tsup/chunk-2BIRGEIU.cjs.map +0 -1
  109. package/dist/tsup/chunk-CORYIKDC.js.map +0 -1
  110. package/dist/tsup/chunk-I472KTIC.js.map +0 -1
  111. package/dist/tsup/chunk-JI6GZ2C2.js.map +0 -1
  112. package/dist/tsup/chunk-MYWZCDML.cjs.map +0 -1
  113. package/dist/tsup/chunk-P2PHHJMH.cjs.map +0 -1
  114. package/src/actor/config.test.ts +0 -78
  115. package/src/actor/keys.test.ts +0 -275
  116. package/src/actor/utils.test.ts +0 -48
  117. package/src/client/test.ts +0 -44
  118. package/src/client/token-provider.test.ts +0 -86
  119. package/src/common/database/mod.test.ts +0 -364
  120. package/src/common/database/native-database.test.ts +0 -220
  121. package/src/common/inline-websocket-adapter.test.ts +0 -51
  122. package/src/db/drizzle.test.ts +0 -164
  123. package/src/registry/config/index.test.ts +0 -25
  124. package/src/registry/run-handler-coordinator.test.ts +0 -252
  125. package/src/registry/runtime.test.ts +0 -124
  126. package/src/unstable/migrations.test.ts +0 -170
  127. package/src/utils/endpoint-parser.test.ts +0 -206
  128. package/src/utils.test.ts +0 -34
  129. package/src/workflow/driver.test.ts +0 -62
  130. /package/dist/tsup/{chunk-H3SGQEHZ.js.map → chunk-DCDCHB5J.js.map} +0 -0
  131. /package/dist/tsup/{chunk-EKAQ7HG2.js.map → chunk-DQ6K3VVV.js.map} +0 -0
  132. /package/dist/tsup/{chunk-OUB7SGSA.js.map → chunk-H6W37YLT.js.map} +0 -0
  133. /package/dist/tsup/{chunk-4SNS3PYZ.js.map → chunk-KQ2WQDYT.js.map} +0 -0
  134. /package/dist/tsup/{chunk-6LOYTFPZ.js.map → chunk-SJPPKBT3.js.map} +0 -0
  135. /package/dist/tsup/{chunk-MXV26ZBB.js.map → chunk-TBJ4I3R3.js.map} +0 -0
@@ -1,14 +1,15 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2;
2
2
 
3
3
 
4
- var _chunkMYWZCDMLcjs = require('./chunk-MYWZCDML.cjs');
4
+
5
+ var _chunkRTWH3AX3cjs = require('./chunk-RTWH3AX3.cjs');
5
6
 
6
7
 
7
- var _chunkKVFIONKQcjs = require('./chunk-KVFIONKQ.cjs');
8
8
 
9
+ var _chunkHW2D5OFJcjs = require('./chunk-HW2D5OFJ.cjs');
9
10
 
10
11
 
11
- var _chunk5SN6GAYXcjs = require('./chunk-5SN6GAYX.cjs');
12
+ var _chunkKVFIONKQcjs = require('./chunk-KVFIONKQ.cjs');
12
13
 
13
14
 
14
15
 
@@ -35,7 +36,7 @@ var _chunk5SN6GAYXcjs = require('./chunk-5SN6GAYX.cjs');
35
36
 
36
37
 
37
38
 
38
- var _chunk2BIRGEIUcjs = require('./chunk-2BIRGEIU.cjs');
39
+ var _chunkIBEFA6CXcjs = require('./chunk-IBEFA6CX.cjs');
39
40
 
40
41
 
41
42
 
@@ -2131,7 +2132,7 @@ async function checkForSchedulingError(group, code, actorId, query, driver, rayI
2131
2132
  try {
2132
2133
  const actor = await driver.getForId({ name, actorId });
2133
2134
  if (actor == null ? void 0 : actor.error) {
2134
- _chunk5SN6GAYXcjs.logger.call(void 0, ).info({
2135
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).info({
2135
2136
  msg: "found actor scheduling error",
2136
2137
  actorId,
2137
2138
  error: actor.error
@@ -2145,10 +2146,10 @@ async function checkForSchedulingError(group, code, actorId, query, driver, rayI
2145
2146
  );
2146
2147
  }
2147
2148
  } catch (err) {
2148
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
2149
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
2149
2150
  msg: "failed to fetch actor details for scheduling error check",
2150
2151
  actorId,
2151
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
2152
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
2152
2153
  });
2153
2154
  }
2154
2155
  return null;
@@ -2176,6 +2177,56 @@ function readRequestBody(request) {
2176
2177
  ).arrayBuffer();
2177
2178
  }
2178
2179
 
2180
+ // src/client/retry-budget.ts
2181
+ var DEFAULT_PERCENT = 10;
2182
+ var DEFAULT_MAX_TOKENS = 100;
2183
+ var RetryBudget = class {
2184
+ #tokens;
2185
+ #maxTokens;
2186
+ #deposit;
2187
+ constructor(options = {}) {
2188
+ const percent = _nullishCoalesce(options.percent, () => ( DEFAULT_PERCENT));
2189
+ const maxTokens = _nullishCoalesce(options.maxTokens, () => ( DEFAULT_MAX_TOKENS));
2190
+ if (!(percent >= 0 && percent <= 100)) {
2191
+ throw new Error("retryBudget.percent must be in 0..=100");
2192
+ }
2193
+ if (!(maxTokens >= 0)) {
2194
+ throw new Error("retryBudget.maxTokens must be at least 0");
2195
+ }
2196
+ this.#maxTokens = maxTokens;
2197
+ this.#tokens = maxTokens;
2198
+ this.#deposit = percent / 100;
2199
+ }
2200
+ /** Credits one request sent. */
2201
+ deposit() {
2202
+ this.#tokens = Math.min(this.#maxTokens, this.#tokens + this.#deposit);
2203
+ }
2204
+ /** Spends one token. Returns `false` when the budget is spent. */
2205
+ tryWithdraw() {
2206
+ if (this.#tokens + 1e-9 < 1) {
2207
+ return false;
2208
+ }
2209
+ this.#tokens = Math.max(0, this.#tokens - 1);
2210
+ return true;
2211
+ }
2212
+ };
2213
+ function retryAfterMs(error) {
2214
+ if (!(error instanceof _chunkMGI2VVF6cjs.RivetError)) {
2215
+ return void 0;
2216
+ }
2217
+ const metadata = error.metadata;
2218
+ if (metadata === null || typeof metadata !== "object") {
2219
+ return void 0;
2220
+ }
2221
+ const hint = metadata.retry_after_ms;
2222
+ return typeof hint === "number" && hint >= 0 ? hint : void 0;
2223
+ }
2224
+ function retryDelayMs(attempt, opts) {
2225
+ const backoff = Math.min(opts.initialDelayMs * 2 ** attempt, opts.maxDelayMs);
2226
+ const jittered = backoff / 2 + Math.random() * (backoff / 2);
2227
+ return Math.max(jittered, _nullishCoalesce(opts.hintMs, () => ( 0)));
2228
+ }
2229
+
2179
2230
  // src/client/lifecycle-errors.ts
2180
2231
  function* walkErrorChain(error, maxDepth = 8) {
2181
2232
  let current = error;
@@ -2351,9 +2402,11 @@ async function waitWithSignal(ms, signal) {
2351
2402
  });
2352
2403
  }
2353
2404
  async function retryOnLifecycleBoundary(run, opts) {
2405
+ var _a;
2354
2406
  const maxAttempts = _nullishCoalesce((opts == null ? void 0 : opts.maxAttempts), () => ( 5));
2355
2407
  const initialDelayMs = _nullishCoalesce((opts == null ? void 0 : opts.initialDelayMs), () => ( 25));
2356
2408
  const maxDelayMs = _nullishCoalesce((opts == null ? void 0 : opts.maxDelayMs), () => ( 200));
2409
+ (_a = opts == null ? void 0 : opts.budget) == null ? void 0 : _a.deposit();
2357
2410
  let lastError;
2358
2411
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
2359
2412
  throwIfAborted(opts == null ? void 0 : opts.signal);
@@ -2367,7 +2420,14 @@ async function retryOnLifecycleBoundary(run, opts) {
2367
2420
  if (attempt === maxAttempts - 1) {
2368
2421
  break;
2369
2422
  }
2370
- const delayMs = Math.min(initialDelayMs * 2 ** attempt, maxDelayMs);
2423
+ if ((opts == null ? void 0 : opts.budget) && !opts.budget.tryWithdraw()) {
2424
+ break;
2425
+ }
2426
+ const delayMs = retryDelayMs(attempt, {
2427
+ initialDelayMs,
2428
+ maxDelayMs,
2429
+ hintMs: retryAfterMs(error)
2430
+ });
2371
2431
  await waitWithSignal(delayMs, opts == null ? void 0 : opts.signal);
2372
2432
  }
2373
2433
  }
@@ -2460,17 +2520,22 @@ function addOutboundTelemetryHeaders(headers, telemetry) {
2460
2520
 
2461
2521
  // src/client/utils.ts
2462
2522
 
2523
+ var RETRY_AFTER_SUFFIX = /^retry_after_ms=(\d+)$/;
2463
2524
  function parseWebSocketCloseReason(reason) {
2464
- const [mainPart, rayId] = reason.split("#");
2525
+ const [mainPart, suffix] = reason.split("#");
2465
2526
  const [group, code] = mainPart.split(".");
2466
2527
  if (!group || !code) {
2467
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({ msg: "failed to parse close reason", reason });
2528
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({ msg: "failed to parse close reason", reason });
2468
2529
  return void 0;
2469
2530
  }
2531
+ const retryAfter = suffix == null ? void 0 : suffix.match(RETRY_AFTER_SUFFIX);
2532
+ if (retryAfter) {
2533
+ return { group, code, retryAfterMs: Number(retryAfter[1]) };
2534
+ }
2470
2535
  return {
2471
2536
  group,
2472
2537
  code,
2473
- rayId
2538
+ rayId: suffix
2474
2539
  };
2475
2540
  }
2476
2541
  function messageLength(message) {
@@ -2486,11 +2551,11 @@ function messageLength(message) {
2486
2551
  if (typeof message === "string") {
2487
2552
  return message.length;
2488
2553
  }
2489
- _chunk2BIRGEIUcjs.assertUnreachable.call(void 0, message);
2554
+ _chunkIBEFA6CXcjs.assertUnreachable.call(void 0, message);
2490
2555
  }
2491
2556
  async function sendHttpRequest(opts) {
2492
2557
  var _a, _b, _c;
2493
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
2558
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
2494
2559
  msg: "sending http request",
2495
2560
  url: opts.url,
2496
2561
  encoding: opts.encoding
@@ -2499,8 +2564,8 @@ async function sendHttpRequest(opts) {
2499
2564
  let bodyData;
2500
2565
  if (opts.method === "POST" || opts.method === "PUT") {
2501
2566
  _invariant2.default.call(void 0, opts.body !== void 0, "missing body");
2502
- contentType = _chunk2BIRGEIUcjs.contentTypeForEncoding.call(void 0, opts.encoding);
2503
- bodyData = _chunk2BIRGEIUcjs.serializeWithEncoding.call(void 0,
2567
+ contentType = _chunkIBEFA6CXcjs.contentTypeForEncoding.call(void 0, opts.encoding);
2568
+ bodyData = _chunkIBEFA6CXcjs.serializeWithEncoding.call(void 0,
2504
2569
  opts.encoding,
2505
2570
  opts.body,
2506
2571
  opts.requestVersionedDataHandler,
@@ -2520,7 +2585,7 @@ async function sendHttpRequest(opts) {
2520
2585
  ...contentType ? {
2521
2586
  "Content-Type": contentType
2522
2587
  } : {},
2523
- "User-Agent": _chunk2BIRGEIUcjs.httpUserAgent.call(void 0, )
2588
+ "User-Agent": _chunkIBEFA6CXcjs.httpUserAgent.call(void 0, )
2524
2589
  },
2525
2590
  body: bodyData,
2526
2591
  credentials: "include",
@@ -2538,7 +2603,7 @@ async function sendHttpRequest(opts) {
2538
2603
  const rayId = response.headers.get("x-rivet-ray-id");
2539
2604
  const encoding = (contentType2 == null ? void 0 : contentType2.includes("application/json")) ? "json" : opts.encoding;
2540
2605
  try {
2541
- const responseData = _chunk2BIRGEIUcjs.deserializeWithEncoding.call(void 0,
2606
+ const responseData = _chunkIBEFA6CXcjs.deserializeWithEncoding.call(void 0,
2542
2607
  encoding,
2543
2608
  new Uint8Array(bufferResponse),
2544
2609
  HTTP_RESPONSE_ERROR_VERSIONED,
@@ -2556,7 +2621,7 @@ async function sendHttpRequest(opts) {
2556
2621
  group: bare5.group,
2557
2622
  code: bare5.code,
2558
2623
  message: bare5.message,
2559
- metadata: bare5.metadata ? _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.metadata)) : void 0,
2624
+ metadata: bare5.metadata ? _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.metadata)) : void 0,
2560
2625
  actor: bare5.actor ? {
2561
2626
  actorId: bare5.actor.actorId,
2562
2627
  generation: Number(bare5.actor.generation),
@@ -2564,7 +2629,7 @@ async function sendHttpRequest(opts) {
2564
2629
  } : void 0
2565
2630
  })
2566
2631
  );
2567
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
2632
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
2568
2633
  msg: "http error response",
2569
2634
  group: responseData.group,
2570
2635
  code: responseData.code,
@@ -2611,7 +2676,7 @@ ${textResponse}`
2611
2676
  }
2612
2677
  try {
2613
2678
  const buffer = new Uint8Array(await response.arrayBuffer());
2614
- return _chunk2BIRGEIUcjs.deserializeWithEncoding.call(void 0,
2679
+ return _chunkIBEFA6CXcjs.deserializeWithEncoding.call(void 0,
2615
2680
  opts.encoding,
2616
2681
  buffer,
2617
2682
  opts.responseVersionedDataHandler,
@@ -2659,8 +2724,8 @@ function createQueueSender(senderOptions) {
2659
2724
  }),
2660
2725
  requestToBare: (value) => ({
2661
2726
  name: _nullishCoalesce(value.name, () => ( name)),
2662
- body: _chunk2BIRGEIUcjs.bufferToArrayBuffer.call(void 0,
2663
- _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0, value.body)
2727
+ body: _chunkIBEFA6CXcjs.bufferToArrayBuffer.call(void 0,
2728
+ _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0, value.body)
2664
2729
  ),
2665
2730
  wait: _nullishCoalesce(value.wait, () => ( false)),
2666
2731
  timeout: value.timeout !== void 0 ? BigInt(value.timeout) : null
@@ -2680,7 +2745,7 @@ function createQueueSender(senderOptions) {
2680
2745
  }
2681
2746
  return {
2682
2747
  status: bare5.status,
2683
- response: _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.response))
2748
+ response: _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.response))
2684
2749
  };
2685
2750
  }
2686
2751
  });
@@ -2747,7 +2812,7 @@ async function rawHttpFetch(driver, target, params, input, init, options = {}, t
2747
2812
  throw new TypeError("Invalid input type for fetch");
2748
2813
  }
2749
2814
  try {
2750
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug(
2815
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug(
2751
2816
  "directId" in target ? {
2752
2817
  msg: "sending raw http request to actor",
2753
2818
  actorId: target.directId
@@ -2773,7 +2838,7 @@ async function rawHttpFetch(driver, target, params, input, init, options = {}, t
2773
2838
  });
2774
2839
  return driver.sendRequest(target, proxyRequest, options);
2775
2840
  } catch (err) {
2776
- const { group, code, message, metadata, rayId, actor } = _chunk2BIRGEIUcjs.deconstructError.call(void 0, err, true);
2841
+ const { group, code, message, metadata, rayId, actor } = _chunkIBEFA6CXcjs.deconstructError.call(void 0, err, true);
2777
2842
  throw new (0, _chunkMGI2VVF6cjs.RivetError)(group, code, message, { metadata, rayId, actor });
2778
2843
  }
2779
2844
  }
@@ -2794,7 +2859,7 @@ async function rawWebSocket(driver, target, params, path, _protocols, options =
2794
2859
  }
2795
2860
  }
2796
2861
  const fullPath = `${PATH_WEBSOCKET_PREFIX}${pathPortion}${queryPortion}`;
2797
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
2862
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
2798
2863
  msg: "opening websocket",
2799
2864
  target,
2800
2865
  encoding,
@@ -2868,6 +2933,7 @@ var ActorHandleRaw = class {
2868
2933
  #queueSendMutex = new (0, _chunkKVFIONKQcjs.AsyncMutex)();
2869
2934
  #currentActorInvocation;
2870
2935
  #startCallSpan;
2936
+ #retryBudget;
2871
2937
  /**
2872
2938
  * Do not call this directly.
2873
2939
  *
@@ -2875,7 +2941,7 @@ var ActorHandleRaw = class {
2875
2941
  *
2876
2942
  * @protected
2877
2943
  */
2878
- constructor(client, driver, params, getParams, encoding, actorResolutionState, gatewayOptions = {}, signal, currentActorInvocation, startCallSpan) {
2944
+ constructor(client, driver, params, getParams, encoding, actorResolutionState, gatewayOptions = {}, signal, currentActorInvocation, startCallSpan, retryBudget = new RetryBudget()) {
2879
2945
  this.#client = client;
2880
2946
  this.#driver = driver;
2881
2947
  this.#encoding = encoding;
@@ -2886,6 +2952,7 @@ var ActorHandleRaw = class {
2886
2952
  this.#signal = signal;
2887
2953
  this.#currentActorInvocation = currentActorInvocation;
2888
2954
  this.#startCallSpan = startCallSpan;
2955
+ this.#retryBudget = retryBudget;
2889
2956
  }
2890
2957
  async #resolveConnectionParams() {
2891
2958
  if (this.#getParams) {
@@ -2902,6 +2969,7 @@ var ActorHandleRaw = class {
2902
2969
  let useQueryTarget = isDynamicActorQuery(
2903
2970
  this.#actorResolutionState
2904
2971
  );
2972
+ this.#retryBudget.deposit();
2905
2973
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
2906
2974
  let actorId;
2907
2975
  try {
@@ -2931,15 +2999,24 @@ var ActorHandleRaw = class {
2931
2999
  }
2932
3000
  }).send(name, body, options);
2933
3001
  } catch (err) {
2934
- const { group, code, message, metadata, rayId, actor } = _chunk2BIRGEIUcjs.deconstructError.call(void 0, err, true);
3002
+ const { group, code, message, metadata, rayId, actor } = _chunkIBEFA6CXcjs.deconstructError.call(void 0, err, true);
2935
3003
  if (this.#shouldRetryQueueDispatchOverload(
2936
3004
  group,
2937
3005
  code,
2938
3006
  metadata,
2939
3007
  attempt,
2940
3008
  maxAttempts
2941
- )) {
2942
- await this.#waitForRetryWindow();
3009
+ ) && this.#retryBudget.tryWithdraw()) {
3010
+ await new Promise(
3011
+ (resolve) => setTimeout(
3012
+ resolve,
3013
+ retryDelayMs(attempt, {
3014
+ initialDelayMs: 25,
3015
+ maxDelayMs: 1e3,
3016
+ hintMs: retryAfterMs(err)
3017
+ })
3018
+ )
3019
+ );
2943
3020
  continue;
2944
3021
  }
2945
3022
  if (await this.#shouldRetrySchedulingError(
@@ -3016,7 +3093,10 @@ var ActorHandleRaw = class {
3016
3093
  if (opts.name === "destroy") {
3017
3094
  return await run();
3018
3095
  }
3019
- return await retryOnLifecycleBoundary(run, { signal });
3096
+ return await retryOnLifecycleBoundary(run, {
3097
+ signal,
3098
+ budget: this.#retryBudget
3099
+ });
3020
3100
  };
3021
3101
  if (!call) {
3022
3102
  return await send();
@@ -3046,13 +3126,13 @@ var ActorHandleRaw = class {
3046
3126
  gatewayOptions
3047
3127
  );
3048
3128
  actorId = "directId" in target ? target.directId : void 0;
3049
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug(
3129
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug(
3050
3130
  actorId ? { msg: "using direct actor gateway target", actorId } : {
3051
3131
  msg: "using query gateway target for action",
3052
3132
  query: this.#actorResolutionState
3053
3133
  }
3054
3134
  );
3055
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3135
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3056
3136
  msg: "handling action",
3057
3137
  name: opts.name,
3058
3138
  encoding: this.#encoding
@@ -3089,19 +3169,19 @@ var ActorHandleRaw = class {
3089
3169
  args
3090
3170
  }),
3091
3171
  requestToBare: (args) => ({
3092
- args: _chunk2BIRGEIUcjs.bufferToArrayBuffer.call(void 0,
3093
- _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0, args)
3172
+ args: _chunkIBEFA6CXcjs.bufferToArrayBuffer.call(void 0,
3173
+ _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0, args)
3094
3174
  )
3095
3175
  }),
3096
3176
  responseFromJson: (json) => json.output,
3097
- responseFromBare: (bare5) => _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.output))
3177
+ responseFromBare: (bare5) => _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.output))
3098
3178
  });
3099
3179
  if (opts.name === "destroy" && actorId) {
3100
3180
  await this.#waitForDestroyActionToSettle(actorId);
3101
3181
  }
3102
3182
  return output;
3103
3183
  } catch (err) {
3104
- const { group, code, message, metadata, rayId, actor } = _chunk2BIRGEIUcjs.deconstructError.call(void 0, err, true);
3184
+ const { group, code, message, metadata, rayId, actor } = _chunkIBEFA6CXcjs.deconstructError.call(void 0, err, true);
3105
3185
  if (await this.#shouldRetrySchedulingError(
3106
3186
  group,
3107
3187
  code,
@@ -3257,7 +3337,7 @@ var ActorHandleRaw = class {
3257
3337
  * @returns {ActorConn<AD>} A connection to the actor.
3258
3338
  */
3259
3339
  connect(params, options = {}) {
3260
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3340
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3261
3341
  msg: "establishing connection from handle",
3262
3342
  query: this.#actorResolutionState
3263
3343
  });
@@ -3334,7 +3414,7 @@ var ActorHandleRaw = class {
3334
3414
  }
3335
3415
  return response;
3336
3416
  } catch (err) {
3337
- const { group, code, message, metadata, rayId, actor } = _chunk2BIRGEIUcjs.deconstructError.call(void 0, err, true);
3417
+ const { group, code, message, metadata, rayId, actor } = _chunkIBEFA6CXcjs.deconstructError.call(void 0, err, true);
3338
3418
  if (await this.#shouldRetrySchedulingError(
3339
3419
  group,
3340
3420
  code,
@@ -3430,7 +3510,7 @@ var ActorHandleRaw = class {
3430
3510
  const contentType = response.headers.get("content-type");
3431
3511
  const encoding = (contentType == null ? void 0 : contentType.includes("application/json")) ? "json" : this.#encoding;
3432
3512
  try {
3433
- const error = _chunk2BIRGEIUcjs.deserializeWithEncoding.call(void 0,
3513
+ const error = _chunkIBEFA6CXcjs.deserializeWithEncoding.call(void 0,
3434
3514
  encoding,
3435
3515
  new Uint8Array(await response.clone().arrayBuffer()),
3436
3516
  HTTP_RESPONSE_ERROR_VERSIONED,
@@ -3446,7 +3526,7 @@ var ActorHandleRaw = class {
3446
3526
  group: bare5.group,
3447
3527
  code: bare5.code,
3448
3528
  message: bare5.message,
3449
- metadata: bare5.metadata ? _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.metadata)) : void 0,
3529
+ metadata: bare5.metadata ? _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0, new Uint8Array(bare5.metadata)) : void 0,
3450
3530
  actor: bare5.actor ? {
3451
3531
  actorId: bare5.actor.actorId,
3452
3532
  generation: Number(bare5.actor.generation),
@@ -3558,6 +3638,7 @@ var ClientRaw = (_class = class {
3558
3638
  #gatewayOptions;
3559
3639
  #currentActorInvocation;
3560
3640
  #startCallSpan;
3641
+ #retryBudget;
3561
3642
  /**
3562
3643
  * Creates an instance of Client.
3563
3644
  */
@@ -3570,6 +3651,7 @@ var ClientRaw = (_class = class {
3570
3651
  this.#gatewayOptions = _nullishCoalesce(options.gateway, () => ( {}));
3571
3652
  this.#currentActorInvocation = options.currentActorInvocation;
3572
3653
  this.#startCallSpan = options.startCallSpan;
3654
+ this.#retryBudget = new RetryBudget(options.retryBudget);
3573
3655
  }
3574
3656
  /**
3575
3657
  * Gets a stateless handle to a actor by its ID.
@@ -3581,7 +3663,7 @@ var ClientRaw = (_class = class {
3581
3663
  * @returns {ActorHandle<AD>} - A handle to the actor.
3582
3664
  */
3583
3665
  getForId(name, actorId, opts) {
3584
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3666
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3585
3667
  msg: "get handle to actor with id",
3586
3668
  name,
3587
3669
  actorId,
@@ -3612,7 +3694,7 @@ var ClientRaw = (_class = class {
3612
3694
  */
3613
3695
  get(name, key, opts) {
3614
3696
  const keyArray = typeof key === "string" ? [key] : key || [];
3615
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3697
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3616
3698
  msg: "get handle to actor",
3617
3699
  name,
3618
3700
  key: keyArray,
@@ -3643,7 +3725,7 @@ var ClientRaw = (_class = class {
3643
3725
  */
3644
3726
  getOrCreate(name, key, opts) {
3645
3727
  const keyArray = typeof key === "string" ? [key] : key || [];
3646
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3728
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3647
3729
  msg: "get or create handle to actor",
3648
3730
  name,
3649
3731
  key: keyArray,
@@ -3687,7 +3769,7 @@ var ClientRaw = (_class = class {
3687
3769
  key: keyArray
3688
3770
  }
3689
3771
  };
3690
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3772
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3691
3773
  msg: "create actor handle",
3692
3774
  name,
3693
3775
  key: keyArray,
@@ -3695,7 +3777,7 @@ var ClientRaw = (_class = class {
3695
3777
  create: createQuery.create
3696
3778
  });
3697
3779
  const actorId = await resolveGatewayTarget(this.#driver, createQuery);
3698
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
3780
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
3699
3781
  msg: "created actor with ID",
3700
3782
  name,
3701
3783
  key: keyArray,
@@ -3727,7 +3809,8 @@ var ClientRaw = (_class = class {
3727
3809
  this.#gatewayOptions,
3728
3810
  signal,
3729
3811
  this.#currentActorInvocation,
3730
- this.#startCallSpan
3812
+ this.#startCallSpan,
3813
+ this.#retryBudget
3731
3814
  );
3732
3815
  }
3733
3816
  [CREATE_ACTOR_CONN_PROXY](conn) {
@@ -3742,11 +3825,11 @@ var ClientRaw = (_class = class {
3742
3825
  */
3743
3826
  async dispose() {
3744
3827
  if (this.#disposed) {
3745
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({ msg: "client already disconnected" });
3828
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({ msg: "client already disconnected" });
3746
3829
  return;
3747
3830
  }
3748
3831
  this.#disposed = true;
3749
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({ msg: "disposing client" });
3832
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({ msg: "disposing client" });
3750
3833
  const disposePromises = [];
3751
3834
  for (const conn of this[ACTOR_CONNS_SYMBOL].values()) {
3752
3835
  disposePromises.push(conn.dispose());
@@ -3927,6 +4010,10 @@ function jwtExpiration(token) {
3927
4010
  }
3928
4011
 
3929
4012
  // src/client/actor-conn.ts
4013
+ var CONNECT_TIMEOUT_MS = 2e4;
4014
+ function isConnectionOpenTimeout(error) {
4015
+ return error instanceof _chunkMGI2VVF6cjs.RivetError && error.group === "client" && error.code === "connection_open_timeout";
4016
+ }
3930
4017
  var CONNECT_SYMBOL = /* @__PURE__ */ Symbol("connect");
3931
4018
  var ActorConnRaw = class {
3932
4019
  #disposed = false;
@@ -3954,6 +4041,8 @@ var ActorConnRaw = class {
3954
4041
  #keepNodeAliveInterval;
3955
4042
  /** Promise used to indicate the socket has connected successfully. This will be rejected if the connection fails. */
3956
4043
  #onOpenPromise;
4044
+ /** Sockets given up on by the connect timeout. Their late events are ignored. */
4045
+ #abandonedSockets = /* @__PURE__ */ new WeakSet();
3957
4046
  #websocket;
3958
4047
  #authRetryAvailable = true;
3959
4048
  #client;
@@ -3984,8 +4073,8 @@ var ActorConnRaw = class {
3984
4073
  if ("getForId" in actorResolutionState) {
3985
4074
  this.#actorId = actorResolutionState.getForId.actorId;
3986
4075
  }
3987
- this.#readyPromise = _chunk2BIRGEIUcjs.promiseWithResolvers.call(void 0,
3988
- (reason) => _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4076
+ this.#readyPromise = _chunkIBEFA6CXcjs.promiseWithResolvers.call(void 0,
4077
+ (reason) => _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
3989
4078
  msg: "unhandled ready promise rejection",
3990
4079
  reason
3991
4080
  })
@@ -4052,11 +4141,11 @@ var ActorConnRaw = class {
4052
4141
  `Invalid action call: expected an options object { name, args }, got ${typeof opts}. Use conn.actionName(...args) for the shorthand API.`
4053
4142
  );
4054
4143
  }
4055
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({ msg: "action", name: opts.name, args: opts.args });
4144
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({ msg: "action", name: opts.name, args: opts.args });
4056
4145
  const actionId = this.#actionIdCounter;
4057
4146
  this.#actionIdCounter += 1;
4058
- const { promise, resolve, reject } = _chunk2BIRGEIUcjs.promiseWithResolvers.call(void 0,
4059
- (reason) => _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4147
+ const { promise, resolve, reject } = _chunkIBEFA6CXcjs.promiseWithResolvers.call(void 0,
4148
+ (reason) => _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4060
4149
  msg: "unhandled action promise rejection",
4061
4150
  reason
4062
4151
  })
@@ -4066,7 +4155,7 @@ var ActorConnRaw = class {
4066
4155
  resolve,
4067
4156
  reject
4068
4157
  });
4069
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4158
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4070
4159
  msg: "added action to in-flight map",
4071
4160
  actionId,
4072
4161
  actionName: opts.name,
@@ -4106,9 +4195,9 @@ var ActorConnRaw = class {
4106
4195
  try {
4107
4196
  handler(status);
4108
4197
  } catch (err) {
4109
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4198
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4110
4199
  msg: "error in status change handler",
4111
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4200
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4112
4201
  });
4113
4202
  }
4114
4203
  }
@@ -4118,9 +4207,9 @@ var ActorConnRaw = class {
4118
4207
  try {
4119
4208
  handler();
4120
4209
  } catch (err) {
4121
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4210
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4122
4211
  msg: "error in open handler",
4123
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4212
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4124
4213
  });
4125
4214
  }
4126
4215
  }
@@ -4130,9 +4219,9 @@ var ActorConnRaw = class {
4130
4219
  try {
4131
4220
  handler();
4132
4221
  } catch (err) {
4133
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4222
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4134
4223
  msg: "error in close handler",
4135
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4224
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4136
4225
  });
4137
4226
  }
4138
4227
  }
@@ -4144,22 +4233,26 @@ var ActorConnRaw = class {
4144
4233
  forever: true,
4145
4234
  minTimeout: 250,
4146
4235
  maxTimeout: 3e4,
4147
- onFailedAttempt: (error) => {
4148
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4236
+ onFailedAttempt: async (error) => {
4237
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4149
4238
  msg: "failed to reconnect",
4150
4239
  attempt: error.attemptNumber,
4151
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, error)
4240
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, error)
4152
4241
  });
4242
+ const hintMs = retryAfterMs(error);
4243
+ if (hintMs !== void 0) {
4244
+ await new Promise((resolve) => setTimeout(resolve, hintMs));
4245
+ }
4153
4246
  },
4154
4247
  // Cancel retry if aborted
4155
4248
  signal: this.#abortController.signal
4156
4249
  }).catch((err) => {
4157
4250
  if (err instanceof _pretry.AbortError || err.name === "AbortError" || !this.#shouldRetryConnectionOpenError(err)) {
4158
- _chunk5SN6GAYXcjs.logger.call(void 0, ).info({ msg: "connection retry aborted" });
4251
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).info({ msg: "connection retry aborted" });
4159
4252
  } else {
4160
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4253
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4161
4254
  msg: "unexpected error in connection retry",
4162
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4255
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4163
4256
  });
4164
4257
  }
4165
4258
  });
@@ -4168,14 +4261,14 @@ var ActorConnRaw = class {
4168
4261
  try {
4169
4262
  if (this.#onOpenPromise)
4170
4263
  throw new Error("#onOpenPromise already defined");
4171
- this.#onOpenPromise = _chunk2BIRGEIUcjs.promiseWithResolvers.call(void 0,
4172
- (reason) => _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4264
+ this.#onOpenPromise = _chunkIBEFA6CXcjs.promiseWithResolvers.call(void 0,
4265
+ (reason) => _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4173
4266
  msg: "unhandled open promise rejection",
4174
4267
  reason
4175
4268
  })
4176
4269
  );
4177
4270
  await this.#connectWebSocket();
4178
- await this.#onOpenPromise.promise;
4271
+ await this.#waitForOpen(this.#onOpenPromise.promise);
4179
4272
  } catch (error) {
4180
4273
  if (this.#shouldRetryConnectionOpenError(error)) {
4181
4274
  throw error;
@@ -4183,24 +4276,77 @@ var ActorConnRaw = class {
4183
4276
  const actorError = error instanceof _chunkMGI2VVF6cjs.RivetError ? error : new (0, _chunkMGI2VVF6cjs.RivetError)(
4184
4277
  "client",
4185
4278
  "connection_open_failed",
4186
- `Failed to open connection: ${_chunk2BIRGEIUcjs.stringifyError.call(void 0, error)}`,
4187
- { error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, error) }
4279
+ `Failed to open connection: ${_chunkIBEFA6CXcjs.stringifyError.call(void 0, error)}`,
4280
+ { error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, error) }
4188
4281
  );
4189
4282
  this.#clearQueuedMessages();
4190
4283
  this.#rejectPendingPromises(actorError, false);
4191
4284
  this.#dispatchActorError(actorError);
4192
4285
  this.#setConnStatus("idle");
4193
4286
  throw new (0, _pretry.AbortError)(
4194
- error instanceof Error ? error : new Error(_chunk2BIRGEIUcjs.stringifyError.call(void 0, error))
4287
+ error instanceof Error ? error : new Error(_chunkIBEFA6CXcjs.stringifyError.call(void 0, error))
4195
4288
  );
4196
4289
  } finally {
4197
4290
  this.#onOpenPromise = void 0;
4198
4291
  }
4199
4292
  }
4293
+ /**
4294
+ * Waits for the actor's Init on the current socket, up to {@link CONNECT_TIMEOUT_MS}. A socket
4295
+ * can stay connecting with no open, error or close event, as when the engine holds the
4296
+ * upgrade or a refused connect reports only an error. On timeout the socket is abandoned
4297
+ * and closed, and the retryable `client.connection_open_timeout` starts the next attempt.
4298
+ */
4299
+ async #waitForOpen(open) {
4300
+ let timer;
4301
+ const timedOut = new Promise((_, reject) => {
4302
+ timer = setTimeout(() => {
4303
+ reject(
4304
+ new (0, _chunkMGI2VVF6cjs.RivetError)(
4305
+ "client",
4306
+ "connection_open_timeout",
4307
+ `Connection did not open within ${CONNECT_TIMEOUT_MS} ms`
4308
+ )
4309
+ );
4310
+ }, CONNECT_TIMEOUT_MS);
4311
+ });
4312
+ try {
4313
+ await Promise.race([open, timedOut]);
4314
+ } catch (error) {
4315
+ if (isConnectionOpenTimeout(error)) {
4316
+ this.#abandonCurrentSocket();
4317
+ }
4318
+ throw error;
4319
+ } finally {
4320
+ clearTimeout(timer);
4321
+ }
4322
+ }
4323
+ #abandonCurrentSocket() {
4324
+ const ws = this.#websocket;
4325
+ if (!ws) return;
4326
+ this.#websocket = void 0;
4327
+ this.#abandonedSockets.add(ws);
4328
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4329
+ msg: "connection did not open in time, retrying",
4330
+ connId: this.#connId,
4331
+ readyState: ws.readyState,
4332
+ timeoutMs: CONNECT_TIMEOUT_MS
4333
+ });
4334
+ try {
4335
+ ws.close(1e3, "Connect timeout");
4336
+ } catch (err) {
4337
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4338
+ msg: "failed to close abandoned websocket",
4339
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4340
+ });
4341
+ }
4342
+ }
4200
4343
  #shouldRetryConnectionOpenError(error) {
4201
4344
  if (error instanceof ActorConnDisposed) {
4202
4345
  return false;
4203
4346
  }
4347
+ if (isConnectionOpenTimeout(error)) {
4348
+ return true;
4349
+ }
4204
4350
  if (error instanceof _chunkMGI2VVF6cjs.RivetError && isInvalidToken(error.group, error.code) && this.#driver.refreshAuthToken && this.#authRetryAvailable) {
4205
4351
  this.#authRetryAvailable = false;
4206
4352
  return true;
@@ -4215,7 +4361,7 @@ var ActorConnRaw = class {
4215
4361
  }
4216
4362
  #clearQueuedMessages() {
4217
4363
  if (this.#messageQueue.length === 0) return;
4218
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4364
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4219
4365
  msg: "clearing queued connection messages",
4220
4366
  queueLength: this.#messageQueue.length
4221
4367
  });
@@ -4228,7 +4374,7 @@ var ActorConnRaw = class {
4228
4374
  try {
4229
4375
  return await this.#getParams();
4230
4376
  } catch (err) {
4231
- const errorMessage = _chunk2BIRGEIUcjs.stringifyError.call(void 0, err);
4377
+ const errorMessage = _chunkIBEFA6CXcjs.stringifyError.call(void 0, err);
4232
4378
  const error = new (0, _chunkMGI2VVF6cjs.RivetError)(
4233
4379
  "client",
4234
4380
  "get_params_failed",
@@ -4252,7 +4398,7 @@ var ActorConnRaw = class {
4252
4398
  this.#gatewayOptions
4253
4399
  );
4254
4400
  _invariant2.default.call(void 0, ws, "websocket should have been created");
4255
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4401
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4256
4402
  msg: "opened websocket",
4257
4403
  connId: this.#connId,
4258
4404
  readyState: ws.readyState,
@@ -4260,38 +4406,42 @@ var ActorConnRaw = class {
4260
4406
  });
4261
4407
  this.#websocket = ws;
4262
4408
  ws.addEventListener("open", () => {
4263
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4409
+ if (this.#abandonedSockets.has(ws)) return;
4410
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4264
4411
  msg: "client websocket open",
4265
4412
  connId: this.#connId
4266
4413
  });
4267
4414
  });
4268
4415
  ws.addEventListener("message", async (ev) => {
4416
+ if (this.#abandonedSockets.has(ws)) return;
4269
4417
  try {
4270
4418
  await this.#handleOnMessage(ev.data);
4271
4419
  } catch (err) {
4272
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4420
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4273
4421
  msg: "error in websocket message handler",
4274
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4422
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4275
4423
  });
4276
4424
  }
4277
4425
  });
4278
4426
  ws.addEventListener("close", async (ev) => {
4427
+ if (this.#abandonedSockets.has(ws)) return;
4279
4428
  try {
4280
4429
  await this.#handleOnClose(ev);
4281
4430
  } catch (err) {
4282
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4431
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4283
4432
  msg: "error in websocket close handler",
4284
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4433
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4285
4434
  });
4286
4435
  }
4287
4436
  });
4288
4437
  ws.addEventListener("error", () => {
4438
+ if (this.#abandonedSockets.has(ws)) return;
4289
4439
  try {
4290
4440
  this.#handleOnError();
4291
4441
  } catch (err) {
4292
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4442
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4293
4443
  msg: "error in websocket error handler",
4294
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4444
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4295
4445
  });
4296
4446
  }
4297
4447
  });
@@ -4299,7 +4449,7 @@ var ActorConnRaw = class {
4299
4449
  /** Called by the onopen event from drivers. */
4300
4450
  #handleOnOpen() {
4301
4451
  if (this.#disposed) {
4302
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4452
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4303
4453
  msg: "handleOnOpen called after dispose, closing websocket"
4304
4454
  });
4305
4455
  if (this.#websocket) {
@@ -4315,7 +4465,7 @@ var ActorConnRaw = class {
4315
4465
  queueMicrotask(() => {
4316
4466
  this.#openScheduled = false;
4317
4467
  if (this.#disposed) {
4318
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4468
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4319
4469
  msg: "handleOnOpen scheduled after dispose, closing websocket"
4320
4470
  });
4321
4471
  if (this.#websocket) {
@@ -4324,7 +4474,7 @@ var ActorConnRaw = class {
4324
4474
  }
4325
4475
  return;
4326
4476
  }
4327
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4477
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4328
4478
  msg: "socket open",
4329
4479
  messageQueueLength: this.#messageQueue.length,
4330
4480
  connId: this.#connId
@@ -4334,14 +4484,14 @@ var ActorConnRaw = class {
4334
4484
  if (this.#onOpenPromise) {
4335
4485
  this.#onOpenPromise.resolve(void 0);
4336
4486
  } else {
4337
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({ msg: "#onOpenPromise is undefined" });
4487
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({ msg: "#onOpenPromise is undefined" });
4338
4488
  }
4339
4489
  for (const eventName of this.#eventSubscriptions.keys()) {
4340
4490
  this.#sendSubscription(eventName, true);
4341
4491
  }
4342
4492
  const queue = this.#messageQueue;
4343
4493
  this.#messageQueue = [];
4344
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4494
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4345
4495
  msg: "flushing message queue",
4346
4496
  queueLength: queue.length
4347
4497
  });
@@ -4353,23 +4503,23 @@ var ActorConnRaw = class {
4353
4503
  /** Called by the onmessage event from drivers. */
4354
4504
  async #handleOnMessage(data) {
4355
4505
  var _a;
4356
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace({
4506
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace({
4357
4507
  msg: "received message",
4358
4508
  dataType: typeof data,
4359
4509
  isBlob: data instanceof Blob,
4360
4510
  isArrayBuffer: data instanceof ArrayBuffer
4361
4511
  });
4362
4512
  const response = await this.#parseMessage(data);
4363
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace(
4364
- _chunk2BIRGEIUcjs.getLogMessage.call(void 0, ) ? {
4513
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace(
4514
+ _chunkIBEFA6CXcjs.getLogMessage.call(void 0, ) ? {
4365
4515
  msg: "parsed message",
4366
- message: _chunk2BIRGEIUcjs.jsonStringifyCompat.call(void 0, response).substring(0, 100) + "..."
4516
+ message: _chunkIBEFA6CXcjs.jsonStringifyCompat.call(void 0, response).substring(0, 100) + "..."
4367
4517
  } : { msg: "parsed message" }
4368
4518
  );
4369
4519
  if (response.body.tag === "Init") {
4370
4520
  this.#actorId = response.body.val.actorId;
4371
4521
  this.#connId = response.body.val.connectionId;
4372
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace({
4522
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace({
4373
4523
  msg: "received init message",
4374
4524
  actorId: this.#actorId,
4375
4525
  connId: this.#connId
@@ -4380,7 +4530,7 @@ var ActorConnRaw = class {
4380
4530
  if (actionId !== null) {
4381
4531
  const inFlight = this.#takeActionInFlight(Number(actionId));
4382
4532
  this.#invalidateActorIfStale(group, code);
4383
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4533
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4384
4534
  msg: "action error",
4385
4535
  actionId,
4386
4536
  actionName: inFlight == null ? void 0 : inFlight.name,
@@ -4399,7 +4549,7 @@ var ActorConnRaw = class {
4399
4549
  })
4400
4550
  );
4401
4551
  } else {
4402
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4552
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4403
4553
  msg: "connection error",
4404
4554
  group,
4405
4555
  code,
@@ -4447,27 +4597,27 @@ var ActorConnRaw = class {
4447
4597
  }
4448
4598
  } else if (response.body.tag === "ActionResponse") {
4449
4599
  const { id: actionId } = response.body.val;
4450
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4600
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4451
4601
  msg: "received action response",
4452
4602
  actionId: Number(actionId),
4453
4603
  inFlightCount: this.#actionsInFlight.size,
4454
4604
  inFlightIds: Array.from(this.#actionsInFlight.keys())
4455
4605
  });
4456
4606
  const inFlight = this.#takeActionInFlight(Number(actionId));
4457
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace({
4607
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace({
4458
4608
  msg: "resolving action promise",
4459
4609
  actionId,
4460
4610
  actionName: inFlight == null ? void 0 : inFlight.name
4461
4611
  });
4462
4612
  inFlight.resolve(response.body.val);
4463
4613
  } else if (response.body.tag === "Event") {
4464
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace({
4614
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace({
4465
4615
  msg: "received event",
4466
4616
  name: response.body.val.name
4467
4617
  });
4468
4618
  this.#dispatchEvent(response.body.val);
4469
4619
  } else {
4470
- _chunk2BIRGEIUcjs.assertUnreachable.call(void 0, response.body);
4620
+ _chunkIBEFA6CXcjs.assertUnreachable.call(void 0, response.body);
4471
4621
  }
4472
4622
  }
4473
4623
  /** Called by the onclose event from drivers. */
@@ -4477,7 +4627,7 @@ var ActorConnRaw = class {
4477
4627
  const closeEvent = event;
4478
4628
  const wasClean = closeEvent.wasClean;
4479
4629
  const wasConnected = this.#connStatus === "connected";
4480
- _chunk5SN6GAYXcjs.logger.call(void 0, ).info({
4630
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).info({
4481
4631
  msg: "socket closed",
4482
4632
  code: closeEvent.code,
4483
4633
  reason: closeEvent.reason,
@@ -4494,7 +4644,8 @@ var ActorConnRaw = class {
4494
4644
  const reason = closeEvent.reason || "";
4495
4645
  const parsed = parseWebSocketCloseReason(reason);
4496
4646
  if (parsed) {
4497
- const { group, code, rayId } = parsed;
4647
+ const { group, code, rayId, retryAfterMs: retryAfterMs2 } = parsed;
4648
+ const closeOptions = retryAfterMs2 === void 0 ? { rayId } : { rayId, metadata: { retry_after_ms: retryAfterMs2 } };
4498
4649
  if (isInvalidToken(group, code) && closeEvent.code === 1008 && failedSocket) {
4499
4650
  try {
4500
4651
  if (!await ((_b = (_a = this.#driver).refreshAuthToken) == null ? void 0 : _b.call(
@@ -4504,7 +4655,7 @@ var ActorConnRaw = class {
4504
4655
  this.#authRetryAvailable = false;
4505
4656
  }
4506
4657
  } catch (e4) {
4507
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn("token renewal failed");
4658
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn("token renewal failed");
4508
4659
  this.#authRetryAvailable = false;
4509
4660
  }
4510
4661
  } else if (isInvalidToken(group, code)) {
@@ -4517,7 +4668,7 @@ var ActorConnRaw = class {
4517
4668
  group,
4518
4669
  code,
4519
4670
  `Connection closed: ${reason}`,
4520
- { rayId }
4671
+ closeOptions
4521
4672
  )
4522
4673
  );
4523
4674
  return;
@@ -4538,7 +4689,7 @@ var ActorConnRaw = class {
4538
4689
  group,
4539
4690
  code,
4540
4691
  `Connection closed: ${reason}`,
4541
- { rayId }
4692
+ closeOptions
4542
4693
  );
4543
4694
  }
4544
4695
  } else {
@@ -4546,7 +4697,7 @@ var ActorConnRaw = class {
4546
4697
  group,
4547
4698
  code,
4548
4699
  `Connection closed: ${reason}`,
4549
- { rayId }
4700
+ closeOptions
4550
4701
  );
4551
4702
  }
4552
4703
  this.#invalidateActorIfStale(group, code);
@@ -4560,7 +4711,7 @@ var ActorConnRaw = class {
4560
4711
  this.#dispatchActorError(error);
4561
4712
  }
4562
4713
  if (wasConnected && this.#authRetryAvailable) {
4563
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4714
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4564
4715
  msg: "triggering reconnect",
4565
4716
  connId: this.#connId
4566
4717
  });
@@ -4584,12 +4735,12 @@ var ActorConnRaw = class {
4584
4735
  /** Called by the onerror event from drivers. */
4585
4736
  #handleOnError() {
4586
4737
  if (this.#disposed) return;
4587
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn("socket error");
4738
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn("socket error");
4588
4739
  }
4589
4740
  #takeActionInFlight(id) {
4590
4741
  const inFlight = this.#actionsInFlight.get(id);
4591
4742
  if (!inFlight) {
4592
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4743
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4593
4744
  msg: "action not found in in-flight map",
4594
4745
  lookupId: id,
4595
4746
  inFlightCount: this.#actionsInFlight.size,
@@ -4604,7 +4755,7 @@ var ActorConnRaw = class {
4604
4755
  throw internalClientError(`No in flight response for ${id}`);
4605
4756
  }
4606
4757
  this.#actionsInFlight.delete(id);
4607
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4758
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4608
4759
  msg: "removed action from in-flight map",
4609
4760
  actionId: id,
4610
4761
  actionName: inFlight.name,
@@ -4631,9 +4782,9 @@ var ActorConnRaw = class {
4631
4782
  try {
4632
4783
  handler(error);
4633
4784
  } catch (err) {
4634
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4785
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4635
4786
  msg: "error in connection error handler",
4636
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4787
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4637
4788
  });
4638
4789
  }
4639
4790
  }
@@ -4738,9 +4889,9 @@ var ActorConnRaw = class {
4738
4889
  try {
4739
4890
  callback();
4740
4891
  } catch (err) {
4741
- _chunk5SN6GAYXcjs.logger.call(void 0, ).error({
4892
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).error({
4742
4893
  msg: "error in open handler",
4743
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, err)
4894
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, err)
4744
4895
  });
4745
4896
  }
4746
4897
  });
@@ -4790,7 +4941,7 @@ var ActorConnRaw = class {
4790
4941
  let queueMessage = false;
4791
4942
  if (this.#websocket) {
4792
4943
  const readyState = this.#websocket.readyState;
4793
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4944
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4794
4945
  msg: "websocket send attempt",
4795
4946
  readyState,
4796
4947
  readyStateString: readyState === 0 ? "CONNECTING" : readyState === 1 ? "OPEN" : readyState === 2 ? "CLOSING" : "CLOSED",
@@ -4799,7 +4950,7 @@ var ActorConnRaw = class {
4799
4950
  actionName: (_a = message.body.val) == null ? void 0 : _a.name
4800
4951
  });
4801
4952
  if (this.#connStatus !== "connected") {
4802
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
4953
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4803
4954
  msg: "websocket init pending, queueing message",
4804
4955
  connStatus: this.#connStatus,
4805
4956
  messageType: message.body.tag
@@ -4807,7 +4958,7 @@ var ActorConnRaw = class {
4807
4958
  queueMessage = true;
4808
4959
  } else if (readyState === 1) {
4809
4960
  try {
4810
- const messageSerialized = _chunk2BIRGEIUcjs.serializeWithEncoding.call(void 0,
4961
+ const messageSerialized = _chunkIBEFA6CXcjs.serializeWithEncoding.call(void 0,
4811
4962
  this.#encoding,
4812
4963
  message,
4813
4964
  CLIENT_PROTOCOL_TO_SERVER,
@@ -4824,8 +4975,8 @@ var ActorConnRaw = class {
4824
4975
  val: {
4825
4976
  id: msg.body.val.id,
4826
4977
  name: msg.body.val.name,
4827
- args: _chunk2BIRGEIUcjs.bufferToArrayBuffer.call(void 0,
4828
- _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0,
4978
+ args: _chunkIBEFA6CXcjs.bufferToArrayBuffer.call(void 0,
4979
+ _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0,
4829
4980
  msg.body.val.args
4830
4981
  )
4831
4982
  )
@@ -4839,12 +4990,12 @@ var ActorConnRaw = class {
4839
4990
  );
4840
4991
  this.#websocket.send(messageSerialized);
4841
4992
  const serializedLength = messageLength(messageSerialized);
4842
- _chunk5SN6GAYXcjs.logger.call(void 0, ).trace({
4993
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).trace({
4843
4994
  msg: "sent websocket message",
4844
4995
  len: serializedLength
4845
4996
  });
4846
4997
  } catch (error) {
4847
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
4998
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
4848
4999
  msg: "failed to send message, added to queue",
4849
5000
  error,
4850
5001
  connId: this.#connId
@@ -4852,19 +5003,19 @@ var ActorConnRaw = class {
4852
5003
  queueMessage = true;
4853
5004
  }
4854
5005
  } else {
4855
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
5006
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4856
5007
  msg: "websocket not open, queueing message",
4857
5008
  readyState
4858
5009
  });
4859
5010
  queueMessage = true;
4860
5011
  }
4861
5012
  } else {
4862
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({ msg: "no websocket, queueing message" });
5013
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({ msg: "no websocket, queueing message" });
4863
5014
  queueMessage = true;
4864
5015
  }
4865
5016
  if (!(opts == null ? void 0 : opts.ephemeral) && queueMessage) {
4866
5017
  this.#messageQueue.push(message);
4867
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({
5018
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({
4868
5019
  msg: "queued connection message",
4869
5020
  queueLength: this.#messageQueue.length,
4870
5021
  connId: this.#connId,
@@ -4875,8 +5026,8 @@ var ActorConnRaw = class {
4875
5026
  }
4876
5027
  async #parseMessage(data) {
4877
5028
  _invariant2.default.call(void 0, this.#websocket, "websocket must be defined");
4878
- const buffer = await _chunk2BIRGEIUcjs.inputDataToBuffer.call(void 0, data);
4879
- return _chunk2BIRGEIUcjs.deserializeWithEncoding.call(void 0,
5029
+ const buffer = await _chunkIBEFA6CXcjs.inputDataToBuffer.call(void 0, data);
5030
+ return _chunkIBEFA6CXcjs.deserializeWithEncoding.call(void 0,
4880
5031
  this.#encoding,
4881
5032
  buffer,
4882
5033
  CLIENT_PROTOCOL_TO_CLIENT,
@@ -4911,7 +5062,7 @@ var ActorConnRaw = class {
4911
5062
  group: msg.body.val.group,
4912
5063
  code: msg.body.val.code,
4913
5064
  message: msg.body.val.message,
4914
- metadata: msg.body.val.metadata ? _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0,
5065
+ metadata: msg.body.val.metadata ? _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0,
4915
5066
  new Uint8Array(
4916
5067
  msg.body.val.metadata
4917
5068
  )
@@ -4933,7 +5084,7 @@ var ActorConnRaw = class {
4933
5084
  tag: "ActionResponse",
4934
5085
  val: {
4935
5086
  id: msg.body.val.id,
4936
- output: _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0,
5087
+ output: _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0,
4937
5088
  new Uint8Array(msg.body.val.output)
4938
5089
  )
4939
5090
  }
@@ -4945,7 +5096,7 @@ var ActorConnRaw = class {
4945
5096
  tag: "Event",
4946
5097
  val: {
4947
5098
  name: msg.body.val.name,
4948
- args: _chunk2BIRGEIUcjs.decodeCborCompat.call(void 0,
5099
+ args: _chunkIBEFA6CXcjs.decodeCborCompat.call(void 0,
4949
5100
  new Uint8Array(msg.body.val.args)
4950
5101
  )
4951
5102
  }
@@ -4986,11 +5137,11 @@ var ActorConnRaw = class {
4986
5137
  */
4987
5138
  async dispose() {
4988
5139
  if (this.#disposed) {
4989
- _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({ msg: "connection already disconnected" });
5140
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({ msg: "connection already disconnected" });
4990
5141
  return;
4991
5142
  }
4992
5143
  this.#disposed = true;
4993
- _chunk5SN6GAYXcjs.logger.call(void 0, ).debug({ msg: "disposing actor conn" });
5144
+ _chunkHW2D5OFJcjs.logger.call(void 0, ).debug({ msg: "disposing actor conn" });
4994
5145
  this.#setConnStatus("idle");
4995
5146
  clearInterval(this.#keepNodeAliveInterval);
4996
5147
  this.#abortController.abort();
@@ -4998,8 +5149,8 @@ var ActorConnRaw = class {
4998
5149
  if (this.#websocket) {
4999
5150
  const ws = this.#websocket;
5000
5151
  if (ws.readyState !== 2 && ws.readyState !== 3) {
5001
- const { promise, resolve } = _chunk2BIRGEIUcjs.promiseWithResolvers.call(void 0,
5002
- (reason) => _chunk5SN6GAYXcjs.logger.call(void 0, ).warn({
5152
+ const { promise, resolve } = _chunkIBEFA6CXcjs.promiseWithResolvers.call(void 0,
5153
+ (reason) => _chunkHW2D5OFJcjs.logger.call(void 0, ).warn({
5003
5154
  msg: "unhandled websocket close promise rejection",
5004
5155
  reason
5005
5156
  })
@@ -5137,7 +5288,7 @@ var ClientConfigSchemaBase = _v42.default.object({
5137
5288
  * Defaults to http://localhost:6420.
5138
5289
  */
5139
5290
  endpoint: _v42.default.string().optional().transform((val) => {
5140
- const resolved = _nullishCoalesce(_nullishCoalesce(val, () => ( _chunk2BIRGEIUcjs.getRivetEngine.call(void 0, ))), () => ( _chunk2BIRGEIUcjs.getRivetEndpoint.call(void 0, )));
5291
+ const resolved = _nullishCoalesce(_nullishCoalesce(val, () => ( _chunkIBEFA6CXcjs.getRivetEngine.call(void 0, ))), () => ( _chunkIBEFA6CXcjs.getRivetEndpoint.call(void 0, )));
5141
5292
  if (!resolved && !hasWarnedMissingEndpoint) {
5142
5293
  hasWarnedMissingEndpoint = true;
5143
5294
  console.warn(
@@ -5147,14 +5298,14 @@ var ClientConfigSchemaBase = _v42.default.object({
5147
5298
  return _nullishCoalesce(resolved, () => ( DEFAULT_ENDPOINT));
5148
5299
  }),
5149
5300
  /** Token to use to authenticate with the API. */
5150
- token: _v42.default.string().optional().transform((val) => _nullishCoalesce(val, () => ( _chunk2BIRGEIUcjs.getRivetToken.call(void 0, )))),
5301
+ token: _v42.default.string().optional().transform((val) => _nullishCoalesce(val, () => ( _chunkIBEFA6CXcjs.getRivetToken.call(void 0, )))),
5151
5302
  /** Issue and renew a client token on demand. Overrides the static token when provided. */
5152
5303
  getToken: _v42.default.custom().optional(),
5153
5304
  /** Namespace to connect to. */
5154
- namespace: _v42.default.string().optional().transform((val) => _nullishCoalesce(val, () => ( _chunk2BIRGEIUcjs.getRivetNamespace.call(void 0, )))),
5305
+ namespace: _v42.default.string().optional().transform((val) => _nullishCoalesce(val, () => ( _chunkIBEFA6CXcjs.getRivetNamespace.call(void 0, )))),
5155
5306
  /** Name of the envoy pool. This is used to group together envoys in to different pools. */
5156
- poolName: _v42.default.string().default(() => _nullishCoalesce(_chunk2BIRGEIUcjs.getRivetPool.call(void 0, ), () => ( "default"))),
5157
- encoding: _chunk2BIRGEIUcjs.EncodingSchema.default("bare"),
5307
+ poolName: _v42.default.string().default(() => _nullishCoalesce(_chunkIBEFA6CXcjs.getRivetPool.call(void 0, ), () => ( "default"))),
5308
+ encoding: _chunkIBEFA6CXcjs.EncodingSchema.default("bare"),
5158
5309
  headers: _v42.default.record(_v42.default.string(), _v42.default.string()).optional().default(() => ({})),
5159
5310
  gateway: _v42.default.object({
5160
5311
  skipReadyWait: _v42.default.boolean().optional().default(false)
@@ -5164,6 +5315,14 @@ var ClientConfigSchemaBase = _v42.default.object({
5164
5315
  // This is required in the client config in order to support
5165
5316
  // `proxyWebSocket`
5166
5317
  getUpgradeWebSocket: _v42.default.custom().optional(),
5318
+ /**
5319
+ * Bounds retries of refused requests: `percent` retries per 100 requests (default 10), with
5320
+ * up to `maxTokens` banked for bursts (default 100). A refusal past the budget is thrown.
5321
+ */
5322
+ retryBudget: _v42.default.object({
5323
+ percent: _v42.default.number().min(0).max(100).optional(),
5324
+ maxTokens: _v42.default.number().int().min(0).optional()
5325
+ }).optional(),
5167
5326
  /** Replaces global fetch for actor HTTP gateway requests. */
5168
5327
  fetch: _v42.default.custom().optional(),
5169
5328
  /** Whether to automatically perform health checks when the client is created. */
@@ -5206,7 +5365,7 @@ function convertRegistryConfigToClientConfig(config) {
5206
5365
  token: config.token,
5207
5366
  getToken: void 0,
5208
5367
  namespace: config.namespace,
5209
- poolName: config.envoy.poolName,
5368
+ poolName: config.node.poolName,
5210
5369
  headers: config.headers,
5211
5370
  gateway: { skipReadyWait: false },
5212
5371
  encoding: "bare",
@@ -5331,7 +5490,7 @@ function setRemoteHibernatableWebSocketAckTestHooks(websocket, token, enabled) {
5331
5490
 
5332
5491
  // src/engine-client/log.ts
5333
5492
  function logger2() {
5334
- return _chunk2BIRGEIUcjs.getLogger.call(void 0, "engine-client");
5493
+ return _chunkIBEFA6CXcjs.getLogger.call(void 0, "engine-client");
5335
5494
  }
5336
5495
 
5337
5496
  // src/engine-client/actor-websocket-client.ts
@@ -5464,7 +5623,7 @@ var BufferedRemoteWebSocket = (_class2 = class {
5464
5623
  function buildActorGatewayUrl(endpoint, actorId, token, path = "") {
5465
5624
  const tokenSegment = token !== void 0 ? `@${encodeURIComponent(token)}` : "";
5466
5625
  const gatewayPath = `/gateway/${encodeURIComponent(actorId)}${tokenSegment}${path}`;
5467
- return _chunk2BIRGEIUcjs.combineUrlPath.call(void 0, endpoint, gatewayPath);
5626
+ return _chunkIBEFA6CXcjs.combineUrlPath.call(void 0, endpoint, gatewayPath);
5468
5627
  }
5469
5628
  function buildActorQueryGatewayUrl(endpoint, namespace, query, token, path = "", maxInputSize = DEFAULT_MAX_QUERY_INPUT_SIZE, crashPolicy = void 0, runnerName, options = {}) {
5470
5629
  if (namespace.length === 0) {
@@ -5530,18 +5689,19 @@ function buildActorQueryGatewayUrl(endpoint, namespace, query, token, path = "",
5530
5689
  separator = "?";
5531
5690
  }
5532
5691
  const gatewayPath = `/gateway/${encodeURIComponent(name)}${path}${separator}${queryString}`;
5533
- return _chunk2BIRGEIUcjs.combineUrlPath.call(void 0, endpoint, gatewayPath);
5692
+ return _chunkIBEFA6CXcjs.combineUrlPath.call(void 0, endpoint, gatewayPath);
5534
5693
  }
5535
5694
  function pushKeyQueryParams(params, key) {
5536
- if (key.length > 0) {
5537
- params.append("rvt-key", key.join(","));
5695
+ const rvtKey = _chunkRTWH3AX3cjs.actorKeyToGatewayQuery.call(void 0, key);
5696
+ if (rvtKey !== void 0) {
5697
+ params.append("rvt-key", rvtKey);
5538
5698
  }
5539
5699
  }
5540
5700
  function pushInputQueryParam(params, input, maxInputSize) {
5541
5701
  if (input === void 0) {
5542
5702
  return;
5543
5703
  }
5544
- const encodedInput = _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0, input);
5704
+ const encodedInput = _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0, input);
5545
5705
  if (encodedInput.byteLength > maxInputSize) {
5546
5706
  throw new Error(
5547
5707
  `Actor query input exceeds maxInputSize (${encodedInput.byteLength} > ${maxInputSize} bytes). Increase client maxInputSize to allow larger query payloads.`
@@ -5550,10 +5710,10 @@ function pushInputQueryParam(params, input, maxInputSize) {
5550
5710
  params.append("rvt-input", uint8ArrayToBase64Url(encodedInput));
5551
5711
  }
5552
5712
  function uint8ArrayToBase64Url(value) {
5553
- return _chunk2BIRGEIUcjs.uint8ArrayToBase64.call(void 0, value).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5713
+ return _chunkIBEFA6CXcjs.uint8ArrayToBase64.call(void 0, value).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5554
5714
  }
5555
5715
  async function openWebSocketToGateway(runConfig, gatewayUrl, encoding, params, options = {}) {
5556
- const WebSocket2 = await _chunk5SN6GAYXcjs.importWebSocket.call(void 0, );
5716
+ const WebSocket2 = await _chunkHW2D5OFJcjs.importWebSocket.call(void 0, );
5557
5717
  const ackHookToken = typeof process !== "undefined" && process.env.VITEST ? crypto.randomUUID() : void 0;
5558
5718
  logger2().debug({
5559
5719
  msg: "opening websocket to actor via guard",
@@ -5621,7 +5781,7 @@ function getEndpoint(config) {
5621
5781
  }
5622
5782
  async function apiCall(config, method, path, body) {
5623
5783
  const endpoint = getEndpoint(config);
5624
- const url = _chunk2BIRGEIUcjs.combineUrlPath.call(void 0, endpoint, path, {
5784
+ const url = _chunkIBEFA6CXcjs.combineUrlPath.call(void 0, endpoint, path, {
5625
5785
  namespace: config.namespace
5626
5786
  });
5627
5787
  logger2().debug({ msg: "making api call", method, url });
@@ -5669,7 +5829,7 @@ async function getActor(config, _, actorId) {
5669
5829
  );
5670
5830
  }
5671
5831
  async function getActorByKey(config, name, key) {
5672
- const serializedKey = _chunkMYWZCDMLcjs.serializeActorKey.call(void 0, key);
5832
+ const serializedKey = _chunkRTWH3AX3cjs.serializeActorKey.call(void 0, key);
5673
5833
  return apiCall(
5674
5834
  config,
5675
5835
  "GET",
@@ -5716,8 +5876,8 @@ async function updateRunnerConfig(config, runnerName, request) {
5716
5876
  return apiCall(
5717
5877
  config,
5718
5878
  "PUT",
5719
- `/runner-configs/${runnerName}`,
5720
- request
5879
+ `/pools/${encodeURIComponent(runnerName)}`,
5880
+ Object.values(request.datacenters)[0]
5721
5881
  );
5722
5882
  }
5723
5883
 
@@ -5754,7 +5914,7 @@ async function lookupMetadataCached(config) {
5754
5914
  msg: "failed to fetch metadata, retrying",
5755
5915
  endpoint,
5756
5916
  attempt: error.attemptNumber,
5757
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, error)
5917
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, error)
5758
5918
  });
5759
5919
  }
5760
5920
  }
@@ -5766,7 +5926,7 @@ async function lookupMetadataCached(config) {
5766
5926
 
5767
5927
  // src/engine-client/ws-proxy.ts
5768
5928
  async function createWebSocketProxy(_c, targetUrl, protocols) {
5769
- const WebSocket2 = await _chunk5SN6GAYXcjs.importWebSocket.call(void 0, );
5929
+ const WebSocket2 = await _chunkHW2D5OFJcjs.importWebSocket.call(void 0, );
5770
5930
  const state = {};
5771
5931
  return {
5772
5932
  onOpen: async (_event, clientWs) => {
@@ -5831,7 +5991,7 @@ async function createWebSocketProxy(_c, targetUrl, protocols) {
5831
5991
  logger2().error({
5832
5992
  msg: "target websocket error",
5833
5993
  targetUrl,
5834
- error: _chunk2BIRGEIUcjs.stringifyError.call(void 0, error)
5994
+ error: _chunkIBEFA6CXcjs.stringifyError.call(void 0, error)
5835
5995
  });
5836
5996
  closeWebSocketIfOpen(clientWs, 1011, "Target WebSocket error");
5837
5997
  });
@@ -5912,7 +6072,7 @@ var RemoteEngineControlClient = class {
5912
6072
  #tokenProvider;
5913
6073
  #webSocketTokens = /* @__PURE__ */ new WeakMap();
5914
6074
  constructor(runConfig) {
5915
- if (_chunk2BIRGEIUcjs.getNextPhase.call(void 0, ) === "phase-production-build") {
6075
+ if (_chunkIBEFA6CXcjs.getNextPhase.call(void 0, ) === "phase-production-build") {
5916
6076
  logger2().info(
5917
6077
  "detected next.js build phase, disabling health check"
5918
6078
  );
@@ -6049,10 +6209,10 @@ var RemoteEngineControlClient = class {
6049
6209
  (config) => getOrCreateActor(config, {
6050
6210
  datacenter: region,
6051
6211
  name,
6052
- key: _chunkMYWZCDMLcjs.serializeActorKey.call(void 0, key),
6053
- runner_name_selector: _nullishCoalesce(poolName, () => ( this.#config.poolName)),
6054
- input: actorInput ? _chunk2BIRGEIUcjs.uint8ArrayToBase64.call(void 0,
6055
- _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0, actorInput)
6212
+ key: _chunkRTWH3AX3cjs.serializeActorKey.call(void 0, key),
6213
+ pool: _nullishCoalesce(poolName, () => ( this.#config.poolName)),
6214
+ input: actorInput ? _chunkIBEFA6CXcjs.uint8ArrayToBase64.call(void 0,
6215
+ _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0, actorInput)
6056
6216
  ) : void 0,
6057
6217
  crash_policy: _nullishCoalesce(crashPolicy, () => ( "sleep"))
6058
6218
  })
@@ -6103,10 +6263,10 @@ var RemoteEngineControlClient = class {
6103
6263
  (config) => createActor(config, {
6104
6264
  datacenter: region,
6105
6265
  name,
6106
- runner_name_selector: _nullishCoalesce(poolName, () => ( this.#config.poolName)),
6107
- key: _chunkMYWZCDMLcjs.serializeActorKey.call(void 0, key),
6108
- input: input ? _chunk2BIRGEIUcjs.uint8ArrayToBase64.call(void 0,
6109
- _chunk2BIRGEIUcjs.encodeCborCompat.call(void 0, input)
6266
+ pool: _nullishCoalesce(poolName, () => ( this.#config.poolName)),
6267
+ key: _chunkRTWH3AX3cjs.serializeActorKey.call(void 0, key),
6268
+ input: input ? _chunkIBEFA6CXcjs.uint8ArrayToBase64.call(void 0,
6269
+ _chunkIBEFA6CXcjs.encodeCborCompat.call(void 0, input)
6110
6270
  ) : void 0,
6111
6271
  crash_policy: _nullishCoalesce(crashPolicy, () => ( "sleep"))
6112
6272
  })
@@ -6238,7 +6398,7 @@ var RemoteEngineControlClient = class {
6238
6398
  const upgradeWebSocket = (_a = config.getUpgradeWebSocket) == null ? void 0 : _a.call(config);
6239
6399
  _invariant2.default.call(void 0, upgradeWebSocket, "missing getUpgradeWebSocket");
6240
6400
  const endpoint = getEndpoint(config);
6241
- const guardUrl = _chunk2BIRGEIUcjs.combineUrlPath.call(void 0, endpoint, path);
6401
+ const guardUrl = _chunkIBEFA6CXcjs.combineUrlPath.call(void 0, endpoint, path);
6242
6402
  const wsGuardUrl = guardUrl.replace("http://", "ws://");
6243
6403
  logger2().debug({
6244
6404
  msg: "forwarding websocket to actor via guard",
@@ -6257,7 +6417,7 @@ var RemoteEngineControlClient = class {
6257
6417
  }
6258
6418
  );
6259
6419
  const args = await createWebSocketProxy(c, wsGuardUrl, protocols);
6260
- return await upgradeWebSocket(() => args)(c, _chunk2BIRGEIUcjs.noopNext.call(void 0, ));
6420
+ return await upgradeWebSocket(() => args)(c, _chunkIBEFA6CXcjs.noopNext.call(void 0, ));
6261
6421
  }
6262
6422
  displayInformation() {
6263
6423
  return { properties: {} };
@@ -6268,7 +6428,7 @@ var RemoteEngineControlClient = class {
6268
6428
  #buildGatewayUrlForTarget(config, target, path, options = {}) {
6269
6429
  const endpoint = getEndpoint(config);
6270
6430
  if (shouldSkipReadyWait(options) && directActorIdFromTarget(target) && canUseDirectSkipReadyWaitPath(path)) {
6271
- return _chunk2BIRGEIUcjs.combineUrlPath.call(void 0, endpoint, path);
6431
+ return _chunkIBEFA6CXcjs.combineUrlPath.call(void 0, endpoint, path);
6272
6432
  }
6273
6433
  if ("directId" in target) {
6274
6434
  return buildActorGatewayUrl(
@@ -6334,7 +6494,7 @@ function apiActorToOutput(actor) {
6334
6494
  return {
6335
6495
  actorId: actor.actor_id,
6336
6496
  name: actor.name,
6337
- key: _chunkMYWZCDMLcjs.deserializeActorKey.call(void 0, actor.key),
6497
+ key: _chunkRTWH3AX3cjs.deserializeActorKey.call(void 0, actor.key),
6338
6498
  createTs: actor.create_ts,
6339
6499
  startTs: _nullishCoalesce(actor.start_ts, () => ( null)),
6340
6500
  connectableTs: _nullishCoalesce(actor.connectable_ts, () => ( null)),
@@ -6369,4 +6529,4 @@ function apiActorToOutput(actor) {
6369
6529
 
6370
6530
 
6371
6531
  exports.HEADER_CONN_PARAMS = HEADER_CONN_PARAMS; exports.HEADER_ORIGINAL_REQUEST_URL = HEADER_ORIGINAL_REQUEST_URL; exports.ALLOWED_PUBLIC_HEADERS = ALLOWED_PUBLIC_HEADERS; exports.ActorClientError = ActorClientError; exports.ManagerError = ManagerError; exports.MalformedResponseMessage = MalformedResponseMessage; exports.ActorConnDisposed = ActorConnDisposed; exports.readActiveTraceHeaders = readActiveTraceHeaders; exports.runWithActorInvocationSpan = runWithActorInvocationSpan; exports.ActorConnRaw = ActorConnRaw; exports.isResponseLike = isResponseLike; exports.ActorHandleRaw = ActorHandleRaw; exports.createClientWithDriver = createClientWithDriver; exports.ENGINE_HOST = ENGINE_HOST; exports.ENGINE_PORT = ENGINE_PORT; exports.buildEngineEndpoint = buildEngineEndpoint; exports.isLocalEngineEndpoint = isLocalEngineEndpoint; exports.tryParseEndpoint = tryParseEndpoint; exports.ClientConfigSchema = ClientConfigSchema; exports.convertRegistryConfigToClientConfig = convertRegistryConfigToClientConfig; exports.getDatacenters = getDatacenters; exports.updateRunnerConfig = updateRunnerConfig; exports.RemoteEngineControlClient = RemoteEngineControlClient;
6372
- //# sourceMappingURL=chunk-P2PHHJMH.cjs.map
6532
+ //# sourceMappingURL=chunk-CTQKKUZC.cjs.map