@rivetkit/supabase 2.3.7 → 2.3.9

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 +448 -107
  2. package/dist/mod.mjs +448 -107
  3. package/package.json +3 -3
package/dist/mod.mjs CHANGED
@@ -471,7 +471,7 @@ function unsupportedFeature(feature) {
471
471
  );
472
472
  }
473
473
 
474
- // ../rivetkit/dist/tsup/chunk-OG4OR2CM.js
474
+ // ../rivetkit/dist/tsup/chunk-UBYPRYJR.js
475
475
  import {
476
476
  pino,
477
477
  stdTimeFunctions
@@ -13147,7 +13147,7 @@ var classic_default = external_exports;
13147
13147
  // ../../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/index.js
13148
13148
  var v4_default = classic_default;
13149
13149
 
13150
- // ../rivetkit/dist/tsup/chunk-OG4OR2CM.js
13150
+ // ../rivetkit/dist/tsup/chunk-UBYPRYJR.js
13151
13151
  var import_invariant = __toESM(require_invariant(), 1);
13152
13152
  import * as cbor from "cbor-x";
13153
13153
  var getRivetEngine = () => getEnvUniversal("RIVET_ENGINE");
@@ -13312,7 +13312,7 @@ function noopNext() {
13312
13312
  }
13313
13313
  var package_default = {
13314
13314
  name: "rivetkit",
13315
- version: "2.3.7",
13315
+ version: "2.3.9",
13316
13316
  description: "Lightweight libraries for building stateful actors on edge platforms",
13317
13317
  license: "Apache-2.0",
13318
13318
  keywords: [
@@ -14063,7 +14063,10 @@ function jsonStringifyCompat(input, space) {
14063
14063
  return [JSON_COMPAT_BIGINT, value.toString()];
14064
14064
  }
14065
14065
  if (value instanceof ArrayBuffer) {
14066
- return [JSON_COMPAT_ARRAY_BUFFER, base64EncodeArrayBuffer(value)];
14066
+ return [
14067
+ JSON_COMPAT_ARRAY_BUFFER,
14068
+ base64EncodeArrayBuffer(value)
14069
+ ];
14067
14070
  }
14068
14071
  if (value instanceof Uint8Array) {
14069
14072
  return [JSON_COMPAT_UINT8_ARRAY, base64EncodeUint8Array(value)];
@@ -14602,7 +14605,7 @@ function Config({ initialBufferLength = 1024, maxBufferLength = 1024 * 1024 * 32
14602
14605
  };
14603
14606
  }
14604
14607
 
14605
- // ../rivetkit/dist/tsup/chunk-6D2WRHJV.js
14608
+ // ../rivetkit/dist/tsup/chunk-CQ23UFQ4.js
14606
14609
  var config2 = /* @__PURE__ */ Config({});
14607
14610
  function readWorkflowCbor(bc) {
14608
14611
  return readData(bc);
@@ -15447,7 +15450,35 @@ function removePrefixFromKey(prefixedKey) {
15447
15450
  return prefixedKey.slice(KEYS.KV.length);
15448
15451
  }
15449
15452
 
15450
- // ../rivetkit/dist/tsup/chunk-YHPFCYL3.js
15453
+ // ../rivetkit/dist/tsup/chunk-7AFZMFPQ.js
15454
+ var MIGRATION_TRANSACTION_TIMEOUT_MS = 5 * 6e4;
15455
+ var AsyncMutex = class {
15456
+ #locked = false;
15457
+ #waiting = [];
15458
+ async acquire() {
15459
+ while (this.#locked) {
15460
+ await new Promise((resolve) => this.#waiting.push(resolve));
15461
+ }
15462
+ this.#locked = true;
15463
+ }
15464
+ release() {
15465
+ this.#locked = false;
15466
+ const next = this.#waiting.shift();
15467
+ if (next) {
15468
+ next();
15469
+ }
15470
+ }
15471
+ async run(fn) {
15472
+ await this.acquire();
15473
+ try {
15474
+ return await fn();
15475
+ } finally {
15476
+ this.release();
15477
+ }
15478
+ }
15479
+ };
15480
+
15481
+ // ../rivetkit/dist/tsup/chunk-X25YYVFL.js
15451
15482
  function logger() {
15452
15483
  return getLogger("actor-client");
15453
15484
  }
@@ -15485,35 +15516,7 @@ async function importWebSocket() {
15485
15516
  return webSocketPromise;
15486
15517
  }
15487
15518
 
15488
- // ../rivetkit/dist/tsup/chunk-7AFZMFPQ.js
15489
- var MIGRATION_TRANSACTION_TIMEOUT_MS = 5 * 6e4;
15490
- var AsyncMutex = class {
15491
- #locked = false;
15492
- #waiting = [];
15493
- async acquire() {
15494
- while (this.#locked) {
15495
- await new Promise((resolve) => this.#waiting.push(resolve));
15496
- }
15497
- this.#locked = true;
15498
- }
15499
- release() {
15500
- this.#locked = false;
15501
- const next = this.#waiting.shift();
15502
- if (next) {
15503
- next();
15504
- }
15505
- }
15506
- async run(fn) {
15507
- await this.acquire();
15508
- try {
15509
- return await fn();
15510
- } finally {
15511
- this.release();
15512
- }
15513
- }
15514
- };
15515
-
15516
- // ../rivetkit/dist/tsup/chunk-YU3C5OCU.js
15519
+ // ../rivetkit/dist/tsup/chunk-MQDQ3A72.js
15517
15520
  var import_invariant2 = __toESM(require_invariant(), 1);
15518
15521
 
15519
15522
  // ../../../node_modules/.pnpm/p-retry@6.2.1/node_modules/p-retry/index.js
@@ -15691,7 +15694,7 @@ function createVersionedDataHandler(config3) {
15691
15694
  return new VersionedDataHandler(config3);
15692
15695
  }
15693
15696
 
15694
- // ../rivetkit/dist/tsup/chunk-YU3C5OCU.js
15697
+ // ../rivetkit/dist/tsup/chunk-MQDQ3A72.js
15695
15698
  var import_invariant3 = __toESM(require_invariant(), 1);
15696
15699
  var import_invariant4 = __toESM(require_invariant(), 1);
15697
15700
  var PATH_CONNECT = "/connect";
@@ -15700,6 +15703,7 @@ var PATH_WEBSOCKET_PREFIX = "/websocket/";
15700
15703
  var HEADER_ACTOR_QUERY = "x-rivet-query";
15701
15704
  var HEADER_ENCODING = "x-rivet-encoding";
15702
15705
  var HEADER_CONN_PARAMS = "x-rivet-conn-params";
15706
+ var HEADER_ORIGINAL_REQUEST_URL = "x-rivet-internal-original-request-url";
15703
15707
  var HEADER_ACTOR_ID = "x-rivet-actor";
15704
15708
  var HEADER_ACTOR_GENERATION = "x-rivet-actor-generation";
15705
15709
  var HEADER_ACTOR_KEY = "x-rivet-actor-key";
@@ -17752,6 +17756,18 @@ async function checkForSchedulingError(group, code, actorId, query, driver) {
17752
17756
  }
17753
17757
  return null;
17754
17758
  }
17759
+ function isUrlLike(value) {
17760
+ return typeof value === "object" && value !== null && typeof value.href === "string" && typeof value.pathname === "string" && typeof value.search === "string";
17761
+ }
17762
+ function isRequestLike(value) {
17763
+ return typeof value === "object" && value !== null && typeof value.url === "string" && typeof value.method === "string" && isHeadersLike(value.headers);
17764
+ }
17765
+ function isResponseLike(value) {
17766
+ return typeof value === "object" && value !== null && typeof value.status === "number" && isHeadersLike(value.headers) && typeof value.arrayBuffer === "function";
17767
+ }
17768
+ function isHeadersLike(value) {
17769
+ return typeof value === "object" && value !== null && typeof value.entries === "function";
17770
+ }
17755
17771
  function* walkErrorChain(error46, maxDepth = 8) {
17756
17772
  let current = error46;
17757
17773
  let depth = 0;
@@ -18177,14 +18193,17 @@ function createQueueSender(senderOptions) {
18177
18193
  }
18178
18194
  async function rawHttpFetch(driver, target, params, input, init, options = {}) {
18179
18195
  let path2;
18196
+ let originalUrl;
18180
18197
  let mergedInit = init || {};
18181
18198
  if (typeof input === "string") {
18182
18199
  path2 = input;
18183
- } else if (input instanceof URL) {
18200
+ } else if (isUrlLike(input)) {
18184
18201
  path2 = input.pathname + input.search;
18185
- } else if (input instanceof Request) {
18202
+ originalUrl = input.toString();
18203
+ } else if (isRequestLike(input)) {
18186
18204
  const url2 = new URL(input.url);
18187
18205
  path2 = url2.pathname + url2.search;
18206
+ originalUrl = url2.toString();
18188
18207
  const requestHeaders = new Headers(input.headers);
18189
18208
  const initHeaders = new Headers((init == null ? void 0 : init.headers) || {});
18190
18209
  const mergedHeaders = new Headers(requestHeaders);
@@ -18226,6 +18245,10 @@ async function rawHttpFetch(driver, target, params, input, init, options = {}) {
18226
18245
  const normalizedPath = path2.startsWith("/") ? path2.slice(1) : path2;
18227
18246
  const url2 = new URL(`http://actor/request/${normalizedPath}`);
18228
18247
  const proxyRequestHeaders = new Headers(mergedInit.headers);
18248
+ proxyRequestHeaders.delete(HEADER_ORIGINAL_REQUEST_URL);
18249
+ if (originalUrl) {
18250
+ proxyRequestHeaders.set(HEADER_ORIGINAL_REQUEST_URL, originalUrl);
18251
+ }
18229
18252
  if (params) {
18230
18253
  proxyRequestHeaders.set(HEADER_CONN_PARAMS, JSON.stringify(params));
18231
18254
  }
@@ -18694,6 +18717,7 @@ var ActorHandleRaw = class {
18694
18717
  async #fetchWithResolvedActor(input, init) {
18695
18718
  const maxAttempts = this.#getDynamicQueryMaxAttempts();
18696
18719
  let useQueryTarget = false;
18720
+ const retryableRequest = isRequestLike(input) ? input.clone() : void 0;
18697
18721
  const { skipReadyWait, ...requestInit } = init ?? {};
18698
18722
  const gatewayOptions = resolveActorGatewayOptions(
18699
18723
  this.#gatewayOptions,
@@ -18713,7 +18737,7 @@ var ActorHandleRaw = class {
18713
18737
  this.#driver,
18714
18738
  target,
18715
18739
  this.#params,
18716
- input,
18740
+ retryableRequest ? retryableRequest.clone() : input,
18717
18741
  requestInit,
18718
18742
  gatewayOptions
18719
18743
  );
@@ -20446,23 +20470,19 @@ async function sendHttpRequestToGateway(runConfig, gatewayUrl, actorRequest, opt
20446
20470
  if (actorRequest.bodyUsed) {
20447
20471
  throw new Error("Request body has already been consumed");
20448
20472
  }
20449
- const reqBody = await actorRequest.arrayBuffer();
20450
- if (reqBody.byteLength !== 0) {
20451
- bodyToSend = reqBody;
20473
+ if (actorRequest.body) {
20474
+ bodyToSend = actorRequest.body;
20452
20475
  guardHeaders.delete("transfer-encoding");
20453
20476
  guardHeaders.delete("content-length");
20454
20477
  }
20455
20478
  }
20456
- const guardRequest = new Request(gatewayUrl, {
20479
+ return fetch(gatewayUrl, {
20457
20480
  method: actorRequest.method,
20458
20481
  headers: guardHeaders,
20459
20482
  body: bodyToSend,
20460
- signal: actorRequest.signal
20483
+ signal: actorRequest.signal,
20484
+ ...bodyToSend ? { duplex: "half" } : {}
20461
20485
  });
20462
- return mutableResponse(await fetch(guardRequest));
20463
- }
20464
- function mutableResponse(fetchRes) {
20465
- return new Response(fetchRes.body, fetchRes);
20466
20486
  }
20467
20487
  function buildGuardHeaders(runConfig, actorRequest, options) {
20468
20488
  const headers = new Headers();
@@ -23936,6 +23956,36 @@ function toNapiSqlBatchStatement(statement) {
23936
23956
  function toNapiBuffer(value) {
23937
23957
  return Buffer.from(value);
23938
23958
  }
23959
+ function toNapiApplication(application) {
23960
+ return async (error46, request) => {
23961
+ if (error46) throw error46;
23962
+ if (!request) {
23963
+ throw new Error("application fetch callback received no request");
23964
+ }
23965
+ const response = await application(
23966
+ {
23967
+ ...request,
23968
+ body: new Uint8Array(request.body),
23969
+ cancelToken: request.cancelToken
23970
+ },
23971
+ request.responseBodyStream ? fromNapiHttpResponseBodyStream(
23972
+ request.responseBodyStream
23973
+ ) : void 0
23974
+ );
23975
+ return {
23976
+ ...response,
23977
+ body: response.body === void 0 ? void 0 : toNapiBuffer(response.body)
23978
+ };
23979
+ };
23980
+ }
23981
+ function fromNapiHttpResponseBodyStream(stream) {
23982
+ return {
23983
+ cancelled: () => stream.cancelled(),
23984
+ write: (chunk) => stream.write(Buffer.from(chunk)),
23985
+ end: () => stream.end(),
23986
+ error: (message) => stream.error(message)
23987
+ };
23988
+ }
23939
23989
  function toNapiHttpRequest(request) {
23940
23990
  if (!request) {
23941
23991
  return request;
@@ -24042,12 +24092,25 @@ var NapiCoreRuntime = class {
24042
24092
  );
24043
24093
  }
24044
24094
  async serveListener(registry2, listener, config3) {
24095
+ const application = listener.application ? toNapiApplication(listener.application) : void 0;
24045
24096
  await asNativeRegistry(registry2).serveListener(
24046
24097
  {
24047
24098
  port: listener.port,
24048
24099
  host: listener.host,
24049
24100
  publicDir: listener.publicDir
24050
24101
  },
24102
+ config3,
24103
+ application
24104
+ );
24105
+ }
24106
+ async serveApplicationListener(registry2, listener, config3) {
24107
+ await asNativeRegistry(registry2).serveApplicationListener(
24108
+ {
24109
+ port: listener.port,
24110
+ host: listener.host,
24111
+ publicDir: listener.publicDir
24112
+ },
24113
+ toNapiApplication(listener.application),
24051
24114
  config3
24052
24115
  );
24053
24116
  }
@@ -24434,6 +24497,135 @@ async function loadNapiRuntime() {
24434
24497
  runtime: new NapiCoreRuntime(bindings)
24435
24498
  };
24436
24499
  }
24500
+ var HTTP_BODY_CHUNK_SIZE = 64 * 1024;
24501
+ function runtimeBytesToArrayBuffer(value) {
24502
+ return value.buffer.slice(
24503
+ value.byteOffset,
24504
+ value.byteOffset + value.byteLength
24505
+ );
24506
+ }
24507
+ function buildNativeHttpRequest(init) {
24508
+ var _a2;
24509
+ const headers = new Headers(init.headers);
24510
+ const originalUrl = headers.get(HEADER_ORIGINAL_REQUEST_URL);
24511
+ headers.delete(HEADER_ORIGINAL_REQUEST_URL);
24512
+ const url2 = originalUrl ?? (init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString());
24513
+ const method2 = init.method.toUpperCase();
24514
+ const bodyForbidden = method2 === "GET" || method2 === "HEAD";
24515
+ const body = bodyForbidden ? void 0 : init.bodyStream ? new ReadableStream({
24516
+ async pull(controller) {
24517
+ var _a22, _b;
24518
+ try {
24519
+ if (init.body && init.body.length > 0) {
24520
+ controller.enqueue(new Uint8Array(init.body));
24521
+ init.body = void 0;
24522
+ return;
24523
+ }
24524
+ const chunk = await ((_a22 = init.bodyStream) == null ? void 0 : _a22.read());
24525
+ if (!chunk) {
24526
+ controller.close();
24527
+ } else {
24528
+ controller.enqueue(new Uint8Array(chunk));
24529
+ }
24530
+ } catch (error46) {
24531
+ (_b = init.abortController) == null ? void 0 : _b.abort(error46);
24532
+ controller.error(error46);
24533
+ }
24534
+ },
24535
+ async cancel() {
24536
+ var _a22;
24537
+ await ((_a22 = init.bodyStream) == null ? void 0 : _a22.cancel());
24538
+ }
24539
+ }) : init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
24540
+ const streamInit = init.bodyStream && !bodyForbidden ? { duplex: "half" } : {};
24541
+ return new Request(url2, {
24542
+ method: method2,
24543
+ headers,
24544
+ body,
24545
+ signal: ((_a2 = init.abortController) == null ? void 0 : _a2.signal) ?? init.signal,
24546
+ ...streamInit
24547
+ });
24548
+ }
24549
+ async function cancelNativeHttpRequestBody(bodyStream) {
24550
+ await (bodyStream == null ? void 0 : bodyStream.cancel());
24551
+ }
24552
+ async function writeResponseChunk(stream, chunk) {
24553
+ for (let offset = 0; offset < chunk.byteLength; offset += HTTP_BODY_CHUNK_SIZE) {
24554
+ await stream.write(
24555
+ chunk.subarray(offset, offset + HTTP_BODY_CHUNK_SIZE)
24556
+ );
24557
+ }
24558
+ }
24559
+ async function pumpResponseBody(reader, stream) {
24560
+ var _a2;
24561
+ const cancelled = stream.cancelled().then(() => ({ cancelled: true }));
24562
+ try {
24563
+ for (; ; ) {
24564
+ const read = reader.read().then((next2) => ({ cancelled: false, next: next2 }));
24565
+ const result = await Promise.race([read, cancelled]);
24566
+ if (result.cancelled) {
24567
+ await reader.cancel(
24568
+ new Error("native http response stream receiver dropped")
24569
+ );
24570
+ return;
24571
+ }
24572
+ const { next } = result;
24573
+ if (next.done) {
24574
+ await stream.end();
24575
+ return;
24576
+ }
24577
+ if ((_a2 = next.value) == null ? void 0 : _a2.byteLength) {
24578
+ await writeResponseChunk(stream, next.value);
24579
+ }
24580
+ }
24581
+ } catch (error46) {
24582
+ try {
24583
+ await stream.error(stringifyError(error46));
24584
+ } catch (streamError) {
24585
+ logger22().debug({
24586
+ msg: "failed to report native http response stream error",
24587
+ error: streamError
24588
+ });
24589
+ }
24590
+ try {
24591
+ await reader.cancel(error46);
24592
+ } catch {
24593
+ }
24594
+ } finally {
24595
+ reader.releaseLock();
24596
+ }
24597
+ }
24598
+ async function convertNativeHttpResponse(response, responseBodyStream) {
24599
+ const headers = Object.fromEntries(response.headers.entries());
24600
+ if (!response.body) {
24601
+ return {
24602
+ response: {
24603
+ status: response.status,
24604
+ headers,
24605
+ body: new Uint8Array()
24606
+ }
24607
+ };
24608
+ }
24609
+ if (responseBodyStream) {
24610
+ const reader = response.body.getReader();
24611
+ const bodyCompletion = pumpResponseBody(reader, responseBodyStream);
24612
+ return {
24613
+ response: {
24614
+ status: response.status,
24615
+ headers,
24616
+ stream: true
24617
+ },
24618
+ bodyCompletion
24619
+ };
24620
+ }
24621
+ return {
24622
+ response: {
24623
+ status: response.status,
24624
+ headers,
24625
+ body: new Uint8Array(await response.arrayBuffer())
24626
+ }
24627
+ };
24628
+ }
24437
24629
  var CONN_PARAMS_KEY = "__conn_params__";
24438
24630
  function validateActionArgs(schemas, name, args) {
24439
24631
  if (!(schemas == null ? void 0 : schemas[name])) {
@@ -24703,6 +24895,11 @@ var WasmCoreRuntime = class {
24703
24895
  "registry.listen() is not supported on the wasm runtime; use registry.serve() and mount the handler in your platform's HTTP server instead"
24704
24896
  );
24705
24897
  }
24898
+ async serveApplicationListener(_registry, _listener, _config) {
24899
+ throw new Error(
24900
+ "registry.listen() is not supported on the wasm runtime; use an application-owned HTTP server instead"
24901
+ );
24902
+ }
24706
24903
  createActorFactory(callbacks, config3) {
24707
24904
  return callWasmSync(
24708
24905
  () => asActorFactoryHandle2(
@@ -25555,7 +25752,7 @@ function toRuntimeBytes(value) {
25555
25752
  function arrayBufferViewToRuntimeBytes(value) {
25556
25753
  return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
25557
25754
  }
25558
- function runtimeBytesToArrayBuffer(value) {
25755
+ function runtimeBytesToArrayBuffer2(value) {
25559
25756
  return value.buffer.slice(
25560
25757
  value.byteOffset,
25561
25758
  value.byteOffset + value.byteLength
@@ -25885,24 +26082,6 @@ function decodeArgs(value) {
25885
26082
  const decoded = decodeValue(value);
25886
26083
  return normalizeArgs(decoded);
25887
26084
  }
25888
- function buildRequest(init) {
25889
- const url2 = init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString();
25890
- const body = init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
25891
- return new Request(url2, {
25892
- method: init.method,
25893
- headers: init.headers,
25894
- body
25895
- });
25896
- }
25897
- async function toRuntimeHttpResponse(response) {
25898
- const headers = Object.fromEntries(response.headers.entries());
25899
- const body = new Uint8Array(await response.arrayBuffer());
25900
- return {
25901
- status: response.status,
25902
- headers,
25903
- body
25904
- };
25905
- }
25906
26085
  function toActorKey(segments) {
25907
26086
  return segments.map(
25908
26087
  (segment) => segment.kind === "number" ? String(segment.numberValue ?? 0) : segment.stringValue ?? ""
@@ -26567,7 +26746,7 @@ var NativeWebSocketAdapter = class {
26567
26746
  this.#runtime.webSocketSetEventCallback(this.#ws, (event2) => {
26568
26747
  if (event2.kind === "message") {
26569
26748
  this.#virtual.triggerMessage(
26570
- event2.binary ? runtimeBytesToArrayBuffer(event2.data) : event2.data,
26749
+ event2.binary ? runtimeBytesToArrayBuffer2(event2.data) : event2.data,
26571
26750
  event2.messageIndex
26572
26751
  );
26573
26752
  return;
@@ -27799,12 +27978,14 @@ function buildNativeFactory(runtime, registryConfig, definition) {
27799
27978
  onStateChange,
27800
27979
  cancelToken
27801
27980
  );
27802
- const maybeHandleNativeInspectorRequest = async (ctx, _rawRequest, jsRequest) => {
27981
+ const maybeHandleNativeInspectorRequest = async (ctx, rawRequest) => {
27803
27982
  var _a22, _b, _c, _d;
27804
- const url2 = new URL(jsRequest.url);
27983
+ const rawUrl = rawRequest.uri.startsWith("http") ? rawRequest.uri : new URL(rawRequest.uri, "http://127.0.0.1").toString();
27984
+ const url2 = new URL(rawUrl);
27805
27985
  if (!url2.pathname.startsWith("/inspector/")) {
27806
27986
  return void 0;
27807
27987
  }
27988
+ const jsRequest = buildNativeHttpRequest(rawRequest);
27808
27989
  const jsonResponse = (body, init) => new Response(JSON.stringify(body), {
27809
27990
  status: (init == null ? void 0 : init.status) ?? 200,
27810
27991
  headers: {
@@ -28335,7 +28516,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28335
28516
  );
28336
28517
  const actorCtx = makeActorCtx(
28337
28518
  ctx,
28338
- request ? buildRequest(request) : void 0
28519
+ request ? buildNativeHttpRequest(request) : void 0
28339
28520
  );
28340
28521
  try {
28341
28522
  await config3.onBeforeConnect(
@@ -28355,7 +28536,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28355
28536
  const { ctx, conn, params, request } = unwrapTsfnPayload(error46, payload);
28356
28537
  const actorCtx = makeActorCtx(
28357
28538
  ctx,
28358
- request ? buildRequest(request) : void 0
28539
+ request ? buildNativeHttpRequest(request) : void 0
28359
28540
  );
28360
28541
  const connAdapter = new NativeConnAdapter(
28361
28542
  runtime,
@@ -28392,7 +28573,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28392
28573
  );
28393
28574
  const actorCtx = makeActorCtx(
28394
28575
  ctx,
28395
- request ? buildRequest(request) : void 0
28576
+ request ? buildNativeHttpRequest(request) : void 0
28396
28577
  );
28397
28578
  const connAdapter = new NativeConnAdapter(
28398
28579
  runtime,
@@ -28497,27 +28678,45 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28497
28678
  onRequest: wrapNativeCallback(
28498
28679
  async (error46, payload) => {
28499
28680
  try {
28500
- const { ctx, request, cancelToken } = unwrapTsfnPayload(
28501
- error46,
28502
- payload
28503
- );
28504
- const jsRequest = buildRequest(request);
28505
- const inspectorResponse = await maybeHandleNativeInspectorRequest(
28506
- ctx,
28507
- request,
28508
- jsRequest
28509
- );
28681
+ const { ctx, request, cancelToken, responseBodyStream } = unwrapTsfnPayload(error46, payload);
28682
+ const inspectorResponse = await maybeHandleNativeInspectorRequest(ctx, request);
28510
28683
  if (inspectorResponse) {
28511
- return await toRuntimeHttpResponse(inspectorResponse);
28684
+ await cancelNativeHttpRequestBody(request.bodyStream);
28685
+ return (await convertNativeHttpResponse(
28686
+ inspectorResponse,
28687
+ responseBodyStream
28688
+ )).response;
28512
28689
  }
28513
28690
  if (typeof config3.onRequest !== "function") {
28514
- return await toRuntimeHttpResponse(
28515
- new Response(null, { status: 404 })
28516
- );
28691
+ await cancelNativeHttpRequestBody(request.bodyStream);
28692
+ return (await convertNativeHttpResponse(
28693
+ new Response(null, { status: 404 }),
28694
+ responseBodyStream
28695
+ )).response;
28517
28696
  }
28518
- const rawConnParams = jsRequest.headers.get(HEADER_CONN_PARAMS);
28697
+ const requestAbortController = new AbortController();
28698
+ const handlerRequest = buildNativeHttpRequest({
28699
+ ...request,
28700
+ abortController: requestAbortController
28701
+ });
28702
+ const rawConnParams = handlerRequest.headers.get(HEADER_CONN_PARAMS);
28519
28703
  let requestCtx;
28520
28704
  let conn;
28705
+ let removeRequestAbortListener;
28706
+ let cleanupDeferredToBody = false;
28707
+ let cleanedUp = false;
28708
+ const cleanupRequest = async () => {
28709
+ if (cleanedUp) return;
28710
+ cleanedUp = true;
28711
+ removeRequestAbortListener == null ? void 0 : removeRequestAbortListener();
28712
+ try {
28713
+ await (requestCtx == null ? void 0 : requestCtx.dispose());
28714
+ } finally {
28715
+ if (conn) {
28716
+ await runtime.connDisconnect(conn);
28717
+ }
28718
+ }
28719
+ };
28521
28720
  try {
28522
28721
  const connParams = validateConnParams(
28523
28722
  schemaConfig.connParamsSchema,
@@ -28533,23 +28732,56 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28533
28732
  requestCtx = makeConnCtx(
28534
28733
  ctx,
28535
28734
  conn,
28536
- jsRequest,
28735
+ handlerRequest,
28537
28736
  cancelToken
28538
28737
  );
28738
+ const ctxAbortSignal = requestCtx.abortSignal;
28739
+ const abortRequest = () => requestAbortController.abort(ctxAbortSignal.reason);
28740
+ if (ctxAbortSignal.aborted) {
28741
+ abortRequest();
28742
+ } else {
28743
+ ctxAbortSignal.addEventListener(
28744
+ "abort",
28745
+ abortRequest,
28746
+ { once: true }
28747
+ );
28748
+ removeRequestAbortListener = () => ctxAbortSignal.removeEventListener(
28749
+ "abort",
28750
+ abortRequest
28751
+ );
28752
+ }
28539
28753
  const response = await config3.onRequest(
28540
28754
  requestCtx,
28541
- jsRequest
28755
+ handlerRequest
28542
28756
  );
28543
- if (!(response instanceof Response)) {
28757
+ if (!isResponseLike(response)) {
28544
28758
  throw new Error(
28545
28759
  "onRequest handler must return a Response"
28546
28760
  );
28547
28761
  }
28548
- return await toRuntimeHttpResponse(response);
28762
+ const conversion = await convertNativeHttpResponse(
28763
+ response,
28764
+ responseBodyStream
28765
+ );
28766
+ if (conversion.bodyCompletion) {
28767
+ cleanupDeferredToBody = true;
28768
+ void conversion.bodyCompletion.then(cleanupRequest).catch((cleanupError) => {
28769
+ logger22().error({
28770
+ msg: "failed to clean up native streaming http request",
28771
+ error: cleanupError
28772
+ });
28773
+ });
28774
+ }
28775
+ return conversion.response;
28549
28776
  } finally {
28550
- await (requestCtx == null ? void 0 : requestCtx.dispose());
28551
- if (conn) {
28552
- await runtime.connDisconnect(conn);
28777
+ try {
28778
+ await cancelNativeHttpRequestBody(
28779
+ request.bodyStream
28780
+ );
28781
+ } finally {
28782
+ if (!cleanupDeferredToBody) {
28783
+ await cleanupRequest();
28784
+ }
28553
28785
  }
28554
28786
  }
28555
28787
  } catch (error210) {
@@ -28564,7 +28796,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28564
28796
  onWebSocket: typeof config3.onWebSocket === "function" ? wrapNativeCallback(
28565
28797
  async (error46, payload) => {
28566
28798
  const { ctx, conn, ws, request } = unwrapTsfnPayload(error46, payload);
28567
- const jsRequest = request ? buildRequest(request) : void 0;
28799
+ const jsRequest = request ? buildNativeHttpRequest(request) : void 0;
28568
28800
  const actorCtx = makeConnCtx(ctx, conn, jsRequest);
28569
28801
  try {
28570
28802
  await config3.onWebSocket(
@@ -28661,7 +28893,7 @@ function buildNativeFactory(runtime, registryConfig, definition) {
28661
28893
  timeoutMs,
28662
28894
  cancelToken
28663
28895
  } = unwrapTsfnPayload(error46, payload);
28664
- const jsRequest = buildRequest(request);
28896
+ const jsRequest = buildNativeHttpRequest(request);
28665
28897
  const actorCtx = withConnContext(
28666
28898
  runtime,
28667
28899
  ctx,
@@ -28810,6 +29042,54 @@ function finishShutdownSignal(signal) {
28810
29042
  }
28811
29043
  process.kill(process.pid, signal);
28812
29044
  }
29045
+ function createApplicationFetch(application, runtime) {
29046
+ return async (request, responseBodyStream) => {
29047
+ const method2 = request.method.toUpperCase();
29048
+ const body = method2 === "GET" || method2 === "HEAD" || request.body.length === 0 ? void 0 : Uint8Array.from(request.body).buffer;
29049
+ const abortController = new AbortController();
29050
+ if (request.cancelToken) {
29051
+ if (runtime.cancellationTokenAborted(request.cancelToken)) {
29052
+ abortController.abort();
29053
+ } else {
29054
+ runtime.onCancellationTokenCancelled(
29055
+ request.cancelToken,
29056
+ () => abortController.abort()
29057
+ );
29058
+ }
29059
+ }
29060
+ const response = await application.fetch(
29061
+ new Request(request.url, {
29062
+ method: method2,
29063
+ headers: request.headers,
29064
+ body,
29065
+ signal: abortController.signal
29066
+ })
29067
+ );
29068
+ if (!isResponseLike(response)) {
29069
+ throw new TypeError(
29070
+ "registry.listen() application fetch must return a Response"
29071
+ );
29072
+ }
29073
+ const conversion = await convertNativeHttpResponse(
29074
+ response,
29075
+ responseBodyStream
29076
+ );
29077
+ if (conversion.bodyCompletion) {
29078
+ void conversion.bodyCompletion.catch((error46) => {
29079
+ logger22().error({
29080
+ msg: "application response stream failed",
29081
+ error: error46
29082
+ });
29083
+ });
29084
+ }
29085
+ return {
29086
+ status: conversion.response.status ?? response.status,
29087
+ headers: conversion.response.headers ?? Object.fromEntries(response.headers.entries()),
29088
+ body: conversion.response.body,
29089
+ stream: conversion.response.stream
29090
+ };
29091
+ };
29092
+ }
28813
29093
  var Registry = class {
28814
29094
  #config;
28815
29095
  #buildConfiguredRegistry;
@@ -28825,6 +29105,7 @@ var Registry = class {
28825
29105
  #runtimeReadyPromise;
28826
29106
  #runtimeServeConfiguredPromise;
28827
29107
  #runtimeServerlessPromise;
29108
+ #applicationListenerPromise;
28828
29109
  #configureServerlessPoolPromise;
28829
29110
  #welcomePrinted = false;
28830
29111
  #shutdownInstalled = false;
@@ -29050,18 +29331,67 @@ var Registry = class {
29050
29331
  * @param opts.host Address to bind. Defaults to `0.0.0.0`.
29051
29332
  * @param opts.publicDir If set, serves static files from this directory
29052
29333
  * as a fallback below the framework routes.
29334
+ * @param opts.application If set, handles requests that do not match a
29335
+ * framework route.
29053
29336
  *
29054
29337
  * @example
29055
29338
  * ```ts
29056
29339
  * await registry.listen();
29057
- * await registry.listen({ port: 8080, publicDir: "./public" });
29340
+ * await registry.listen({ application: app });
29058
29341
  * ```
29059
29342
  */
29060
29343
  async listen(opts = {}) {
29061
29344
  const port = opts.port ?? parsePortEnv(process.env.RIVET_PORT) ?? 3e3;
29062
29345
  const publicDir = opts.publicDir ?? getRivetkitPublicDir();
29063
29346
  const config3 = this.parseConfig();
29064
- const configuredRegistryPromise = buildConfiguredRegistry(config3);
29347
+ if (opts.application && getRivetkitRuntimeMode() !== "serverless") {
29348
+ if (config3.runtime === "wasm") {
29349
+ throw new Error(
29350
+ "registry.listen() requires the native runtime; use an application-owned HTTP server with WebAssembly"
29351
+ );
29352
+ }
29353
+ this.#installSignalHandlers(config3);
29354
+ this.#printWelcome(config3, "serverful", {
29355
+ port,
29356
+ host: opts.host,
29357
+ publicDir
29358
+ });
29359
+ this.#startEnvoy(config3, true);
29360
+ const readyPromise = this.startAndWait();
29361
+ const configuredRegistryPromise2 = this.#runtimeServeConfiguredPromise;
29362
+ if (!configuredRegistryPromise2) {
29363
+ throw new Error("registry envoy startup did not initialize");
29364
+ }
29365
+ const { runtime: runtime2, registry: registry22, serveConfig: serveConfig2 } = await configuredRegistryPromise2;
29366
+ const application2 = createApplicationFetch(
29367
+ opts.application,
29368
+ runtime2
29369
+ );
29370
+ await readyPromise;
29371
+ const listenerPromise = runtime2.serveApplicationListener(
29372
+ registry22,
29373
+ {
29374
+ port,
29375
+ host: opts.host,
29376
+ publicDir,
29377
+ application: application2
29378
+ },
29379
+ serveConfig2
29380
+ );
29381
+ this.#applicationListenerPromise = listenerPromise;
29382
+ const serveLifecyclePromise = this.#runtimeServeLifecyclePromise;
29383
+ if (!serveLifecyclePromise) {
29384
+ throw new Error(
29385
+ "registry envoy serve lifecycle did not initialize"
29386
+ );
29387
+ }
29388
+ await Promise.all([
29389
+ listenerPromise,
29390
+ serveLifecyclePromise
29391
+ ]);
29392
+ return;
29393
+ }
29394
+ const configuredRegistryPromise = this.#buildConfiguredRegistry(config3);
29065
29395
  this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
29066
29396
  this.#runtimeServerlessPromise = configuredRegistryPromise;
29067
29397
  this.#installSignalHandlers(config3);
@@ -29072,9 +29402,15 @@ var Registry = class {
29072
29402
  });
29073
29403
  this.#ensureServerlessPoolConfigured(config3);
29074
29404
  const { runtime, registry: registry2, serveConfig } = await configuredRegistryPromise;
29405
+ const application = opts.application ? createApplicationFetch(opts.application, runtime) : void 0;
29075
29406
  await runtime.serveListener(
29076
29407
  registry2,
29077
- { port, host: opts.host, publicDir },
29408
+ {
29409
+ port,
29410
+ host: opts.host,
29411
+ publicDir,
29412
+ application
29413
+ },
29078
29414
  serveConfig
29079
29415
  );
29080
29416
  }
@@ -29174,11 +29510,9 @@ var Registry = class {
29174
29510
  await runtime.serveRegistry(registry2, serveConfig);
29175
29511
  }
29176
29512
  );
29177
- this.#runtimeServePromise = this.#runtimeServeLifecyclePromise.catch(
29178
- (error46) => {
29179
- logger22().warn({ error: error46 }, "runtime registry serve errored");
29180
- }
29181
- );
29513
+ this.#runtimeServePromise = this.#runtimeServeLifecyclePromise.catch((error46) => {
29514
+ logger22().warn({ error: error46 }, "runtime registry serve errored");
29515
+ });
29182
29516
  this.#installSignalHandlers(config3);
29183
29517
  }
29184
29518
  if (printWelcome) {
@@ -29285,6 +29619,9 @@ var Registry = class {
29285
29619
  if (runtimeServePromise !== void 0) {
29286
29620
  await runtimeServePromise.catch(() => void 0);
29287
29621
  }
29622
+ if (this.#applicationListenerPromise !== void 0) {
29623
+ await this.#applicationListenerPromise.catch(() => void 0);
29624
+ }
29288
29625
  };
29289
29626
  await Promise.race([
29290
29627
  drain(),
@@ -29335,7 +29672,9 @@ var Registry = class {
29335
29672
  startAndWait() {
29336
29673
  if (this.#shutdownInFlight !== null) {
29337
29674
  return Promise.reject(
29338
- new Error("registry.startAndWait() cannot run after shutdown has begun")
29675
+ new Error(
29676
+ "registry.startAndWait() cannot run after shutdown has begun"
29677
+ )
29339
29678
  );
29340
29679
  }
29341
29680
  if (this.#runtimeReadyPromise) return this.#runtimeReadyPromise;
@@ -29376,7 +29715,9 @@ var Registry = class {
29376
29715
  const readinessPromise = (async () => {
29377
29716
  const { runtime, registry: registry2 } = await configuredRegistryPromise;
29378
29717
  const stoppedBeforeReady = serveLifecyclePromise.then(() => {
29379
- throw new Error("RivetKit registry stopped before becoming ready");
29718
+ throw new Error(
29719
+ "RivetKit registry stopped before becoming ready"
29720
+ );
29380
29721
  });
29381
29722
  await Promise.race([
29382
29723
  runtime.waitRegistryReady(registry2),