@rivetkit/supabase 2.3.12-rc.3 → 2.3.12

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 (3) hide show
  1. package/dist/mod.js +394 -140
  2. package/dist/mod.mjs +394 -140
  3. package/package.json +3 -3
package/dist/mod.mjs CHANGED
@@ -297,7 +297,7 @@ var require_retry2 = __commonJS({
297
297
  // src/mod.ts
298
298
  import * as wasmBindings from "@rivetkit/rivetkit-wasm";
299
299
 
300
- // ../rivetkit/dist/tsup/chunk-IXBD7BXC.js
300
+ // ../rivetkit/dist/tsup/chunk-OUQUIBVW.js
301
301
  var INTERNAL_ERROR_CODE = "internal_error";
302
302
  var INTERNAL_ERROR_DESCRIPTION = "An internal error occurred";
303
303
  var USER_ERROR_CODE = "user_error";
@@ -481,7 +481,7 @@ function unsupportedFeature(feature) {
481
481
  );
482
482
  }
483
483
 
484
- // ../rivetkit/dist/tsup/chunk-OLGQYFUW.js
484
+ // ../rivetkit/dist/tsup/chunk-MF42PRF2.js
485
485
  import {
486
486
  pino,
487
487
  stdTimeFunctions
@@ -13157,7 +13157,7 @@ var classic_default = external_exports;
13157
13157
  // ../../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/index.js
13158
13158
  var v4_default = classic_default;
13159
13159
 
13160
- // ../rivetkit/dist/tsup/chunk-OLGQYFUW.js
13160
+ // ../rivetkit/dist/tsup/chunk-MF42PRF2.js
13161
13161
  var import_invariant = __toESM(require_invariant(), 1);
13162
13162
  import * as cbor from "cbor-x";
13163
13163
  var getRivetEngine = () => getEnvUniversal("RIVET_ENGINE");
@@ -13176,6 +13176,10 @@ var getRivetRunEnginePort = () => {
13176
13176
  return value !== void 0 ? parseInt(value, 10) : void 0;
13177
13177
  };
13178
13178
  var getRivetRunEngineVersion = () => getEnvUniversal("RIVET_RUN_ENGINE_VERSION");
13179
+ var getRivetRunServices = () => {
13180
+ const value = getEnvUniversal("RIVET_RUN_SERVICES");
13181
+ return value === void 0 ? void 0 : value === "1";
13182
+ };
13179
13183
  var getRivetEnvoyVersion = () => {
13180
13184
  const value = getEnvUniversal("RIVET_ENVOY_VERSION");
13181
13185
  return value !== void 0 ? parseInt(value, 10) : void 0;
@@ -13327,7 +13331,7 @@ function noopNext() {
13327
13331
  }
13328
13332
  var package_default = {
13329
13333
  name: "rivetkit",
13330
- version: "2.3.12-rc.3",
13334
+ version: "2.3.12",
13331
13335
  description: "Lightweight libraries for building stateful actors on edge platforms",
13332
13336
  license: "Apache-2.0",
13333
13337
  keywords: [
@@ -13537,6 +13541,7 @@ var package_default = {
13537
13541
  dependencies: {
13538
13542
  "@hono/zod-openapi": "^1.1.5",
13539
13543
  "@rivet-dev/agent-os-core": "^0.1.1",
13544
+ "@rivet-dev/services": "^0.1.3",
13540
13545
  "@rivetkit/bare-ts": "^0.6.2",
13541
13546
  "@rivetkit/engine-cli": "workspace:*",
13542
13547
  "@rivetkit/engine-envoy-protocol": "workspace:*",
@@ -14630,7 +14635,7 @@ function Config({ initialBufferLength = 1024, maxBufferLength = 1024 * 1024 * 32
14630
14635
  };
14631
14636
  }
14632
14637
 
14633
- // ../rivetkit/dist/tsup/chunk-WVFTFWJL.js
14638
+ // ../rivetkit/dist/tsup/chunk-GEN4NHXM.js
14634
14639
  var config2 = /* @__PURE__ */ Config({});
14635
14640
  function readWorkflowCbor(bc) {
14636
14641
  return readData(bc);
@@ -15509,6 +15514,44 @@ function removePrefixFromKey(prefixedKey) {
15509
15514
  return prefixedKey.slice(KEYS.KV.length);
15510
15515
  }
15511
15516
 
15517
+ // ../rivetkit/dist/tsup/chunk-JYTXOMM7.js
15518
+ function logger() {
15519
+ return getLogger("actor-client");
15520
+ }
15521
+ var webSocketPromise = null;
15522
+ async function importWebSocket() {
15523
+ if (webSocketPromise !== null) {
15524
+ return webSocketPromise;
15525
+ }
15526
+ webSocketPromise = (async () => {
15527
+ let _WebSocket;
15528
+ if (typeof WebSocket !== "undefined") {
15529
+ _WebSocket = WebSocket;
15530
+ } else {
15531
+ try {
15532
+ const moduleName = "ws";
15533
+ const ws = await import(
15534
+ /* webpackIgnore: true */
15535
+ moduleName
15536
+ );
15537
+ _WebSocket = ws.default;
15538
+ logger().debug("using websocket from npm");
15539
+ } catch {
15540
+ _WebSocket = class MockWebSocket {
15541
+ constructor() {
15542
+ throw new Error(
15543
+ 'WebSocket support requires installing the "ws" peer dependency.'
15544
+ );
15545
+ }
15546
+ };
15547
+ logger().debug("using mock websocket");
15548
+ }
15549
+ }
15550
+ return _WebSocket;
15551
+ })();
15552
+ return webSocketPromise;
15553
+ }
15554
+
15512
15555
  // ../rivetkit/dist/tsup/chunk-JTHHCZCZ.js
15513
15556
  var MIGRATION_TRANSACTION_TIMEOUT_MS = 5 * 6e4;
15514
15557
  function isManualTransactionControl(query) {
@@ -15592,45 +15635,7 @@ var AsyncMutex = class {
15592
15635
  }
15593
15636
  };
15594
15637
 
15595
- // ../rivetkit/dist/tsup/chunk-XI4MEUUI.js
15596
- function logger() {
15597
- return getLogger("actor-client");
15598
- }
15599
- var webSocketPromise = null;
15600
- async function importWebSocket() {
15601
- if (webSocketPromise !== null) {
15602
- return webSocketPromise;
15603
- }
15604
- webSocketPromise = (async () => {
15605
- let _WebSocket;
15606
- if (typeof WebSocket !== "undefined") {
15607
- _WebSocket = WebSocket;
15608
- } else {
15609
- try {
15610
- const moduleName = "ws";
15611
- const ws = await import(
15612
- /* webpackIgnore: true */
15613
- moduleName
15614
- );
15615
- _WebSocket = ws.default;
15616
- logger().debug("using websocket from npm");
15617
- } catch {
15618
- _WebSocket = class MockWebSocket {
15619
- constructor() {
15620
- throw new Error(
15621
- 'WebSocket support requires installing the "ws" peer dependency.'
15622
- );
15623
- }
15624
- };
15625
- logger().debug("using mock websocket");
15626
- }
15627
- }
15628
- return _WebSocket;
15629
- })();
15630
- return webSocketPromise;
15631
- }
15632
-
15633
- // ../rivetkit/dist/tsup/chunk-YYIDQBBM.js
15638
+ // ../rivetkit/dist/tsup/chunk-VOYNLY57.js
15634
15639
  var import_invariant2 = __toESM(require_invariant(), 1);
15635
15640
 
15636
15641
  // ../../../node_modules/.pnpm/p-retry@6.2.1/node_modules/p-retry/index.js
@@ -15808,7 +15813,7 @@ function createVersionedDataHandler(config3) {
15808
15813
  return new VersionedDataHandler(config3);
15809
15814
  }
15810
15815
 
15811
- // ../rivetkit/dist/tsup/chunk-YYIDQBBM.js
15816
+ // ../rivetkit/dist/tsup/chunk-VOYNLY57.js
15812
15817
  var import_invariant3 = __toESM(require_invariant(), 1);
15813
15818
  var import_invariant4 = __toESM(require_invariant(), 1);
15814
15819
  var PATH_CONNECT = "/connect";
@@ -15817,6 +15822,7 @@ var PATH_WEBSOCKET_PREFIX = "/websocket/";
15817
15822
  var HEADER_ACTOR_QUERY = "x-rivet-query";
15818
15823
  var HEADER_ENCODING = "x-rivet-encoding";
15819
15824
  var HEADER_CONN_PARAMS = "x-rivet-conn-params";
15825
+ var HEADER_ORIGINAL_REQUEST_URL = "x-rivet-internal-original-request-url";
15820
15826
  var HEADER_ACTOR_ID = "x-rivet-actor";
15821
15827
  var HEADER_ACTOR_GENERATION = "x-rivet-actor-generation";
15822
15828
  var HEADER_ACTOR_KEY = "x-rivet-actor-key";
@@ -17875,6 +17881,18 @@ async function checkForSchedulingError(group, code, actorId, query, driver, rayI
17875
17881
  }
17876
17882
  return null;
17877
17883
  }
17884
+ function isUrlLike(value) {
17885
+ return typeof value === "object" && value !== null && typeof value.href === "string" && typeof value.pathname === "string" && typeof value.search === "string";
17886
+ }
17887
+ function isRequestLike(value) {
17888
+ return typeof value === "object" && value !== null && typeof value.url === "string" && typeof value.method === "string" && isHeadersLike(value.headers);
17889
+ }
17890
+ function isResponseLike(value) {
17891
+ return typeof value === "object" && value !== null && typeof value.status === "number" && isHeadersLike(value.headers) && typeof value.arrayBuffer === "function";
17892
+ }
17893
+ function isHeadersLike(value) {
17894
+ return typeof value === "object" && value !== null && typeof value.entries === "function";
17895
+ }
17878
17896
  function* walkErrorChain(error46, maxDepth = 8) {
17879
17897
  let current = error46;
17880
17898
  let depth = 0;
@@ -18300,28 +18318,19 @@ function createQueueSender(senderOptions) {
18300
18318
  send
18301
18319
  };
18302
18320
  }
18303
- function isUrlLike(value) {
18304
- return typeof value === "object" && value !== null && typeof value.href === "string" && typeof value.pathname === "string" && typeof value.search === "string";
18305
- }
18306
- function isRequestLike(value) {
18307
- return typeof value === "object" && value !== null && typeof value.url === "string" && typeof value.method === "string" && isHeadersLike(value.headers);
18308
- }
18309
- function isResponseLike(value) {
18310
- return typeof value === "object" && value !== null && typeof value.status === "number" && isHeadersLike(value.headers) && typeof value.arrayBuffer === "function";
18311
- }
18312
- function isHeadersLike(value) {
18313
- return typeof value === "object" && value !== null && typeof value.entries === "function";
18314
- }
18315
18321
  async function rawHttpFetch(driver, target, params, input, init, options = {}) {
18316
18322
  let path2;
18323
+ let originalUrl;
18317
18324
  let mergedInit = init || {};
18318
18325
  if (typeof input === "string") {
18319
18326
  path2 = input;
18320
18327
  } else if (isUrlLike(input)) {
18321
18328
  path2 = input.pathname + input.search;
18329
+ originalUrl = input.toString();
18322
18330
  } else if (isRequestLike(input)) {
18323
18331
  const url2 = new URL(input.url);
18324
18332
  path2 = url2.pathname + url2.search;
18333
+ originalUrl = url2.toString();
18325
18334
  const requestHeaders = new Headers(input.headers);
18326
18335
  const initHeaders = new Headers((init == null ? void 0 : init.headers) || {});
18327
18336
  const mergedHeaders = new Headers(requestHeaders);
@@ -18363,6 +18372,10 @@ async function rawHttpFetch(driver, target, params, input, init, options = {}) {
18363
18372
  const normalizedPath = path2.startsWith("/") ? path2.slice(1) : path2;
18364
18373
  const url2 = new URL(`http://actor/request/${normalizedPath}`);
18365
18374
  const proxyRequestHeaders = new Headers(mergedInit.headers);
18375
+ proxyRequestHeaders.delete(HEADER_ORIGINAL_REQUEST_URL);
18376
+ if (originalUrl) {
18377
+ proxyRequestHeaders.set(HEADER_ORIGINAL_REQUEST_URL, originalUrl);
18378
+ }
18366
18379
  if (params) {
18367
18380
  proxyRequestHeaders.set(HEADER_CONN_PARAMS, JSON.stringify(params));
18368
18381
  }
@@ -18488,7 +18501,9 @@ var ActorHandleRaw = class {
18488
18501
  async #sendQueueMessage(name, body, options) {
18489
18502
  return await this.#queueSendMutex.run(async () => {
18490
18503
  const maxAttempts = this.#getDynamicQueryMaxAttempts();
18491
- let useQueryTarget = isDynamicActorQuery(this.#actorResolutionState);
18504
+ let useQueryTarget = isDynamicActorQuery(
18505
+ this.#actorResolutionState
18506
+ );
18492
18507
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
18493
18508
  let actorId;
18494
18509
  try {
@@ -18837,9 +18852,10 @@ var ActorHandleRaw = class {
18837
18852
  return this.#fetchWithResolvedActor(input, init);
18838
18853
  }
18839
18854
  async #fetchWithResolvedActor(input, init) {
18840
- const maxAttempts = this.#getDynamicQueryMaxAttempts();
18841
- let useQueryTarget = isDynamicActorQuery(this.#actorResolutionState);
18842
18855
  const { skipReadyWait, ...requestInit } = init ?? {};
18856
+ const hasBody = requestInit.body !== void 0 ? requestInit.body !== null : isRequestLike(input) && input.body !== null;
18857
+ const maxAttempts = hasBody ? 1 : this.#getDynamicQueryMaxAttempts();
18858
+ let useQueryTarget = isDynamicActorQuery(this.#actorResolutionState);
18843
18859
  const gatewayOptions = resolveActorGatewayOptions(
18844
18860
  this.#gatewayOptions,
18845
18861
  {
@@ -20607,23 +20623,19 @@ async function sendHttpRequestToGateway(runConfig, gatewayUrl, actorRequest, opt
20607
20623
  if (actorRequest.bodyUsed) {
20608
20624
  throw new Error("Request body has already been consumed");
20609
20625
  }
20610
- const reqBody = await actorRequest.arrayBuffer();
20611
- if (reqBody.byteLength !== 0) {
20612
- bodyToSend = reqBody;
20626
+ if (actorRequest.body) {
20627
+ bodyToSend = actorRequest.body;
20613
20628
  guardHeaders.delete("transfer-encoding");
20614
20629
  guardHeaders.delete("content-length");
20615
20630
  }
20616
20631
  }
20617
- const guardRequest = new Request(gatewayUrl, {
20632
+ return fetch(gatewayUrl, {
20618
20633
  method: actorRequest.method,
20619
20634
  headers: guardHeaders,
20620
20635
  body: bodyToSend,
20621
- signal: actorRequest.signal
20636
+ signal: actorRequest.signal,
20637
+ ...bodyToSend ? { duplex: "half" } : {}
20622
20638
  });
20623
- return mutableResponse(await fetch(guardRequest));
20624
- }
20625
- function mutableResponse(fetchRes) {
20626
- return new Response(fetchRes.body, fetchRes);
20627
20639
  }
20628
20640
  function buildGuardHeaders(runConfig, actorRequest, options) {
20629
20641
  const headers = new Headers();
@@ -21573,7 +21585,7 @@ function apiActorToOutput(actor2) {
21573
21585
  };
21574
21586
  }
21575
21587
 
21576
- // ../rivetkit/dist/tsup/chunk-PSXMESQJ.js
21588
+ // ../rivetkit/dist/tsup/chunk-EBXARMGI.js
21577
21589
  var nativeStateTransactionOpeners = /* @__PURE__ */ new WeakMap();
21578
21590
  var nativeStateTransactionClientBinders = /* @__PURE__ */ new WeakMap();
21579
21591
  function registerNativeStateTransactionOpener(provider, opener) {
@@ -23649,6 +23661,12 @@ var RegistryConfigSchema = external_exports.object({
23649
23661
  enginePort: external_exports.number().int().min(1).max(65535).optional().default(() => getRivetRunEnginePort() ?? ENGINE_PORT),
23650
23662
  /** @experimental */
23651
23663
  engineVersion: external_exports.string().optional().default(() => getRivetRunEngineVersion() ?? VERSION),
23664
+ /**
23665
+ * Starts the first-party Services actor host when RivetKit manages
23666
+ * a local engine. Defaults to the local-engine decision. Set
23667
+ * RIVET_RUN_SERVICES=0 or 1 to override it.
23668
+ */
23669
+ startServices: external_exports.boolean().optional(),
23652
23670
  /**
23653
23671
  * @experimental
23654
23672
  *
@@ -23729,6 +23747,7 @@ var RegistryConfigSchema = external_exports.object({
23729
23747
  config3.enginePort
23730
23748
  );
23731
23749
  const endpoint = config3.startEngine ? localEngineEndpoint : (parsedEndpoint == null ? void 0 : parsedEndpoint.endpoint) ?? (isDevEnv ? localEngineEndpoint : void 0);
23750
+ const startServices = config3.startServices ?? getRivetRunServices() ?? Boolean(endpoint && isLocalEngineEndpoint(endpoint));
23732
23751
  const validateServerlessEndpoint = Boolean(
23733
23752
  config3.startEngine || parsedEndpoint
23734
23753
  );
@@ -23752,6 +23771,7 @@ var RegistryConfigSchema = external_exports.object({
23752
23771
  ...config3,
23753
23772
  sqlite,
23754
23773
  endpoint,
23774
+ startServices,
23755
23775
  namespace,
23756
23776
  token,
23757
23777
  publicEndpoint,
@@ -23865,6 +23885,9 @@ var DocRegistryConfigSchema = external_exports.object({
23865
23885
  engineVersion: external_exports.string().optional().describe(
23866
23886
  "Version of the local engine package to use. Defaults to the current RivetKit version."
23867
23887
  ),
23888
+ startServices: external_exports.boolean().optional().describe(
23889
+ "Starts Services when RivetKit manages a local Engine. Defaults to the local-Engine decision. Set RIVET_RUN_SERVICES=0 or 1 to override."
23890
+ ),
23868
23891
  configurePool: DocConfigurePoolSchema.describe(
23869
23892
  "Automatically configure serverless runners in the engine."
23870
23893
  ),
@@ -24374,16 +24397,30 @@ function toNapiApplication(application) {
24374
24397
  if (!request) {
24375
24398
  throw new Error("application fetch callback received no request");
24376
24399
  }
24377
- const response = await application({
24378
- ...request,
24379
- body: new Uint8Array(request.body)
24380
- });
24400
+ const response = await application(
24401
+ {
24402
+ ...request,
24403
+ body: new Uint8Array(request.body),
24404
+ cancelToken: request.cancelToken
24405
+ },
24406
+ request.responseBodyStream ? fromNapiHttpResponseBodyStream(
24407
+ request.responseBodyStream
24408
+ ) : void 0
24409
+ );
24381
24410
  return {
24382
24411
  ...response,
24383
- body: toNapiBuffer(response.body)
24412
+ body: response.body === void 0 ? void 0 : toNapiBuffer(response.body)
24384
24413
  };
24385
24414
  };
24386
24415
  }
24416
+ function fromNapiHttpResponseBodyStream(stream) {
24417
+ return {
24418
+ cancelled: () => stream.cancelled(),
24419
+ write: (chunk) => stream.write(Buffer.from(chunk)),
24420
+ end: () => stream.end(),
24421
+ error: (message) => stream.error(message)
24422
+ };
24423
+ }
24387
24424
  function toNapiHttpRequest(request) {
24388
24425
  if (!request) {
24389
24426
  return request;
@@ -24926,6 +24963,147 @@ async function loadNapiRuntime() {
24926
24963
  runtime: new NapiCoreRuntime(bindings)
24927
24964
  };
24928
24965
  }
24966
+ var HTTP_BODY_CHUNK_SIZE = 64 * 1024;
24967
+ function runtimeBytesToArrayBuffer(value) {
24968
+ return value.buffer.slice(
24969
+ value.byteOffset,
24970
+ value.byteOffset + value.byteLength
24971
+ );
24972
+ }
24973
+ function buildNativeHttpRequest(init) {
24974
+ var _a2;
24975
+ const headers = new Headers(init.headers);
24976
+ const originalUrl = headers.get(HEADER_ORIGINAL_REQUEST_URL);
24977
+ headers.delete(HEADER_ORIGINAL_REQUEST_URL);
24978
+ const url2 = originalUrl ?? (init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString());
24979
+ const method2 = init.method.toUpperCase();
24980
+ const bodyForbidden = method2 === "GET" || method2 === "HEAD";
24981
+ const body = bodyForbidden ? void 0 : init.bodyStream ? new ReadableStream({
24982
+ async pull(controller) {
24983
+ var _a22, _b;
24984
+ try {
24985
+ if (init.body && init.body.length > 0) {
24986
+ controller.enqueue(new Uint8Array(init.body));
24987
+ init.body = void 0;
24988
+ return;
24989
+ }
24990
+ const chunk = await ((_a22 = init.bodyStream) == null ? void 0 : _a22.read());
24991
+ if (!chunk) {
24992
+ controller.close();
24993
+ } else {
24994
+ controller.enqueue(new Uint8Array(chunk));
24995
+ }
24996
+ } catch (error46) {
24997
+ (_b = init.abortController) == null ? void 0 : _b.abort(error46);
24998
+ controller.error(error46);
24999
+ }
25000
+ },
25001
+ async cancel() {
25002
+ var _a22;
25003
+ await ((_a22 = init.bodyStream) == null ? void 0 : _a22.cancel());
25004
+ }
25005
+ }) : init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
25006
+ const streamInit = init.bodyStream && !bodyForbidden ? { duplex: "half" } : {};
25007
+ return new Request(url2, {
25008
+ method: method2,
25009
+ headers,
25010
+ body,
25011
+ signal: ((_a2 = init.abortController) == null ? void 0 : _a2.signal) ?? init.signal,
25012
+ ...streamInit
25013
+ });
25014
+ }
25015
+ async function cancelNativeHttpRequestBody(bodyStream) {
25016
+ await (bodyStream == null ? void 0 : bodyStream.cancel());
25017
+ }
25018
+ async function writeResponseChunk(stream, chunk) {
25019
+ for (let offset = 0; offset < chunk.byteLength; offset += HTTP_BODY_CHUNK_SIZE) {
25020
+ await stream.write(
25021
+ chunk.subarray(offset, offset + HTTP_BODY_CHUNK_SIZE)
25022
+ );
25023
+ }
25024
+ }
25025
+ async function pumpResponseBody(reader, stream) {
25026
+ var _a2;
25027
+ const cancelled = stream.cancelled().then(() => ({ cancelled: true }));
25028
+ try {
25029
+ for (; ; ) {
25030
+ const read = reader.read().then((next2) => ({ cancelled: false, next: next2 }));
25031
+ const result = await Promise.race([read, cancelled]);
25032
+ if (result.cancelled) {
25033
+ void reader.cancel(
25034
+ new Error(
25035
+ "native http response stream receiver dropped"
25036
+ )
25037
+ ).catch((error46) => {
25038
+ logger22().debug({
25039
+ msg: "failed to cancel native http response reader",
25040
+ error: error46
25041
+ });
25042
+ });
25043
+ return;
25044
+ }
25045
+ const { next } = result;
25046
+ if (next.done) {
25047
+ await stream.end();
25048
+ return;
25049
+ }
25050
+ if ((_a2 = next.value) == null ? void 0 : _a2.byteLength) {
25051
+ await writeResponseChunk(stream, next.value);
25052
+ }
25053
+ }
25054
+ } catch (error46) {
25055
+ try {
25056
+ await stream.error(stringifyError(error46));
25057
+ } catch (streamError) {
25058
+ logger22().debug({
25059
+ msg: "failed to report native http response stream error",
25060
+ error: streamError
25061
+ });
25062
+ }
25063
+ void reader.cancel(error46).catch(() => {
25064
+ });
25065
+ } finally {
25066
+ try {
25067
+ reader.releaseLock();
25068
+ } catch (error46) {
25069
+ logger22().debug({
25070
+ msg: "failed to release native http response reader lock",
25071
+ error: error46
25072
+ });
25073
+ }
25074
+ }
25075
+ }
25076
+ async function convertNativeHttpResponse(response, responseBodyStream) {
25077
+ const headers = Object.fromEntries(response.headers.entries());
25078
+ if (!response.body) {
25079
+ return {
25080
+ response: {
25081
+ status: response.status,
25082
+ headers,
25083
+ body: new Uint8Array()
25084
+ }
25085
+ };
25086
+ }
25087
+ if (responseBodyStream) {
25088
+ const reader = response.body.getReader();
25089
+ const bodyCompletion = pumpResponseBody(reader, responseBodyStream);
25090
+ return {
25091
+ response: {
25092
+ status: response.status,
25093
+ headers,
25094
+ stream: true
25095
+ },
25096
+ bodyCompletion
25097
+ };
25098
+ }
25099
+ return {
25100
+ response: {
25101
+ status: response.status,
25102
+ headers,
25103
+ body: new Uint8Array(await response.arrayBuffer())
25104
+ }
25105
+ };
25106
+ }
24929
25107
  var CONN_PARAMS_KEY = "__conn_params__";
24930
25108
  function validateActionArgs(schemas, name, args) {
24931
25109
  if (!(schemas == null ? void 0 : schemas[name])) {
@@ -26374,7 +26552,7 @@ function toRuntimeBytes(value) {
26374
26552
  function arrayBufferViewToRuntimeBytes(value) {
26375
26553
  return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
26376
26554
  }
26377
- function runtimeBytesToArrayBuffer(value) {
26555
+ function runtimeBytesToArrayBuffer2(value) {
26378
26556
  return value.buffer.slice(
26379
26557
  value.byteOffset,
26380
26558
  value.byteOffset + value.byteLength
@@ -26420,6 +26598,9 @@ function decodeNativeKvValue(value, options) {
26420
26598
  async function loadEngineCli() {
26421
26599
  return import(["@rivetkit", "engine-cli"].join("/"));
26422
26600
  }
26601
+ async function loadServices() {
26602
+ return import(["@rivet-dev", "services"].join("/"));
26603
+ }
26423
26604
  function decodeValue(value) {
26424
26605
  if (!value || value.length === 0) {
26425
26606
  return void 0;
@@ -26705,24 +26886,6 @@ function decodeArgs(value) {
26705
26886
  const decoded = decodeValue(value);
26706
26887
  return normalizeArgs(decoded);
26707
26888
  }
26708
- function buildRequest(init) {
26709
- const url2 = init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString();
26710
- const body = init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
26711
- return new Request(url2, {
26712
- method: init.method,
26713
- headers: init.headers,
26714
- body
26715
- });
26716
- }
26717
- async function toRuntimeHttpResponse(response) {
26718
- const headers = Object.fromEntries(response.headers.entries());
26719
- const body = new Uint8Array(await response.arrayBuffer());
26720
- return {
26721
- status: response.status,
26722
- headers,
26723
- body
26724
- };
26725
- }
26726
26889
  function toActorKey(segments) {
26727
26890
  return segments.map(
26728
26891
  (segment) => segment.kind === "number" ? String(segment.numberValue ?? 0) : segment.stringValue ?? ""
@@ -27435,7 +27598,7 @@ var NativeWebSocketAdapter = class {
27435
27598
  this.#runtime.webSocketSetEventCallback(this.#ws, (event2) => {
27436
27599
  if (event2.kind === "message") {
27437
27600
  this.#virtual.triggerMessage(
27438
- event2.binary ? runtimeBytesToArrayBuffer(event2.data) : event2.data,
27601
+ event2.binary ? runtimeBytesToArrayBuffer2(event2.data) : event2.data,
27439
27602
  event2.messageIndex
27440
27603
  );
27441
27604
  return;
@@ -28818,12 +28981,14 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28818
28981
  cancelToken,
28819
28982
  run !== void 0
28820
28983
  );
28821
- const maybeHandleNativeInspectorRequest = async (ctx, _rawRequest, jsRequest) => {
28984
+ const maybeHandleNativeInspectorRequest = async (ctx, rawRequest) => {
28822
28985
  var _a22, _b, _c, _d;
28823
- const url2 = new URL(jsRequest.url);
28986
+ const rawUrl = rawRequest.uri.startsWith("http") ? rawRequest.uri : new URL(rawRequest.uri, "http://127.0.0.1").toString();
28987
+ const url2 = new URL(rawUrl);
28824
28988
  if (!url2.pathname.startsWith("/inspector/")) {
28825
28989
  return void 0;
28826
28990
  }
28991
+ const jsRequest = buildNativeHttpRequest(rawRequest);
28827
28992
  const jsonResponse = (body, init) => new Response(JSON.stringify(body), {
28828
28993
  status: (init == null ? void 0 : init.status) ?? 200,
28829
28994
  headers: {
@@ -29354,7 +29519,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29354
29519
  );
29355
29520
  const actorCtx = makeActorCtx(
29356
29521
  ctx,
29357
- request ? buildRequest(request) : void 0
29522
+ request ? buildNativeHttpRequest(request) : void 0
29358
29523
  );
29359
29524
  try {
29360
29525
  await config3.onBeforeConnect(
@@ -29374,7 +29539,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29374
29539
  const { ctx, conn, params, request } = unwrapTsfnPayload(error46, payload);
29375
29540
  const actorCtx = makeActorCtx(
29376
29541
  ctx,
29377
- request ? buildRequest(request) : void 0
29542
+ request ? buildNativeHttpRequest(request) : void 0
29378
29543
  );
29379
29544
  const connAdapter = new NativeConnAdapter(
29380
29545
  runtime,
@@ -29412,7 +29577,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29412
29577
  );
29413
29578
  const actorCtx = makeActorCtx(
29414
29579
  ctx,
29415
- request ? buildRequest(request) : void 0
29580
+ request ? buildNativeHttpRequest(request) : void 0
29416
29581
  );
29417
29582
  const connAdapter = new NativeConnAdapter(
29418
29583
  runtime,
@@ -29519,27 +29684,45 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29519
29684
  onRequest: wrapNativeCallback(
29520
29685
  async (error46, payload) => {
29521
29686
  try {
29522
- const { ctx, request, cancelToken } = unwrapTsfnPayload(
29523
- error46,
29524
- payload
29525
- );
29526
- const jsRequest = buildRequest(request);
29527
- const inspectorResponse = await maybeHandleNativeInspectorRequest(
29528
- ctx,
29529
- request,
29530
- jsRequest
29531
- );
29687
+ const { ctx, request, cancelToken, responseBodyStream } = unwrapTsfnPayload(error46, payload);
29688
+ const inspectorResponse = await maybeHandleNativeInspectorRequest(ctx, request);
29532
29689
  if (inspectorResponse) {
29533
- return await toRuntimeHttpResponse(inspectorResponse);
29690
+ await cancelNativeHttpRequestBody(request.bodyStream);
29691
+ return (await convertNativeHttpResponse(
29692
+ inspectorResponse,
29693
+ responseBodyStream
29694
+ )).response;
29534
29695
  }
29535
29696
  if (typeof config3.onRequest !== "function") {
29536
- return await toRuntimeHttpResponse(
29537
- new Response(null, { status: 404 })
29538
- );
29697
+ await cancelNativeHttpRequestBody(request.bodyStream);
29698
+ return (await convertNativeHttpResponse(
29699
+ new Response(null, { status: 404 }),
29700
+ responseBodyStream
29701
+ )).response;
29539
29702
  }
29540
- const rawConnParams = jsRequest.headers.get(HEADER_CONN_PARAMS);
29703
+ const requestAbortController = new AbortController();
29704
+ const handlerRequest = buildNativeHttpRequest({
29705
+ ...request,
29706
+ abortController: requestAbortController
29707
+ });
29708
+ const rawConnParams = handlerRequest.headers.get(HEADER_CONN_PARAMS);
29541
29709
  let requestCtx;
29542
29710
  let conn;
29711
+ let removeRequestAbortListener;
29712
+ let cleanupDeferredToBody = false;
29713
+ let cleanedUp = false;
29714
+ const cleanupRequest = async () => {
29715
+ if (cleanedUp) return;
29716
+ cleanedUp = true;
29717
+ removeRequestAbortListener == null ? void 0 : removeRequestAbortListener();
29718
+ try {
29719
+ await (requestCtx == null ? void 0 : requestCtx.dispose());
29720
+ } finally {
29721
+ if (conn) {
29722
+ await runtime.connDisconnect(conn);
29723
+ }
29724
+ }
29725
+ };
29543
29726
  try {
29544
29727
  const connParams = validateConnParams(
29545
29728
  schemaConfig.connParamsSchema,
@@ -29555,23 +29738,56 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29555
29738
  requestCtx = makeConnCtx(
29556
29739
  ctx,
29557
29740
  conn,
29558
- jsRequest,
29741
+ handlerRequest,
29559
29742
  cancelToken
29560
29743
  );
29744
+ const ctxAbortSignal = requestCtx.abortSignal;
29745
+ const abortRequest = () => requestAbortController.abort(ctxAbortSignal.reason);
29746
+ if (ctxAbortSignal.aborted) {
29747
+ abortRequest();
29748
+ } else {
29749
+ ctxAbortSignal.addEventListener(
29750
+ "abort",
29751
+ abortRequest,
29752
+ { once: true }
29753
+ );
29754
+ removeRequestAbortListener = () => ctxAbortSignal.removeEventListener(
29755
+ "abort",
29756
+ abortRequest
29757
+ );
29758
+ }
29561
29759
  const response = await config3.onRequest(
29562
29760
  requestCtx,
29563
- jsRequest
29761
+ handlerRequest
29564
29762
  );
29565
29763
  if (!isResponseLike(response)) {
29566
29764
  throw new Error(
29567
29765
  "onRequest handler must return a Response"
29568
29766
  );
29569
29767
  }
29570
- return await toRuntimeHttpResponse(response);
29768
+ const conversion = await convertNativeHttpResponse(
29769
+ response,
29770
+ responseBodyStream
29771
+ );
29772
+ if (conversion.bodyCompletion) {
29773
+ cleanupDeferredToBody = true;
29774
+ void conversion.bodyCompletion.then(cleanupRequest).catch((cleanupError) => {
29775
+ logger22().error({
29776
+ msg: "failed to clean up native streaming http request",
29777
+ error: cleanupError
29778
+ });
29779
+ });
29780
+ }
29781
+ return conversion.response;
29571
29782
  } finally {
29572
- await (requestCtx == null ? void 0 : requestCtx.dispose());
29573
- if (conn) {
29574
- await runtime.connDisconnect(conn);
29783
+ try {
29784
+ await cancelNativeHttpRequestBody(
29785
+ request.bodyStream
29786
+ );
29787
+ } finally {
29788
+ if (!cleanupDeferredToBody) {
29789
+ await cleanupRequest();
29790
+ }
29575
29791
  }
29576
29792
  }
29577
29793
  } catch (error210) {
@@ -29586,7 +29802,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29586
29802
  onWebSocket: typeof config3.onWebSocket === "function" ? wrapNativeCallback(
29587
29803
  async (error46, payload) => {
29588
29804
  const { ctx, conn, ws, request } = unwrapTsfnPayload(error46, payload);
29589
- const jsRequest = request ? buildRequest(request) : void 0;
29805
+ const jsRequest = request ? buildNativeHttpRequest(request) : void 0;
29590
29806
  const actorCtx = makeConnCtx(ctx, conn, jsRequest);
29591
29807
  try {
29592
29808
  await config3.onWebSocket(
@@ -29692,7 +29908,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29692
29908
  timeoutMs,
29693
29909
  cancelToken
29694
29910
  } = unwrapTsfnPayload(error46, payload);
29695
- const jsRequest = buildRequest(request);
29911
+ const jsRequest = buildNativeHttpRequest(request);
29696
29912
  const actorCtx = withConnContext(
29697
29913
  runtime,
29698
29914
  ctx,
@@ -29762,7 +29978,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
29762
29978
  buildActorConfig(definition, registryConfig, runtime.kind)
29763
29979
  );
29764
29980
  }
29765
- async function buildServeConfig(config3) {
29981
+ async function buildServeConfig(config3, resolveServicesBinary = true) {
29766
29982
  var _a2;
29767
29983
  if (!config3.endpoint) {
29768
29984
  throw nativeEndpointNotConfiguredError();
@@ -29773,6 +29989,7 @@ async function buildServeConfig(config3) {
29773
29989
  token: config3.token,
29774
29990
  namespace: config3.namespace,
29775
29991
  poolName: config3.envoy.poolName,
29992
+ startServices: resolveServicesBinary && config3.startServices,
29776
29993
  handleInspectorHttpInRuntime: true,
29777
29994
  serverlessBasePath: config3.serverless.basePath,
29778
29995
  serverlessPackageVersion: VERSION,
@@ -29791,6 +30008,17 @@ async function buildServeConfig(config3) {
29791
30008
  error: stringifyError(error46)
29792
30009
  });
29793
30010
  }
30011
+ if (resolveServicesBinary && config3.startServices) {
30012
+ try {
30013
+ const { getServicesPath } = await loadServices();
30014
+ serveConfig.servicesBinaryPath = getServicesPath();
30015
+ } catch (error46) {
30016
+ logger22().warn({
30017
+ msg: "could not resolve the Services binary; a local engine will fail with services.binary_unavailable \u2014 set RIVET_RUN_SERVICES=0 to disable Services or RIVET_SERVICES_BINARY to a local rivet-services binary",
30018
+ error: stringifyError(error46)
30019
+ });
30020
+ }
30021
+ }
29794
30022
  serveConfig.engineHost = config3.engineHost;
29795
30023
  serveConfig.enginePort = config3.enginePort;
29796
30024
  if ((_a2 = config3.test) == null ? void 0 : _a2.enabled) {
@@ -29817,7 +30045,7 @@ async function buildRegistryWithRuntime(config3, runtime) {
29817
30045
  return {
29818
30046
  runtime,
29819
30047
  registry: registry2,
29820
- serveConfig: await buildServeConfig(config3)
30048
+ serveConfig: await buildServeConfig(config3, runtime.kind === "napi")
29821
30049
  };
29822
30050
  }
29823
30051
  async function buildConfiguredRegistry(config3) {
@@ -29842,15 +30070,27 @@ function finishShutdownSignal(signal) {
29842
30070
  }
29843
30071
  process.kill(process.pid, signal);
29844
30072
  }
29845
- function createApplicationFetch(application) {
29846
- return async (request) => {
30073
+ function createApplicationFetch(application, runtime) {
30074
+ return async (request, responseBodyStream) => {
29847
30075
  const method2 = request.method.toUpperCase();
29848
30076
  const body = method2 === "GET" || method2 === "HEAD" || request.body.length === 0 ? void 0 : Uint8Array.from(request.body).buffer;
30077
+ const abortController = new AbortController();
30078
+ if (request.cancelToken) {
30079
+ if (runtime.cancellationTokenAborted(request.cancelToken)) {
30080
+ abortController.abort();
30081
+ } else {
30082
+ runtime.onCancellationTokenCancelled(
30083
+ request.cancelToken,
30084
+ () => abortController.abort()
30085
+ );
30086
+ }
30087
+ }
29849
30088
  const response = await application.fetch(
29850
30089
  new Request(request.url, {
29851
30090
  method: method2,
29852
30091
  headers: request.headers,
29853
- body
30092
+ body,
30093
+ signal: abortController.signal
29854
30094
  })
29855
30095
  );
29856
30096
  if (!isResponseLike(response)) {
@@ -29858,10 +30098,23 @@ function createApplicationFetch(application) {
29858
30098
  "registry.listen() application fetch must return a Response"
29859
30099
  );
29860
30100
  }
30101
+ const conversion = await convertNativeHttpResponse(
30102
+ response,
30103
+ responseBodyStream
30104
+ );
30105
+ if (conversion.bodyCompletion) {
30106
+ void conversion.bodyCompletion.catch((error46) => {
30107
+ logger22().error({
30108
+ msg: "application response stream failed",
30109
+ error: error46
30110
+ });
30111
+ });
30112
+ }
29861
30113
  return {
29862
- status: response.status,
29863
- headers: Object.fromEntries(response.headers.entries()),
29864
- body: new Uint8Array(await response.arrayBuffer())
30114
+ status: conversion.response.status ?? response.status,
30115
+ headers: conversion.response.headers ?? Object.fromEntries(response.headers.entries()),
30116
+ body: conversion.response.body,
30117
+ stream: conversion.response.stream
29865
30118
  };
29866
30119
  };
29867
30120
  }
@@ -30119,8 +30372,7 @@ var Registry = class {
30119
30372
  const port = opts.port ?? parsePortEnv(process.env.RIVET_PORT) ?? 3e3;
30120
30373
  const publicDir = opts.publicDir ?? getRivetkitPublicDir();
30121
30374
  const config3 = this.parseConfig();
30122
- const application = opts.application ? createApplicationFetch(opts.application) : void 0;
30123
- if (application && getRivetkitRuntimeMode() !== "serverless") {
30375
+ if (opts.application && getRivetkitRuntimeMode() !== "serverless") {
30124
30376
  if (config3.runtime === "wasm") {
30125
30377
  throw new Error(
30126
30378
  "registry.listen() requires the native runtime; use an application-owned HTTP server with WebAssembly"
@@ -30139,13 +30391,18 @@ var Registry = class {
30139
30391
  throw new Error("registry envoy startup did not initialize");
30140
30392
  }
30141
30393
  const { runtime: runtime2, registry: registry22, serveConfig: serveConfig2 } = await configuredRegistryPromise2;
30394
+ const application2 = createApplicationFetch(
30395
+ opts.application,
30396
+ runtime2
30397
+ );
30398
+ await readyPromise;
30142
30399
  const listenerPromise = runtime2.serveApplicationListener(
30143
30400
  registry22,
30144
30401
  {
30145
30402
  port,
30146
30403
  host: opts.host,
30147
30404
  publicDir,
30148
- application
30405
+ application: application2
30149
30406
  },
30150
30407
  serveConfig2
30151
30408
  );
@@ -30156,14 +30413,10 @@ var Registry = class {
30156
30413
  "registry envoy serve lifecycle did not initialize"
30157
30414
  );
30158
30415
  }
30159
- await Promise.all([
30160
- readyPromise,
30161
- listenerPromise,
30162
- serveLifecyclePromise
30163
- ]);
30416
+ await Promise.all([listenerPromise, serveLifecyclePromise]);
30164
30417
  return;
30165
30418
  }
30166
- const configuredRegistryPromise = buildConfiguredRegistry(config3);
30419
+ const configuredRegistryPromise = this.#buildConfiguredRegistry(config3);
30167
30420
  this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
30168
30421
  this.#runtimeServerlessPromise = configuredRegistryPromise;
30169
30422
  this.#installSignalHandlers(config3);
@@ -30174,6 +30427,7 @@ var Registry = class {
30174
30427
  });
30175
30428
  this.#ensureServerlessPoolConfigured(config3);
30176
30429
  const { runtime, registry: registry2, serveConfig } = await configuredRegistryPromise;
30430
+ const application = opts.application ? createApplicationFetch(opts.application, runtime) : void 0;
30177
30431
  await runtime.serveListener(
30178
30432
  registry2,
30179
30433
  {