{"version":3,"file":"index-workers.cjs","names":["cfw","RpcTarget","RpcStub","RpcPromise","stub","#readable","#writableHook","#fail","#readyState","#onmessage","#claim","#onclose","#onerror","#write","#writer","#release","#listeners","#claimed","#readLoop","#close","#dispatchEvent","RpcPromise","RpcStub","RpcStub","RpcSession","#session","#mainStub","newWebSocketRpcSession","RpcSession","#webSocket","#sendQueue","#receivedError","#error","#receiveResolver","#receiveRejecter","#receiveQueue","#promise","#scheduleBatch","#batchToSend","#batchToReceive","#aborted","newHttpBatchRpcSession","RpcSession","#allReceived","newMessagePortRpcSession","RpcSession","#port","#error","#receivedError","#receiveResolver","#receiveRejecter","#receiveQueue","RpcPromise","RpcStub","RpcStubImpl","RpcPromiseImpl","RpcSessionImpl","RpcTargetImpl","newWebSocketRpcSessionImpl","newHttpBatchRpcSessionImpl","newMessagePortRpcSessionImpl"],"sources":["../src/symbols.ts","../src/inject-workers-module.ts","../src/core.ts","../src/websocket-streams.ts","../src/serialize.ts","../src/rpc.ts","../src/websocket.ts","../src/batch.ts","../src/messageport.ts","../src/map.ts","../src/streams.ts","../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nexport let WORKERS_MODULE_SYMBOL = Symbol(\"workers-module\");\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { WORKERS_MODULE_SYMBOL } from \"./symbols.js\";\n\n// Import cloudflare:workers and stick it in the global scope where in can be used conditionally.\n// As long as inject-workers-module.ts is imported before the rest of the library, this allows the\n// library to set up automatic interoperability with Cloudflare Workers' built-in RPC.\n//\n// Meanwhile, we define our `exports` in package.json such that when building on Workers, this\n// module is in fact imported first.\nimport * as cfw from \"cloudflare:workers\";\n(globalThis as any)[WORKERS_MODULE_SYMBOL] = cfw;\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport type { RpcTargetBranded, __RPC_TARGET_BRAND } from \"./types.js\";\nimport { WORKERS_MODULE_SYMBOL } from \"./symbols.js\"\n\n// Polyfill Symbol.dispose for browsers that don't support it yet\nif (!Symbol.dispose) {\n  (Symbol as any).dispose = Symbol.for('dispose');\n}\nif (!Symbol.asyncDispose) {\n  (Symbol as any).asyncDispose = Symbol.for('asyncDispose');\n}\n\n// Polyfill Promise.withResolvers() for old Safari versions (ugh), Hermes (React Native), and\n// maybe others.\nif (!Promise.withResolvers) {\n  Promise.withResolvers = function<T>(): PromiseWithResolvers<T> {\n    let resolve: (value: T | PromiseLike<T>) => void;\n    let reject: (reason?: any) => void;\n    const promise = new Promise<T>((res, rej) => {\n      resolve = res;\n      reject = rej;\n    });\n    return { promise, resolve: resolve!, reject: reject! };\n  };\n}\n\nlet workersModule: any = (globalThis as any)[WORKERS_MODULE_SYMBOL];\n\nexport interface RpcTarget {\n  [__RPC_TARGET_BRAND]: never;\n};\n\nexport let RpcTarget = workersModule ? workersModule.RpcTarget : class {};\n\nexport type PropertyPath = (string | number)[];\n\ntype TypeForRpc = \"unsupported\" | \"primitive\" | \"object\" | \"function\" | \"array\" | \"date\" |\n    \"bigint\" | \"bytes\" | \"blob\" | \"stub\" | \"rpc-promise\" | \"rpc-target\" | \"rpc-thenable\" |\n    \"error\" | \"undefined\" | \"writable\" | \"readable\" | \"headers\" | \"request\" | \"response\";\n\nconst AsyncFunction = (async function () {}).constructor;\n\n// Buffer.prototype for Node.js environments, where Buffer is a Uint8Array subclass that we want\n// to accept as \"bytes\". In browsers, this is undefined, which won't match any prototype.\nlet BUFFER_PROTOTYPE: object | undefined =\n    typeof Buffer !== \"undefined\" ? Buffer.prototype : undefined;\n\nexport function typeForRpc(value: unknown): TypeForRpc {\n  switch (typeof value) {\n    case \"boolean\":\n    case \"number\":\n    case \"string\":\n      return \"primitive\";\n\n    case \"undefined\":\n      return \"undefined\";\n\n    case \"object\":\n    case \"function\":\n      // Test by prototype, below.\n      break;\n\n    case \"bigint\":\n      return \"bigint\";\n\n    default:\n      return \"unsupported\";\n  }\n\n  // Ugh JavaScript, why is `typeof null` equal to \"object\" but null isn't otherwise anything like\n  // an object?\n  if (value === null) {\n    return \"primitive\";\n  }\n\n  // Aside from RpcTarget, we generally don't support serializing *subclasses* of serializable\n  // types, so we switch on the exact prototype rather than use `instanceof` here.\n  let prototype = Object.getPrototypeOf(value);\n  switch (prototype) {\n    case Object.prototype:\n      return \"object\";\n\n    case Function.prototype:\n    case AsyncFunction.prototype:\n      return \"function\";\n\n    case Array.prototype:\n      return \"array\";\n\n    case Date.prototype:\n      return \"date\";\n\n    case Uint8Array.prototype:\n    case BUFFER_PROTOTYPE:\n    case ArrayBuffer.prototype:\n    case DataView.prototype:\n    case Int8Array.prototype:\n    case Uint8ClampedArray.prototype:\n    case Int16Array.prototype:\n    case Uint16Array.prototype:\n    case Int32Array.prototype:\n    case Uint32Array.prototype:\n    case BigInt64Array.prototype:\n    case BigUint64Array.prototype:\n    case Float32Array.prototype:\n    case Float64Array.prototype:\n      return \"bytes\";\n\n    case WritableStream.prototype:\n      return \"writable\";\n\n    case ReadableStream.prototype:\n      return \"readable\";\n\n    case Headers.prototype:\n      return \"headers\";\n\n    case Request.prototype:\n      return \"request\";\n\n    case Response.prototype:\n      return \"response\";\n\n    case Blob.prototype:\n      return \"blob\";\n\n    // TODO: Other RPC-compatible pass-by-value types.\n\n    case RpcStub.prototype:\n      return \"stub\";\n\n    case RpcPromise.prototype:\n      return \"rpc-promise\";\n\n    // TODO: Promise<T> or thenable\n\n    default:\n      if (workersModule) {\n        // TODO: We also need to match `RpcPromise` and `RpcProperty`, but they currently aren't\n        //   exported by cloudflare:workers.\n        if (prototype == workersModule.RpcStub.prototype ||\n            value instanceof workersModule.ServiceStub) {\n          return \"rpc-target\";\n        } else if (prototype == workersModule.RpcPromise.prototype ||\n                   prototype == workersModule.RpcProperty.prototype) {\n          // Like rpc-target, but should be wrapped in RpcPromise, so that it can be pull()ed,\n          // which will await the thenable.\n          return \"rpc-thenable\";\n        }\n      }\n\n      if (value instanceof RpcTarget) {\n        return \"rpc-target\";\n      }\n\n      if (value instanceof Error) {\n        return \"error\";\n      }\n\n      return \"unsupported\";\n  }\n}\n\nfunction mapNotLoaded(): never {\n  throw new Error(\"RPC map() implementation was not loaded.\");\n}\n\n// map() is implemented in `map.ts`. We can't import it here because it would create an import\n// cycle, so instead we define two hook functions that map.ts will overwrite when it is imported.\nexport let mapImpl: MapImpl = { applyMap: mapNotLoaded, sendMap: mapNotLoaded };\n\ntype MapImpl = {\n  // Applies a map function to an input value (usually an array).\n  applyMap(input: unknown, parent: object | undefined, owner: RpcPayload | null,\n           captures: StubHook[], instructions: unknown[])\n          : StubHook;\n\n  // Implements the .map() method of RpcStub.\n  sendMap(hook: StubHook, path: PropertyPath, func: (value: RpcPromise) => unknown)\n         : RpcPromise;\n}\n\nfunction streamNotLoaded(): never {\n  throw new Error(\"Stream implementation was not loaded.\");\n}\n\n// Stream support is implemented in `streams.ts`. We can't import it here because it would create\n// an import cycle, so instead we define hook functions that streams.ts will overwrite.\nexport let streamImpl: StreamImpl = {\n  createWritableStreamHook: streamNotLoaded,\n  createWritableStreamFromHook: streamNotLoaded,\n  createReadableStreamHook: streamNotLoaded\n};\n\nexport type StreamImpl = {\n  // Creates a StubHook wrapping a local WritableStream for export.\n  // The hook will call getWriter() on the stream, locking it.\n  createWritableStreamHook(stream: WritableStream): StubHook;\n\n  // Creates a proxy WritableStream that forwards writes to a remote hook.\n  createWritableStreamFromHook(hook: StubHook): WritableStream;\n\n  // Creates a minimal StubHook wrapping a local ReadableStream for disposal tracking.\n  // The hook's dispose() will cancel the stream.\n  createReadableStreamHook(stream: ReadableStream): StubHook;\n}\n\n/** Information about one application function invocation received over RPC. */\nexport type RpcCallInfo = {\n  /** The property path used to reach the function from the referenced capability. */\n  path: PropertyPath;\n  /** The object that owns the function, or the function itself for a callable capability. */\n  target: unknown;\n};\n\n/**\n * Wraps one local application invocation. `invoke()` must be called synchronously so Cap'n Web's\n * e-order guarantees are preserved, but the returned promise remains pending for the full call.\n */\nexport type RpcCallHandler = <T>(info: RpcCallInfo, invoke: () => Promise<T>) => Promise<T>;\n\n// Inner interface backing an RpcStub or RpcPromise.\n//\n// A hook may eventually resolve to a \"payload\".\n//\n// Declared as `abstract class` to allow `instanceof StubHook`, used by `RpcStub` constructor.\n//\n// This is conceptually similar to the Cap'n Proto C++ class `ClientHook`.\nexport abstract class StubHook {\n  // Call a function at the given property path with the given arguments. Returns a hook for the\n  // promise for the result.\n  abstract call(path: PropertyPath, args: RpcPayload): StubHook;\n\n  // Like call(), but designed for streaming calls (e.g. WritableStream writes). Returns:\n  // - promise: A Promise<void> for the completion of the call.\n  // - size: If the call was remote, the byte size of the serialized message. For local calls,\n  //   undefined is returned, indicating the caller should await the promise to serialize writes\n  //   (no overlapping).\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    // Default implementation: delegate to call() + pull(). No size is returned, so the caller\n    // knows this is a local call and should await the promise directly.\n    let hook = this.call(path, args);\n    let pulled = hook.pull();\n    let promise: Promise<void>;\n    if (pulled instanceof Promise) {\n      promise = pulled.then(p => { p.dispose(); });\n    } else {\n      pulled.dispose();\n      promise = Promise.resolve();\n    }\n    return { promise };\n  }\n\n  // Apply a map operation.\n  //\n  // `captures` is a list of external stubs which are used as part of the mapper function.\n  // NOTE: The callee takes ownership of `captures`.\n  //\n  // `instructions` is a JSON-serializable value describing the mapper function as a series of\n  // steps. Each step is an expression to evaluate, in the usual RPC expression format. The last\n  // instruction is the return value.\n  //\n  // Each instruction can refer to the results of any of the instructions before it, as well as to\n  // the captures, as if they were imports on the import table. In particular:\n  // * The value 0 is the input to the mapper function (e.g. one element of the array being mapped).\n  // * Positive values are 1-based indexes into the instruction table, representing the results of\n  //   previous instructions.\n  // * Negative values are -1-based indexes into the capture list.\n  abstract map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook;\n\n  // Read the property at the given path. Returns a StubHook representing a promise for that\n  // property. This behaves very similarly to call(), except that no actual function is invoked\n  // on the remote end, the property is simply returned. (Well, if the property has a getter, then\n  // that will be invoked...)\n  //\n  // (In the case that this stub is a promise with a resolution payload, get() implies cloning\n  // a branch of the payload, making a deep copy of any pass-by-value content.)\n  abstract get(path: PropertyPath): StubHook;\n\n  // Create a clone of this StubHook, which can be disposed independently.\n  //\n  // The returned hook is NOT considered a promise, so will not resolve to a payload (you can use\n  // `get([])` to get a promise for a cloned payload).\n  abstract dup(): StubHook;\n\n  // Requests resolution of a StubHook that represents a promise, and eventually produces the\n  // payload.\n  //\n  // pull() should not be called on capabilities that aren't promises. It may never resolve or it\n  // may throw an exception.\n  //\n  // If pull() is never called (on a remote promise), the RPC system will not transmit the\n  // resolution at all. This allows a promise to be used strictly for pipelining.\n  //\n  // If the payload is already available, pull() returns it immediately, instead of returning a\n  // promise. This allows the caller to skip the microtask queue which is sometimes necessary to\n  // maintain e-order guarantees.\n  //\n  // The returned RpcPayload is the same one backing the StubHook itself. If the caller delivers\n  // or disposes the payload directly, then it should not call dispose() on the hook. If the caller\n  // does not intend to consume the StubHook, the caller must take responsibility for cloning the\n  // payload.\n  //\n  // You can call pull() multiple times, but it will return the same RpcPayload every time, and\n  // that payload should only be disposed once.\n  //\n  // If pull() returns a promise which rejects, the StubHook does not need to be disposed.\n  abstract pull(): RpcPayload | Promise<RpcPayload>;\n\n  // Called to prevent this stub from generating unhandled rejection events if it throws without\n  // having been pulled. Without this, if a client \"push\"es a call that immediately throws before\n  // the client manages to \"pull\" it or use it in a pipeline, this may be treated by the system as\n  // an unhandled rejection. Unfortunately, this unhandled rejection would be reported in the\n  // callee rather than the caller, possibly causing the callee to crash or log spurious errors,\n  // even though it's really up to the caller to deal with the exception!\n  abstract ignoreUnhandledRejections(): void;\n\n  // Attempts to cancel any outstanding promise backing this hook, and disposes the payload that\n  // pull() would return (if any). If a pull() promise is outstanding, it may still resolve (with\n  // a disposed payload) or it may reject. It's safe to call dispose() multiple times.\n  abstract dispose(): void;\n\n  abstract onBroken(callback: (error: any) => void): void;\n}\n\nexport class ErrorStubHook extends StubHook {\n  constructor(private error: any) { super(); }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook { return this; }\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook { return this; }\n  get(path: PropertyPath): StubHook { return this; }\n  dup(): StubHook { return this; }\n  pull(): RpcPayload | Promise<RpcPayload> { return Promise.reject(this.error); }\n  ignoreUnhandledRejections(): void {}\n  dispose(): void {}\n  onBroken(callback: (error: any) => void): void {\n    try {\n      callback(this.error);\n    } catch (err) {\n      // Don't throw back into the RPC system. Treat this as an unhandled rejection.\n      Promise.resolve(err);\n    }\n  }\n};\n\nconst DISPOSED_HOOK: StubHook = new ErrorStubHook(\n    new Error(\"Attempted to use RPC stub after it has been disposed.\"));\n\n// A call interceptor can be used to intercept all RPC stub invocations within some synchronous\n// scope. This is used to implement record/replay\ntype CallInterceptor = (hook: StubHook, path: PropertyPath, params: RpcPayload) => StubHook;\nlet doCall: CallInterceptor = (hook: StubHook, path: PropertyPath, params: RpcPayload) => {\n  return hook.call(path, params);\n}\n\nexport function withCallInterceptor<T>(interceptor: CallInterceptor, callback: () => T): T {\n  let oldValue = doCall;\n  doCall = interceptor;\n  try {\n    return callback();\n  } finally {\n    doCall = oldValue;\n  }\n}\n\n// Private symbol which may be used to unwrap the real stub through the Proxy.\nlet RAW_STUB = Symbol(\"realStub\");\n\nexport interface RpcStub extends Disposable {\n  // Declare magic `RAW_STUB` key that unwraps the proxy.\n  [RAW_STUB]: this;\n}\n\nconst PROXY_HANDLERS: ProxyHandler<{raw: RpcStub}> = {\n  apply(target: {raw: RpcStub}, thisArg: any, argumentsList: any[]) {\n    let stub = target.raw;\n    return new RpcPromise(doCall(stub.hook,\n        stub.pathIfPromise || [], RpcPayload.fromAppParams(argumentsList)), []);\n  },\n\n  get(target: {raw: RpcStub}, prop: string | symbol, receiver: any) {\n    let stub = target.raw;\n    if (prop === RAW_STUB) {\n      return stub;\n    } else if (prop in RpcPromise.prototype) {\n      // Any method or property declared on RpcPromise (including inherited from RpcStub or\n      // Object) should pass through to the target object, as trying to turn these into RPCs will\n      // likely be problematic.\n      //\n      // Note we don't just check `prop in target` because we intentionally want to hide the\n      // properties `hook` and `path`.\n      return (<any>stub)[prop];\n    } else if (typeof prop === \"string\") {\n      // Return promise for property.\n      return new RpcPromise(stub.hook,\n          stub.pathIfPromise ? [...stub.pathIfPromise, prop] : [prop]);\n    } else if (prop === Symbol.dispose &&\n          (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {\n      // We only advertise Symbol.dispose on stubs and root promises, not properties.\n      return () => {\n        stub.hook.dispose();\n        stub.hook = DISPOSED_HOOK;\n      };\n    } else {\n      return undefined;\n    }\n  },\n\n  has(target: {raw: RpcStub}, prop: string | symbol) {\n    let stub = target.raw;\n    if (prop === RAW_STUB) {\n      return true;\n    } else if (prop in RpcPromise.prototype) {\n      return prop in stub;\n    } else if (typeof prop === \"string\") {\n      return true;\n    } else if (prop === Symbol.dispose &&\n          (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {\n      return true;\n    } else {\n      return false;\n    }\n  },\n\n  construct(target: {raw: RpcStub}, args: any) {\n    throw new Error(\"An RPC stub cannot be used as a constructor.\");\n  },\n\n  defineProperty(target: {raw: RpcStub}, property: string | symbol, attributes: PropertyDescriptor)\n      : boolean {\n    throw new Error(\"Can't define properties on RPC stubs.\");\n  },\n\n  deleteProperty(target: {raw: RpcStub}, p: string | symbol): boolean {\n    throw new Error(\"Can't delete properties on RPC stubs.\");\n  },\n\n  getOwnPropertyDescriptor(target: {raw: RpcStub}, p: string | symbol): PropertyDescriptor | undefined {\n    // Treat all properties as prototype properties. That's probably fine?\n    return undefined;\n  },\n\n  getPrototypeOf(target: {raw: RpcStub}): object | null {\n    return Object.getPrototypeOf(target.raw);\n  },\n\n  isExtensible(target: {raw: RpcStub}): boolean {\n    return false;\n  },\n\n  ownKeys(target: {raw: RpcStub}): ArrayLike<string | symbol> {\n    return [];\n  },\n\n  preventExtensions(target: {raw: RpcStub}): boolean {\n    // Extensions are not possible anyway.\n    return true;\n  },\n\n  set(target: {raw: RpcStub}, p: string | symbol, newValue: any, receiver: any): boolean {\n    throw new Error(\"Can't assign properties on RPC stubs.\");\n  },\n\n  setPrototypeOf(target: {raw: RpcStub}, v: object | null): boolean {\n    throw new Error(\"Can't override prototype of RPC stubs.\");\n  },\n};\n\n// Implementation of RpcStub.\n//\n// Note that the in the public API, we override the type of RpcStub to reflect the interface\n// exposed by the proxy. That happens in index.ts. But for internal purposes, it's easier to just\n// omit the type parameter.\nexport class RpcStub extends RpcTarget {\n  // Although `hook` and `path` are declared `public` here, they are effectively hidden by the\n  // proxy.\n  constructor(hook: StubHook, pathIfPromise?: PropertyPath) {\n    super();\n\n    if (!(hook instanceof StubHook)) {\n      // Application invoked the constructor to explicitly construct a stub backed by some value\n      // (usually an RpcTarget). (Note we override the types as seen by the app, which is why\n      // the app can pass something that isn't a StubHook -- within the implementation, though,\n      // we always pass StubHook.)\n      let value = <any>hook;\n      if (value instanceof RpcTarget || value instanceof Function) {\n        hook = TargetStubHook.create(value, undefined);\n      } else {\n        // We adopt the value with \"return\" semantics since we want to take ownership of any stubs\n        // within.\n        hook = new PayloadStubHook(RpcPayload.fromAppReturn(value));\n      }\n\n      // Don't let app set this.\n      if (pathIfPromise) {\n        throw new TypeError(\"RpcStub constructor expected one argument, received two.\");\n      }\n    }\n\n    this.hook = hook;\n    this.pathIfPromise = pathIfPromise;\n\n    // Proxy has an unfortunate rule that it will only be considered callable if the underlying\n    // `target` is callable, i.e. a function. So our target *must* be callable. So we use a\n    // dummy function.\n    let func: any = () => {};\n    func.raw = this;\n    return new Proxy(func, PROXY_HANDLERS);\n  }\n\n  public hook: StubHook;\n  public pathIfPromise?: PropertyPath;\n\n  dup(): RpcStub {\n    // Unfortunately the method will be invoked with `this` being the Proxy, not the `RpcPromise`\n    // itself, so we have to unwrap it.\n\n    // Note dup() intentionally resets the path to empty and turns the result into a stub.\n    // TODO: Maybe it should actually return the same type? But I think that's not what it does\n    //   in Workers RPC today? (Need to check.) Alternatively, should there be an optional\n    //   parameter to specify promise vs. stub?\n    let target = this[RAW_STUB];\n    if (target.pathIfPromise) {\n      return new RpcStub(target.hook.get(target.pathIfPromise));\n    } else {\n      return new RpcStub(target.hook.dup());\n    }\n  }\n\n  onRpcBroken(callback: (error: any) => void) {\n    this[RAW_STUB].hook.onBroken(callback);\n  }\n\n  map(func: (value: RpcPromise) => unknown): RpcPromise {\n    let {hook, pathIfPromise} = this[RAW_STUB];\n    return mapImpl.sendMap(hook, pathIfPromise || [], func);\n  }\n\n  toString() {\n    return \"[object RpcStub]\";\n  }\n}\n\nexport class RpcPromise extends RpcStub {\n  // TODO: Support passing target value or promise to constructor.\n  constructor(hook: StubHook, pathIfPromise: PropertyPath) {\n    super(hook, pathIfPromise);\n  }\n\n  then(onfulfilled?: ((value: unknown) => unknown) | undefined | null,\n       onrejected?: ((reason: any) => unknown) | undefined | null)\n       : Promise<unknown> {\n    return pullPromise(this).then(...arguments);\n  }\n\n  catch(onrejected?: ((reason: any) => unknown) | undefined | null): Promise<unknown> {\n    return pullPromise(this).catch(...arguments);\n  }\n\n  finally(onfinally?: (() => void) | undefined | null): Promise<unknown> {\n    return pullPromise(this).finally(...arguments);\n  }\n\n  toString() {\n    return \"[object RpcPromise]\";\n  }\n}\n\n// Given a stub (still wrapped in a Proxy), extract the underlying `StubHook`.\n//\n// The caller takes ownership, meaning it's expected that the original stub will never be disposed\n// itself, but the caller is responsible for calling `dispose()` on the returned hook.\n//\n// However, if the stub points to a property of some other stub or promise, then no ownership is\n// \"transferred\" because properties do not actually have disposers. However, the returned hook is\n// a new hook that aliases that property, but does actually need to be disposed.\n//\n// The result is a promise (i.e. can be pull()ed) if and only if the input is a promise.\nexport function unwrapStubTakingOwnership(stub: RpcStub): StubHook {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise && pathIfPromise.length > 0) {\n    return hook.get(pathIfPromise);\n  } else {\n    return hook;\n  }\n}\n\n// Given a stub (still wrapped in a Proxy), extract the underlying `StubHook`, and duplicate it,\n// returning the duplicate.\n//\n// The caller is responsible for disposing the returned hook, but the original stub also still\n// needs to be disposed by its owner (unless it is a property, which never needs disposal).\n//\n// The result is a promise (i.e. can be pull()ed) if and only if the input is a promise. Note that\n// this differs from the semantics of the actual `dup()` method.\nexport function unwrapStubAndDup(stub: RpcStub): StubHook {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise) {\n    return hook.get(pathIfPromise);\n  } else {\n    return hook.dup();\n  }\n}\n\n// Unwrap a stub returning the underlying `StubHook`, returning `undefined` if it is a property\n// stub.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed (unless `undefined` is returned, in which case neither need to be\n// disposed, as properties are not normally disposable).\nexport function unwrapStubNoProperties(stub: RpcStub): StubHook | undefined {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise && pathIfPromise.length > 0) {\n    return undefined;\n  }\n\n  return hook;\n}\n\n// Unwrap a stub returning the underlying `StubHook`. If it's a property, return the `StubHook`\n// representing the stub or promise of which is is a property.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed.\nexport function unwrapStubOrParent(stub: RpcStub): StubHook {\n  return stub[RAW_STUB].hook;\n}\n\n// Given a stub (still wrapped in a Proxy), extract the `hook` and `pathIfPromise` properties.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed.\nexport function unwrapStubAndPath(stub: RpcStub): {hook: StubHook, pathIfPromise?: PropertyPath} {\n  return stub[RAW_STUB];\n}\n\n// Given a promise stub (still wrapped in a Proxy), pull the remote promise and deliver the\n// payload. This is a helper used to implement the then/catch/finally methods of RpcPromise.\nasync function pullPromise(promise: RpcPromise): Promise<unknown> {\n  let {hook, pathIfPromise} = promise[RAW_STUB];\n  if (pathIfPromise!.length > 0) {\n    // If this isn't the root promise, we have to clone it and pull the clone. This is a little\n    // weird in terms of disposal: There's no way for the app to dispose/cancel the promise while\n    // waiting because it never actually got a direct disposable reference. It has to dispose\n    // the result.\n    hook = hook.get(pathIfPromise!);\n  }\n  let payload = await hook.pull();\n  return payload.deliverResolve();\n}\n\n// =======================================================================================\n// RpcPayload\n\nexport type LocatedPromise = {parent: object, property: string | number, promise: RpcPromise};\n\n// Represents the params to an RPC call, or the resolution of an RPC promise, as it passes\n// through the system.\n//\n// `RpcPayload` is a linear type -- it is passed to or returned from a call, ownership is being\n// transferred. The payload in turn owns all the stubs within it. Disposing the payload disposes\n// the stubs.\n//\n// Hypothetically, when an `RpcPayload` is first constructed from a message structure passed from\n// the app, it ought to be deep-copied, for a few reasons:\n// - To ensure subsequent modifications of the data structure by the app aren't reflected in the\n//   already-sent message.\n// - To find all stubs in the message tree, to take ownership of them.\n// - To find all RpcTargets in the message tree, to wrap them in stubs.\n//\n// However, most payloads are immediately serialized to send across the wire. Said serialization\n// *also* has to make a deep copy, and takes ownership of all stubs found within. In the case that\n// the payload is immediately serialized, then making a deep copy first is wasteful.\n//\n// So, as an optimization, RpcPayload does not necessarily make a copy right away. Instead, it\n// keeps track of whether it's still pointing at the message structure received directly from the\n// app. In that case, the serializer can operate on the original structure directly, making it\n// more efficient.\n//\n// On the receiving end, when an RpcPayload is deserialized from the wire, the payload can safely\n// be delivered directly to the app without a copy. However, if the app makes a loopback call to\n// itself, the payload may never cross the wire. In this case, a deep copy must be made before\n// delivering the final message to the app. There are really two reasons for this copy:\n// - We obviously don't want the caller and callee sharing in-memory mutable data structures, as\n//   this would lead to vasty different behavior than what you'd see when doing RPC across a\n//   network connection.\n// - Before delivering the message to the application, all promises embedded in the message must\n//   be resolved. This is what makes pipelining possible: the sender of a message can place\n//   `RpcPromise`s in it that refer back to values in the recipient's process. These will be filled\n//   in just before delivering the message to the recipient, so that there's no need to transmit\n//   these values back and forth across the wire. It would be unreasonable to expect the\n//   application itself to check the message for promises and resolve them all, so instead the\n//   system automatically resolves all promises upfront, replacing them with their resolutions.\n//   This modifies the payload in-place -- but this of course requires that the payload is\n//   operating on a copy of the message, not the original provided from the sending app.\n//\n// For both the purposes of disposal and substituting promises with their resolutions, it is\n// necessary at some point to make a list of all the stubs (including promise stubs) present in\n// the message. Again, `RpcPayload` tries to minimize the number of times that the whole message\n// needs to be walked, so it implements the following policy:\n// * When constructing a payload from an app-provided message object, the message is not walked\n//   upfront. We do not know yet what stubs it contains.\n// * When deserializing a payload from the wire, we build a list of stubs as part of the\n//   deserialization process.\n// * If we need to deep-copy an app-provided message, we make a list of stubs then.\n// * Hence, we have a list of stubs if and only if the message structure was NOT provided directly\n//   by the application.\n// * If an app-provided payload is serialized, the serializer finds the stubs. (It also typically\n//   takes ownership of the stubs, effectively consuming the payload, so there's no need to build\n//   a list of the stubs.)\n// * If an app-provided payload is disposed, then we have to walk the message at that time to\n//   dispose all stubs within. But, note that when a payload is serialized -- with the serializer\n//   taking ownership of stubs -- then the payload will NOT be disposed explicitly, so this step\n//   will not be needed.\nexport class RpcPayload {\n  // Create a payload from a value passed as params to an RPC from the app.\n  //\n  // The payload does NOT take ownership of any stubs in `value`, and but promises not to modify\n  // `value`. If the payload is delivered locally, `value` will be deep-copied first, so as not\n  // to have the sender and recipient end up sharing the same mutable object. `value` will not be\n  // touched again after the call returns synchronously (returns a promise) -- by that point,\n  // the value has either been copied or serialized to the wire.\n  public static fromAppParams(value: unknown): RpcPayload {\n    return new RpcPayload(value, \"params\");\n  }\n\n  // Create a payload from a value return from an RPC implementation by the app.\n  //\n  // Unlike fromAppParams(), in this case the payload takes ownership of all stubs in `value`, and\n  // may hold onto `value` for an arbitrarily long time (e.g. to serve pipelined requests). It\n  // will still avoid modifying `value` and will make a deep copy if it is delivered locally.\n  public static fromAppReturn(value: unknown): RpcPayload {\n    return new RpcPayload(value, \"return\");\n  }\n\n  // Combine an array of payloads into a single payload whose value is an array. Ownership of all\n  // stubs is transferred from the inputs to the outputs, hence if the output is disposed, the\n  // inputs should not be. (In case of exception, nothing is disposed, though.)\n  public static fromArray(array: RpcPayload[]): RpcPayload {\n    let hooks: StubHook[] = [];\n    let promises: LocatedPromise[] = [];\n\n    let resultArray: unknown[] = [];\n\n    for (let payload of array) {\n      payload.ensureDeepCopied();\n      for (let hook of payload.hooks!) {\n        hooks.push(hook);\n      }\n      for (let promise of payload.promises!) {\n        if (promise.parent === payload) {\n          // This promise is the root of the source payload. We need to reparent it to its proper\n          // location in the result array.\n          promise = {\n            parent: resultArray,\n            property: resultArray.length,\n            promise: promise.promise\n          };\n        }\n        promises.push(promise);\n      }\n      resultArray.push(payload.value);\n    }\n\n    return new RpcPayload(resultArray, \"owned\", hooks, promises);\n  }\n\n  // Create a payload from a value parsed off the wire using Evaluator.evaluate().\n  //\n  // A payload is constructed with a null value and the given hooks and promises arrays. The value\n  // is expected to be filled in by the evaluator, and the hooks and promises arrays are expected\n  // to be extended with stubs found during parsing. (This weird usage model is necessary so that\n  // if the root value turns out to be a promise, its `parent` in `promises` can be the payload\n  // object itself.)\n  //\n  // When done, the payload takes ownership of the final value and all the stubs within. It may\n  // modify the value in preparation for delivery, and may deliver the value directly to the app\n  // without copying.\n  public static forEvaluate(\n      hooks: StubHook[], promises: LocatedPromise[], callHandler?: RpcCallHandler) {\n    return new RpcPayload(null, \"owned\", hooks, promises, callHandler);\n  }\n\n  // Deep-copy the given value, including dup()ing all stubs.\n  //\n  // If `value` is a function, it should be bound to `oldParent` as its `this`.\n  //\n  // If deep-copying from a branch of some other RpcPayload, it must be provided, to make sure\n  // RpcTargets found within don't get duplicate stubs.\n  public static deepCopyFrom(\n      value: unknown, oldParent: object | undefined, owner: RpcPayload | null): RpcPayload {\n    let result = new RpcPayload(null, \"owned\", [], []);\n    result.value = result.deepCopy(value, oldParent, \"value\", result, /*dupStubs=*/true, owner);\n    return result;\n  }\n\n  // Private constructor; use factory functions above to construct.\n  private constructor(\n    // The payload value.\n    public value: unknown,\n\n    // What is the provenance of `value`?\n    // \"params\": It came from the app, in params to a call. We must dupe any stubs within.\n    // \"return\": It came from the app, returned from a call. We take ownership of all stubs within.\n    // \"owned\": This value belongs fully to us, either because it was deserialized from the wire\n    //   or because we deep-copied a value from the app.\n    private source: \"params\" | \"return\" | \"owned\",\n\n    // `hooks` and `promises` are filled in only if `value` belongs to us (`source` is \"owned\") and\n    // so can safely be delivered to the app. If `value` came from then app in the first place,\n    // then it cannot be delivered back to the app nor modified by us without first deep-copying\n    // it. `hooks` and `promises` will be computed as part of the deep-copy.\n\n    // All non-promise stubs found in `value`. This list is needed only for the purpose of being\n    // able to dispose them when desired. This intentionally doesn't inculde promises because they\n    // are already covered by `promises`, below.\n    private hooks?: StubHook[],\n\n    // All promises found in `value`. The locations of each promise are provided to allow\n    // substitutions later.\n    private promises?: LocatedPromise[],\n\n    // Optional server hook carried by received call arguments. Keeping it on the payload means it\n    // naturally survives while a promise-pipelined target resolves.\n    public callHandler?: RpcCallHandler\n  ) {}\n\n  // For `source === \"return\"` payloads only, this tracks any StubHooks created around RpcTargets,\n  // streams, or WebSockets found in the payload at the time that it is serialized (or deep-copied)\n  // for return, so that we can make sure they are not disposed before the pipeline ends.\n  //\n  // This is initialized on first use.\n  private rpcTargets?: Map<object, StubHook>;\n\n  // Common implementation of the getHookFor*() methods below, for `source === \"return\"` payloads.\n  // Looks up `key` in `rpcTargets`, calling `create()` to make the hook if there isn't one yet.\n  //\n  // If dupStubs is true, we want to both make sure the map contains the hook, and also return\n  // a dup of that hook.\n  //\n  // If dupStubs is false, then we are being called as part of ensureDeepCopied(), i.e. replacing\n  // ourselves with a deep copy. In this case we actually want the copy to end up owning all\n  // the hooks, and the map to be left empty. So what we do in this case is:\n  // * If the key is not in the map, we just create the hook, but don't populate the map.\n  // * If the key *is* in the map, we *remove* the hook from the map, and return it.\n  private getHookForReturn(key: object, dupStubs: boolean, create: () => StubHook): StubHook {\n    let hook = this.rpcTargets?.get(key);\n    if (hook) {\n      if (dupStubs) {\n        return hook.dup();\n      } else {\n        this.rpcTargets!.delete(key);\n        return hook;\n      }\n    } else {\n      hook = create();\n      if (dupStubs) {\n        if (!this.rpcTargets) {\n          this.rpcTargets = new Map;\n        }\n        this.rpcTargets.set(key, hook);\n        return hook.dup();\n      } else {\n        return hook;\n      }\n    }\n  }\n\n  // Get the StubHook representing the given RpcTarget found inside this payload.\n  public getHookForRpcTarget(target: RpcTarget | Function, parent: object | undefined,\n                             dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      if (dupStubs) {\n        // We aren't supposed to take ownership of stubs appearing in params -- we're supposed to\n        // dupe them. But an RpcTarget isn't a stub. If we create a stub around it, the stub takes\n        // ownership.\n        //\n        // Usually, people passing raw RpcTargets into functions actually want the call to take\n        // ownership -- that is, they want to have the disposer called later.\n        //\n        // But, if the RpcTarget happens to implement a `dup()` method, we will go ahead and call\n        // that method, and wrap whatever it returns instead. This method wouldn't actually be\n        // available over RPC anyway (since calling `dup()` on the client-side stub just dupes the\n        // stub), so if an `RpcTarget` implements this, it must intend for us to use it.\n        //\n        // This is particularly important for the case of workerd-native RpcStubs, that is, stubs\n        // from the built-in RPC system, rather than the pure-JS implementation of Cap'n Web.\n        // We treat those stubs as RpcTargets. But, we do need to dup() them, just like we would\n        // our own stubs.\n\n        let dupable = target as any;\n        if (typeof dupable.dup === \"function\") {\n          target = dupable.dup();\n        }\n      }\n\n      return TargetStubHook.create(target, parent);\n    } else if (this.source === \"return\") {\n      return this.getHookForReturn(target, dupStubs, () => TargetStubHook.create(target, parent));\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw RpcTargets\");\n    }\n  }\n\n  // Get the StubHook representing the given WritableStream found inside this payload.\n  public getHookForWritableStream(stream: WritableStream, parent: object | undefined,\n                                  dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      // For params, we always create a new hook. WritableStreams don't have a dup() method,\n      // and it wouldn't really make sense anyway since we're locking the stream by calling\n      // getWriter().\n      return streamImpl.createWritableStreamHook(stream);\n    } else if (this.source === \"return\") {\n      return this.getHookForReturn(stream, dupStubs,\n          () => streamImpl.createWritableStreamHook(stream));\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw WritableStreams\");\n    }\n  }\n\n  // Get the StubHook representing the given ReadableStream found inside this payload.\n  public getHookForReadableStream(stream: ReadableStream, parent: object | undefined,\n                                  dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      return streamImpl.createReadableStreamHook(stream);\n    } else if (this.source === \"return\") {\n      return this.getHookForReturn(stream, dupStubs,\n          () => streamImpl.createReadableStreamHook(stream));\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw ReadableStreams\");\n    }\n  }\n\n  // WebSockets that have been serialized from this payload. Unlike `rpcTargets`, this is used\n  // for both \"params\" and \"return\" payloads, and only to detect duplicates: wrapping a socket in\n  // streams has side effects (it accepts the socket, attaches its listeners, and starts pumping\n  // messages), so it can happen at most once per socket.\n  private sentWebSockets?: Set<object>;\n\n  // Get the StubHook representing the given WebSocket (the `webSocket` property of an upgrade\n  // Response) found inside this payload. The caller provides a factory that wraps the socket in\n  // a pair of streams and returns the hook for the writable half (see websocket-streams.ts; the\n  // readable half is piped separately by the caller). Attempting to serialize the same socket\n  // twice is an error; see `sentWebSockets`.\n  public getHookForWebSocket(webSocket: object, makeHook: () => StubHook): StubHook {\n    if (this.source === \"owned\") {\n      throw new Error(\"owned payload shouldn't contain raw WebSockets\");\n    }\n\n    if (this.sentWebSockets?.has(webSocket)) {\n      throw new Error(\"A WebSocket can only be sent over RPC once.\");\n    }\n    if (!this.sentWebSockets) {\n      this.sentWebSockets = new Set;\n    }\n    this.sentWebSockets.add(webSocket);\n\n    let hook = makeHook();\n    if (this.source === \"params\") {\n      // The export takes full ownership of the hook.\n      return hook;\n    } else {\n      // For a return, the hook is also tracked in rpcTargets so that it stays alive until the\n      // pipeline ends (and so disposeImpl()/deepCopy() can account for it).\n      if (!this.rpcTargets) {\n        this.rpcTargets = new Map;\n      }\n      this.rpcTargets.set(webSocket, hook);\n      return hook.dup();\n    }\n  }\n\n  // If serializing this payload previously created a tunnel hook for the given WebSocket,\n  // transfer or dup that hook, following the same dupStubs contract as the getHookFor*() methods\n  // above. Unlike for streams, deep-copying does NOT create a hook when none exists: wrapping a\n  // socket in a tunnel has side effects that would break a socket that is merely being delivered\n  // locally.\n  public getExistingHookForWebSocket(webSocket: object, dupStubs: boolean): StubHook | undefined {\n    let hook = this.rpcTargets?.get(webSocket);\n    if (!hook) {\n      return undefined;\n    } else if (dupStubs) {\n      return hook.dup();\n    } else {\n      this.rpcTargets!.delete(webSocket);\n      return hook;\n    }\n  }\n\n  private deepCopy(\n      value: unknown, oldParent: object | undefined, property: string | number, parent: object,\n      dupStubs: boolean, owner: RpcPayload | null): unknown {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n        // This will throw later on when someone tries to do something with it.\n        return value;\n\n      case \"primitive\":\n      case \"bigint\":\n      case \"date\":\n      case \"bytes\":\n      case \"blob\":\n      case \"error\":\n      case \"undefined\":\n        // immutable, no need to copy\n        // TODO: Should errors be copied if they have own properties?\n        return value;\n\n      case \"array\": {\n        // We have to construct the new array first, then fill it in, so we can pass it as the\n        // parent.\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        let result = new Array(len);\n        for (let i = 0; i < len; i++) {\n          result[i] = this.deepCopy(array[i], array, i, result, dupStubs, owner);\n        }\n        return result;\n      }\n\n      case \"object\": {\n        // Plain object. Unfortunately there's no way to pre-allocate the right shape.\n        let result: Record<string, unknown> = {};\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          result[i] = this.deepCopy(object[i], object, i, result, dupStubs, owner);\n        }\n        return result;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let stub = <RpcStub>value;\n        let hook: StubHook;\n        if (dupStubs) {\n          hook = unwrapStubAndDup(stub);\n        } else {\n          hook = unwrapStubTakingOwnership(stub);\n        }\n        if (stub instanceof RpcPromise) {\n          let promise = new RpcPromise(hook, []);\n          this.promises!.push({parent, property, promise});\n          return promise;\n        } else {\n          this.hooks!.push(hook);\n          return new RpcStub(hook);\n        }\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        let target = <RpcTarget | Function>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForRpcTarget(target, oldParent, dupStubs);\n        } else {\n          hook = TargetStubHook.create(target, oldParent);\n        }\n        this.hooks!.push(hook);\n        return new RpcStub(hook);\n      }\n\n      case \"rpc-thenable\": {\n        let target = <RpcTarget>value;\n        let promise: RpcPromise;\n        if (owner) {\n          promise = new RpcPromise(owner.getHookForRpcTarget(target, oldParent, dupStubs), []);\n        } else {\n          promise = new RpcPromise(TargetStubHook.create(target, oldParent), []);\n        }\n        this.promises!.push({parent, property, promise});\n        return promise;\n      }\n\n      case \"writable\": {\n        let stream = <WritableStream>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForWritableStream(stream, oldParent, dupStubs);\n        } else {\n          hook = streamImpl.createWritableStreamHook(stream);\n        }\n        this.hooks!.push(hook);\n        return stream;\n      }\n\n      case \"readable\": {\n        // Note that we don't use tee() here because we treat streams as reference types -- we\n        // actually want to share the same body. tee()ing the stream would force the runtime to\n        // buffer a copy of the whole body which would usually never be read.\n        let stream = <ReadableStream>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForReadableStream(stream, oldParent, dupStubs);\n        } else {\n          hook = streamImpl.createReadableStreamHook(stream);\n        }\n        this.hooks!.push(hook);\n        return stream;\n      }\n\n      case \"headers\":\n        return new Headers(<Headers>value);\n\n      case \"request\": {\n        let req = <Request>value;\n        if (req.body) {\n          // Note \"deep-copy\" of a ReadableStream always returns the same stream, but we still\n          // need to run it in order to handle refcounting / disposal properly.\n          this.deepCopy(req.body, req, \"body\", req, dupStubs, owner);\n        }\n\n        // Make an actual copy of the object, e.g. so the headers are copied.\n        // Note that it would be incorrect to use clone() here since that would tee() the body\n        // stream.\n        return new Request(req);\n      }\n\n      case \"response\": {\n        let resp = <Response>value;\n        if (resp.body) {\n          // Note \"deep-copy\" of a ReadableStream always returns the same stream, but we still\n          // need to run it in order to handle refcounting / disposal properly.\n          this.deepCopy(resp.body, resp, \"body\", resp, dupStubs, owner);\n        }\n\n        // Make an actual copy of the object, e.g. so the headers are copied.\n        // Note that it would be incorrect to use clone() here since that would tee() the body\n        // stream.\n        let result = new Response(resp.body, resp);\n\n        let webSocket = (<any>resp).webSocket;\n        if (webSocket) {\n          // A WebSocket upgrade response (Cloudflare Workers extension). Like a ReadableStream\n          // body, the copy shares the original socket -- but if serializing this payload\n          // previously wrapped the socket in a tunnel, we must take over that hook so that it\n          // is properly accounted for.\n          let hook = owner?.getExistingHookForWebSocket(webSocket, dupStubs);\n          if (hook) this.hooks!.push(hook);\n          Object.defineProperty(result, \"webSocket\", { value: webSocket, configurable: true });\n        }\n        return result;\n      }\n\n      default:\n        kind satisfies never;\n        throw new Error(\"unreachable\");\n    }\n  }\n\n  // Ensures that if the value originally came from an unowned source, we have replaced it with a\n  // deep copy.\n  public ensureDeepCopied() {\n    if (this.source !== \"owned\") {\n      // If we came from call params, we need to dupe any stubs. Otherwise (we came from a return),\n      // we take ownership of all stubs.\n      let dupStubs = this.source === \"params\";\n\n      this.hooks = [];\n      this.promises = [];\n\n      // Deep-copy the value.\n      try {\n        this.value = this.deepCopy(this.value, undefined, \"value\", this, dupStubs, this);\n      } catch (err) {\n        // Roll back the change.\n        this.hooks = undefined;\n        this.promises = undefined;\n        throw err;\n      }\n\n      // We now own the value.\n      this.source = \"owned\";\n\n      // `rpcTargets` should have been left empty. We can throw it out.\n      if (this.rpcTargets && this.rpcTargets.size > 0) {\n        throw new Error(\"Not all rpcTargets were accounted for in deep-copy?\");\n      }\n      this.rpcTargets = undefined;\n    }\n  }\n\n  // Resolve all promises in this payload and then assign the final value into `parent[property]`.\n  private deliverTo(parent: object, property: string | number, promises: Promise<any>[]): void {\n    this.ensureDeepCopied();\n\n    if (this.value instanceof RpcPromise) {\n      RpcPayload.deliverRpcPromiseTo(this.value, parent, property, promises);\n    } else {\n      (<any>parent)[property] = this.value;\n\n      for (let record of this.promises!) {\n        // Note that because we already did ensureDeepCopied(), replacing each promise with its\n        // resolution does not interfere with disposal later on -- disposal will be based on the\n        // `promises` list, so will still properly dispose each promise, which in turn disposes\n        // the promise's eventual payload.\n        RpcPayload.deliverRpcPromiseTo(record.promise, record.parent, record.property, promises);\n      }\n    }\n  }\n\n  private static deliverRpcPromiseTo(\n      promise: RpcPromise, parent: object, property: string | number,\n      promises: Promise<unknown>[]) {\n    // deepCopy() should have replaced any property stubs with normal promise stubs.\n    let hook = unwrapStubNoProperties(promise);\n    if (!hook) {\n      throw new Error(\"property promises should have been resolved earlier\");\n    }\n\n    let inner = hook.pull();\n    if (inner instanceof RpcPayload) {\n      // Immediately resolved to payload.\n      inner.deliverTo(parent, property, promises);\n    } else {\n      // It's a promise.\n      promises.push(inner.then(payload => {\n        let subPromises: Promise<unknown>[] = [];\n        payload.deliverTo(parent, property, subPromises);\n        if (subPromises.length > 0) {\n          return Promise.all(subPromises);\n        }\n      }));\n    }\n  }\n\n  // Call the given function with the payload as an argument. The call is made synchronously if\n  // possible, in order to maintain e-order. However, if any RpcPromises exist in the payload,\n  // they are awaited and substituted before calling the function. The result of the call is\n  // wrapped into another payload.\n  //\n  // The payload is automatically disposed after the call completes. The caller should not call\n  // dispose().\n  public async deliverCall(func: Function, thisArg: object | undefined): Promise<RpcPayload> {\n    try {\n      let promises: Promise<void>[] = [];\n      this.deliverTo(this, \"value\", promises);\n\n      // WARNING: It is critical that if the promises list is empty, we do not await anything, so\n      //   that the function is called immediately and synchronously. Otherwise, we might violate\n      //   e-order.\n      if (promises.length > 0) {\n        await Promise.all(promises);\n      }\n\n      // Call the function.\n      let result = Function.prototype.apply.call(func, thisArg, this.value);\n\n      if (result instanceof RpcPromise) {\n        // Special case: If the function immediately returns RpcPromise, we don't want to await it,\n        // since that will actually wait for the promise. Instead we want to construct a payload\n        // around it directly.\n        return RpcPayload.fromAppReturn(result);\n      } else {\n        // In all other cases, await the result (which may or may not be a promise, but `await`\n        // will just pass through non-promises).\n        return RpcPayload.fromAppReturn(await result);\n      }\n    } finally {\n      this.dispose();\n    }\n  }\n\n  // Deliver this payload as the argument list to `WritableStreamDefaultWriter.write(chunk)`.\n  //\n  // Unlike deliverCall(), stream chunks are enqueued and read asynchronously. Disposing the\n  // payload when write() returns would free any stubs nested in the chunk before the reader\n  // dequeues them. A chunk only needs its disposal deferred if it owns capabilities the\n  // reader will use after write() resolves. Pure data (primitives, bytes, Date, plain\n  // objects) carries no capabilities, so dispose it immediately and leave the chunk\n  // untouched. Bare RpcStubs already implement Symbol.dispose, so their own disposer owns\n  // the capability; only attach a payload disposer otherwise.\n  //\n  // Expects `this.value` to be a one-element argument array `[chunk]`. Returns a payload\n  // wrapping the (void) write result.\n  public async deliverStreamWrite(\n      writer: { write(chunk: unknown): Promise<void> }): Promise<RpcPayload> {\n    try {\n      let promises: Promise<void>[] = [];\n      this.deliverTo(this, \"value\", promises);\n\n      // Same e-order constraint as deliverCall: if there are no nested promises, call write\n      // synchronously so concurrent writes stay ordered.\n      if (promises.length > 0) {\n        await Promise.all(promises);\n      }\n\n      let chunk = (this.value as unknown[])[0];\n\n      // deliverTo → ensureDeepCopied, so hooks/promises are populated.\n      const ownsCapabilities = this.hooks!.length > 0 || this.promises!.length > 0;\n\n      if (ownsCapabilities && chunk instanceof Object) {\n        // Keep the payload alive until the reader disposes the chunk. A bare RpcStub already\n        // implements Symbol.dispose (its own disposer owns the hook); only attach otherwise.\n        if (!(Symbol.dispose in chunk)) {\n          Object.defineProperty(chunk, Symbol.dispose, {\n            value: () => this.dispose(),\n            writable: true,\n            enumerable: false,\n            configurable: true,\n          });\n        }\n        await writer.write(chunk);\n        return RpcPayload.fromAppReturn(undefined);\n      }\n\n      // No capabilities (or non-object chunk): nothing to keep alive beyond the write.\n      await writer.write(chunk);\n      this.dispose();\n      return RpcPayload.fromAppReturn(undefined);\n    } catch (err) {\n      // deliverTo / write failed: free any capabilities we still own.\n      this.dispose();\n      throw err;\n    }\n  }\n\n  // Produce a promise for this payload for return to the application. Any RpcPromises in the\n  // payload are awaited and substituted with their results first.\n  //\n  // The returned object will have a disposer which disposes the payload. The caller should not\n  // separately dispose it.\n  public async deliverResolve(): Promise<unknown> {\n    try {\n      let promises: Promise<void>[] = [];\n      this.deliverTo(this, \"value\", promises);\n\n      if (promises.length > 0) {\n        await Promise.all(promises);\n      }\n\n      let result = this.value;\n\n      // Add disposer to result.\n      if (result instanceof Object) {\n        if (!(Symbol.dispose in result)) {\n          // We want the disposer to be non-enumerable as otherwise it gets in the way of things\n          // like unit tests trying to deep-compare the result to an object.\n          Object.defineProperty(result, Symbol.dispose, {\n            // NOTE: Using `this.dispose.bind(this)` here causes Playwright's build of\n            //   Chromium 140.0.7339.16 to fail when the object is assigned to a `using` variable,\n            //   with the error:\n            //       TypeError: Symbol(Symbol.dispose) is not a function\n            //   I cannot reproduce this problem in Chrome 140.0.7339.127 nor in Node or workerd,\n            //   so maybe it was a short-lived V8 bug or something. To be safe, though, we use\n            //   `() => this.dispose()`, which seems to always work.\n            value: () => this.dispose(),\n            writable: true,\n            enumerable: false,\n            configurable: true,\n          });\n        }\n      }\n\n      return result;\n    } catch (err) {\n      // Automatically dispose since the application will never receive the disposable...\n      this.dispose();\n      throw err;\n    }\n  }\n\n  public dispose() {\n    if (this.source === \"owned\") {\n      // Oh good, we can just run through them.\n      this.hooks!.forEach(hook => hook.dispose());\n      this.promises!.forEach(promise => promise.promise[Symbol.dispose]());\n    } else if (this.source === \"return\") {\n      // Value received directly from app as a return value. We take ownership of all stubs, so we\n      // must recursively scan it for things to dispose.\n      this.disposeImpl(this.value, undefined);\n      if (this.rpcTargets && this.rpcTargets.size > 0) {\n        throw new Error(\"Not all rpcTargets were accounted for in disposeImpl()?\");\n      }\n    } else {\n      // this.source is \"params\". We don't own the stubs within.\n    }\n\n    // Make dispose() idempotent.\n    this.source = \"owned\";\n    this.hooks = [];\n    this.promises = [];\n  }\n\n  // Recursive dispose, called only when `source` is \"return\".\n  private disposeImpl(value: unknown, parent: object | undefined) {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"blob\":\n      case \"date\":\n      case \"error\":\n      case \"undefined\":\n        return;\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        for (let i = 0; i < len; i++) {\n          this.disposeImpl(array[i], array);\n        }\n        return;\n      }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          this.disposeImpl(object[i], object);\n        }\n        return;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let stub = <RpcStub>value;\n        let hook = unwrapStubNoProperties(stub);\n        if (hook) {\n          hook.dispose();\n        }\n        return;\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        let target = <RpcTarget | Function>value;\n        let hook = this.rpcTargets?.get(target);\n        if (hook) {\n          // We created a hook around this target earlier. Dispose it now.\n          hook.dispose();\n          this.rpcTargets!.delete(target);\n        } else {\n          // There never was a stub pointing at this target. This could be because:\n          // * The call was used only for promise pipelining, so the result was never serialized,\n          //   so it never got added to `rpcTargets`.\n          // * The same RpcTarget appears in the results twice, and we already disposed the hook\n          //   when we saw it earlier. Note that it's intentional that we should call the disposer\n          //   twice if the same object appears twice.\n          disposeRpcTarget(target);\n        }\n        return;\n      }\n\n      case \"rpc-thenable\":\n        // Since thenables are promises, we don't own them, so we don't dispose them.\n        return;\n\n      case \"headers\":\n        // Headers have no owned resources to dispose.\n        return;\n\n      case \"request\": {\n        // The body may be a ReadableStream that has an associated hook in rpcTargets.\n        let req = <Request>value;\n        if (req.body) this.disposeImpl(req.body, req);\n        // TODO: When we support AbortSignal, we may need to dispose request.signal here?\n        return;\n      }\n\n      case \"response\": {\n        // The body may be a ReadableStream that has an associated hook in rpcTargets.\n        let resp = <Response>value;\n        if (resp.body) this.disposeImpl(resp.body, resp);\n\n        let webSocket = (<any>resp).webSocket;\n        if (webSocket) {\n          let hook = this.rpcTargets?.get(webSocket);\n          if (hook) {\n            // Serialization wrapped this socket in a tunnel. Dispose our reference; if the\n            // receiver imported the tunnel, its dup keeps the socket alive.\n            this.rpcTargets!.delete(webSocket);\n            hook.dispose();\n          } else {\n            // The response was never serialized, so no one can ever receive this socket. Close\n            // it so the connection isn't left dangling.\n            try { webSocket.close(); } catch {}\n          }\n        }\n        return;\n      }\n\n      case \"writable\": {\n        let stream = <WritableStream>value;\n        let hook = this.rpcTargets?.get(stream);\n        if (hook) {\n          this.rpcTargets!.delete(stream);\n        } else {\n          // Create a hook just so we can call its disposer for consistent behavior, which will\n          // abort the stream.\n          hook = streamImpl.createWritableStreamHook(stream);\n        }\n\n        hook.dispose();\n\n        return;\n      }\n\n      case \"readable\": {\n        let stream = <ReadableStream>value;\n        let hook = this.rpcTargets?.get(stream);\n        if (hook) {\n          this.rpcTargets!.delete(stream);\n        } else {\n          // Create a hook just so we can call its disposer for consistent behavior, which will\n          // cancel the stream.\n          hook = streamImpl.createReadableStreamHook(stream);\n        }\n\n        hook.dispose();\n\n        return;\n      }\n\n      default:\n        kind satisfies never;\n        return;\n    }\n  }\n\n  // Ignore unhandled rejections in all promises in this payload -- that is, all promises that\n  // *would* be awaited if this payload were to be delivered. See the similarly-named method of\n  // StubHook for explanation.\n  ignoreUnhandledRejections(): void {\n    if (this.hooks) {\n      // Propagate to all stubs and promises.\n      this.hooks.forEach(hook => {\n        hook.ignoreUnhandledRejections();\n      });\n      this.promises!.forEach(\n          promise => unwrapStubOrParent(promise.promise).ignoreUnhandledRejections());\n    } else {\n      // Ugh we have to walk the tree.\n      this.ignoreUnhandledRejectionsImpl(this.value);\n    }\n  }\n\n  private ignoreUnhandledRejectionsImpl(value: unknown) {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"blob\":\n      case \"date\":\n      case \"error\":\n      case \"undefined\":\n      case \"function\":\n      case \"rpc-target\":\n      case \"writable\":\n      case \"readable\":\n      case \"headers\":\n      case \"request\":\n      case \"response\":\n        return;\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        for (let i = 0; i < len; i++) {\n          this.ignoreUnhandledRejectionsImpl(array[i]);\n        }\n        return;\n      }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          this.ignoreUnhandledRejectionsImpl(object[i]);\n        }\n        return;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\":\n        unwrapStubOrParent(<RpcStub>value).ignoreUnhandledRejections();\n        return;\n\n      case \"rpc-thenable\":\n        (<any>value).then((_: any) => {}, (_: any) => {});\n        return;\n\n      default:\n        kind satisfies never;\n        return;\n    }\n  }\n};\n\n// =======================================================================================\n// Local StubHook implementations\n\n// Result of followPath().\ntype FollowPathResult = {\n  // Path led to a regular value.\n\n  value: unknown,              // the value\n  parent: object | undefined,  // the immediate parent (useful as `this` if making a call)\n  owner: RpcPayload | null,    // RpcPayload that owns the value, if any\n\n  hook?: never,\n  remainingPath?: never,\n} | {\n  // Path leads into another stub, which needs to be called recursively.\n\n  hook: StubHook,               // StubHook of the inner stub.\n  remainingPath: PropertyPath,  // Path to pass to `hook` when recursing.\n\n  value?: never,\n  parent?: never,\n  owner?: never,\n};\n\nfunction followPath(value: unknown, parent: object | undefined,\n                    path: PropertyPath, owner: RpcPayload | null): FollowPathResult {\n  for (let i = 0; i < path.length; i++) {\n    parent = <object>value;\n\n    let part = path[i];\n    if (part in Object.prototype) {\n      // Don't allow messing with Object.prototype properties over RPC. We block these even if\n      // the specific object has overridden them for consistency with the deserialization code,\n      // which will refuse to deserialize an object containing such properties. Anyway, it's\n      // impossible for a normal client to even request these because accessing Object prototype\n      // properties on a stub will resolve to the local prototype property, not making an RPC at\n      // all.\n      value = undefined;\n      continue;\n    }\n\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"object\":\n      case \"function\":\n        // Must be own property, NOT inherited from a prototype.\n        if (Object.hasOwn(<object>value, part)) {\n          value = (<any>value)[part];\n        } else {\n          value = undefined;\n        }\n        break;\n\n      case \"array\":\n        // For arrays, restrict specifically to numeric indexes, to be consistent with\n        // serialization, which only sends a flat list.\n        if (Number.isInteger(part) && <number>part >= 0) {\n          value = (<any>value)[part];\n        } else {\n          value = undefined;\n        }\n        break;\n\n      case \"rpc-target\":\n      case \"rpc-thenable\": {\n        // Must be prototype property, and must NOT be inherited from `Object`.\n        if (Object.hasOwn(<object>value, part)) {\n          // We throw an error in this case, rather than return undefined, because otherwise\n          // people tend to get confused about this. If you don't want it to be possible to\n          // probe the existence of your instance properties, make them properly private (prefix\n          // with #).\n          throw new TypeError(\n              `Attempted to access property '${part}', which is an instance property of the ` +\n              `RpcTarget. To avoid leaking private internals, instance properties cannot be ` +\n              `accessed over RPC. If you want to make this property available over RPC, define ` +\n              `it as a method or getter on the class, instead of an instance property.`);\n        } else {\n          value = (<any>value)[part];\n        }\n\n        // Since we're descending into the RpcTarget, the rest of the path is not \"owned\" by any\n        // RpcPayload.\n        owner = null;\n        break;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let {hook: hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n        return { hook, remainingPath:\n            pathIfPromise ? pathIfPromise.concat(path.slice(i)) : path.slice(i) };\n      }\n\n      case \"writable\":\n        // TODO: How do we pipeline on WritableStream? We can't expose the literal WritableStream\n        //   interface because the caller would call getWriter() which would conflict with the\n        //   RPC system calling it later. Perhaps the caller needs to somehow indicate, on the\n        //   client side, \"this pipelined property is expected to be a WritableStream\", and then\n        //   we can give them a WritableStream, and somehow this correctly pipelines... idk.\n        value = undefined;\n        break;\n\n      case \"readable\":\n        // TODO: Do we want to support pipelining on ReadableStream at all? It doesn't seem like\n        //   it really makes sense... you might as well just wait for the promise for the\n        //   ReadableStream to resolve, and then read it, because you'll get bytes just as fast.\n        value = undefined;\n        break;\n\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"blob\":\n      case \"date\":\n      case \"error\":\n      case \"headers\":\n      case \"request\":\n      case \"response\":\n        // These have no properties that can be accessed remotely.\n        value = undefined;\n        break;\n\n      case \"undefined\":\n        // Intentionally produce TypeError.\n        value = (value as any)[part];\n        break;\n\n      case \"unsupported\": {\n        if (i === 0) {\n          throw new TypeError(`RPC stub points at a non-serializable type.`);\n        } else {\n          let prefix = path.slice(0, i).join(\".\");\n          let remainder = path.slice(0, i).join(\".\");\n          throw new TypeError(\n              `'${prefix}' is not a serializable type, so property ${remainder} cannot ` +\n              `be accessed.`);\n        }\n      }\n\n      default:\n        kind satisfies never;\n        throw new TypeError(\"unreachable\");\n    }\n  }\n\n  // If we reached a promise, we actually want the caller to forward to the promise, not return\n  // the promise itself.\n  if (value instanceof RpcPromise) {\n    let {hook: hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n    return { hook, remainingPath: pathIfPromise || [] };\n  }\n\n  // We don't validate the final value itself because we don't know the intended use yet. If it's\n  // for a call, any callable is valid. If it's for get(), then any serializable value is valid.\n  return {\n    value,\n    parent,\n    owner,\n  };\n}\n\n// Shared base class for PayloadStubHook and TargetStubHook.\nabstract class ValueStubHook extends StubHook {\n  protected abstract getValue(): {value: unknown, owner: RpcPayload | null};\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    try {\n      let {value, owner} = this.getValue();\n      let followResult = followPath(value, undefined, path, owner);\n\n      if (followResult.hook) {\n        return followResult.hook.call(followResult.remainingPath, args);\n      }\n\n      // It's a local function.\n      if (typeof followResult.value != \"function\") {\n        throw new TypeError(`'${path.join('.')}' is not a function.`);\n      }\n      const func = followResult.value;\n      const invoke = () => args.deliverCall(func, followResult.parent);\n      let promise = args.callHandler\n        ? args.callHandler({\n            path: [...path],\n            target: followResult.parent ?? followResult.value,\n          }, invoke)\n        : invoke();\n      return new PromiseStubHook(promise.then(payload => {\n        return new PayloadStubHook(payload);\n      }));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    try {\n      let followResult: FollowPathResult;\n      try {\n        let {value, owner} = this.getValue();\n        followResult = followPath(value, undefined, path, owner);;\n      } catch (err) {\n        // Oops, we need to dispose the captures of which we took ownership.\n        for (let cap of captures) {\n          cap.dispose();\n        }\n        throw err;\n      }\n\n      if (followResult.hook) {\n        return followResult.hook.map(followResult.remainingPath, captures, instructions);\n      }\n\n      return mapImpl.applyMap(\n          followResult.value, followResult.parent, followResult.owner, captures, instructions);\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  get(path: PropertyPath): StubHook {\n    try {\n      let {value, owner} = this.getValue();\n\n      if (path.length === 0 && owner === null) {\n        // The only way this happens is if someone sends \"pipeline\" and references a\n        // TargetStubHook, but they shouldn't do that, because TargetStubHook never backs a\n        // promise, and a non-promise cannot be converted to a promise.\n        // TODO: Is this still correct for rpc-thenable?\n        throw new Error(\"Can't dup an RpcTarget stub as a promise.\");\n      }\n\n      let followResult = followPath(value, undefined, path, owner);\n\n      if (followResult.hook) {\n        return followResult.hook.get(followResult.remainingPath);\n      }\n\n      // Note that if `followResult.owner` is null, then we've descended into the contents of an\n      // RpcTarget. In that case, if this deep copy discovers an RpcTarget embedded in the result,\n      // it will create a new stub for it. If that RpcTarget has a disposer, it'll be disposed when\n      // that stub is disposed. If the same RpcTarget is returned in *another* get(), it create\n      // *another* stub, which calls the disposer *another* time. This can be quite weird -- the\n      // disposer may be called any number of times, including zero if the property is never read\n      // at all. Unfortunately, that's just the way it is. The application can avoid this problem by\n      // wrapping the RpcTarget in an RpcStub itself, proactively, and using that as the property --\n      // then, each time the property is get()ed, a dup() of that stub is returned.\n      return new PayloadStubHook(RpcPayload.deepCopyFrom(\n          followResult.value, followResult.parent, followResult.owner));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n}\n\n// StubHook wrapping an RpcPayload in local memory.\n//\n// This is used for:\n// - Resolution of a promise.\n//   - Initially on the server side, where it can be pull()ed and used in pipelining.\n//   - On the client side, after pull() has transmitted the payload.\n// - Implementing RpcTargets, on the server side.\n//   - Since the payload's root is an RpcTarget, pull()ing it will just duplicate the stub.\nexport class PayloadStubHook extends ValueStubHook {\n  constructor(payload: RpcPayload) {\n    super();\n    this.payload = payload;\n  }\n\n  private payload?: RpcPayload;  // cleared when disposed\n\n  private getPayload(): RpcPayload {\n    if (this.payload) {\n      return this.payload;\n    } else {\n      throw new Error(\"Attempted to use an RPC StubHook after it was disposed.\");\n    }\n  }\n\n  protected getValue() {\n    let payload = this.getPayload();\n    return {value: payload.value, owner: payload};\n  }\n\n  dup(): StubHook {\n    // Although dup() is documented as not copying the payload, what this really means is that\n    // you aren't expected to be able to pull() from a dup()ed hook if it is remote. However,\n    // PayloadStubHook already has the value locally, and there's nothing we can do except clone\n    // it here.\n    //\n    // TODO: Should we prohibit pull()ing from the clone? The fact that it'll be wrapped as\n    //   RpcStub instead of RpcPromise should already prevent this...\n    let thisPayload = this.getPayload();\n    return new PayloadStubHook(RpcPayload.deepCopyFrom(\n        thisPayload.value, undefined, thisPayload));\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Reminder: pull() intentionally returns the hook's own payload and not a clone. The caller\n    // only needs to dispose one of the hook or the payload. It is the caller's responsibility\n    // to not dispose the payload if they intend to keep the hook around.\n    return this.getPayload();\n  }\n\n  ignoreUnhandledRejections(): void {\n    if (this.payload) {\n      this.payload.ignoreUnhandledRejections();\n    }\n  }\n\n  dispose(): void {\n    if (this.payload) {\n      this.payload.dispose();\n      this.payload = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.payload) {\n      if (this.payload.value instanceof RpcStub) {\n        // Payload is a single stub, we should forward onRpcBroken to it.\n        // TODO: Consider prohibiting PayloadStubHook created around a single stub; should always\n        //   use the underlying stub's hook instead?\n        this.payload.value.onRpcBroken(callback);\n      }\n\n      // TODO: Should native stubs be able to implement onRpcBroken?\n    }\n  }\n}\n\nfunction disposeRpcTarget(target: RpcTarget | Function) {\n  if (Symbol.dispose in target) {\n    try {\n      ((<Disposable><any>target)[Symbol.dispose])();\n    } catch (err) {\n      // We don't actually want to throw from dispose() as this will create trouble for\n      // the RPC state machine. Instead, treat the application's error as an unhandled\n      // rejection.\n      Promise.reject(err);\n    }\n  }\n}\n\n// Many TargetStubHooks could point at the same RpcTarget. We store a refcount in a separate\n// object that they all share.\n//\n// We can't store the refcount on the RpcTarget itself because if the application chooses to pass\n// the same RpcTarget into the RPC system multiple times, we need to call this disposer multiple\n// times for consistency.\ntype BoxedRefcount = { count: number };\n\n// StubHook which wraps an RpcTarget. This has similarities to PayloadStubHook (especially when\n// the root of the payload happens to be an RpcTarget), but there can only be one RpcPayload\n// pointing at an RpcTarget whereas there can be several TargetStubHooks pointing at it. Also,\n// TargetStubHook cannot be pull()ed, because it always backs an RpcStub, not an RpcPromise.\nclass TargetStubHook extends ValueStubHook {\n  // Constructs a TargetStubHook that is not duplicated from an existing hook.\n  //\n  // If `value` is a function, `parent` is bound as its \"this\".\n  static create(value: RpcTarget | Function, parent: object | undefined) {\n    if (typeof value !== \"function\") {\n      // If the target isn't callable, we don't need to pass a `this` to it, so drop `parent`.\n      // NOTE: `typeof value === \"function\"` checks if the value is callable. This technically\n      //   works even for `RpcTarget` implementations that are callable, not just plain functions.\n      parent = undefined;\n    }\n    return new TargetStubHook(value, parent);\n  }\n\n  private constructor(target: RpcTarget | Function,\n                      parent?: object | undefined,\n                      dupFrom?: TargetStubHook) {\n    super();\n    this.target = target;\n    this.parent = parent;\n    if (dupFrom) {\n      if (dupFrom.refcount) {\n        this.refcount = dupFrom.refcount;\n        ++this.refcount.count;\n      }\n    } else if (Symbol.dispose in target) {\n      // Disposer present, so we need to refcount.\n      this.refcount = {count: 1};\n    }\n  }\n\n  private target?: RpcTarget | Function;  // cleared when disposed\n  private parent?: object | undefined;  // `this` parameter when calling `target`\n  private refcount?: BoxedRefcount;  // undefined if not needed (because target has no disposer)\n\n  private getTarget(): RpcTarget | Function {\n    if (this.target) {\n      return this.target;\n    } else {\n      throw new Error(\"Attempted to use an RPC StubHook after it was disposed.\");\n    }\n  }\n\n  protected getValue() {\n    return {value: this.getTarget(), owner: null};\n  }\n\n  dup(): StubHook {\n    return new TargetStubHook(this.getTarget(), this.parent, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    let target = this.getTarget();\n    if (\"then\" in target) {\n      // If the target is itself thenable, we allow it to be treated as a promise. This is used\n      // in particular to support wrapping a workerd-native RpcPromise or RpcProperty.\n      return Promise.resolve(target).then(resolution => {\n        return RpcPayload.fromAppReturn(resolution);\n      });\n    } else {\n      // This shouldn't be called since RpcTarget always becomes RpcStub, not RpcPromise, and you\n      // can only pull a promise.\n      return Promise.reject(new Error(\"Tried to resolve a non-promise stub.\"));\n    }\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    if (this.target) {\n      if (this.refcount) {\n        if (--this.refcount.count == 0) {\n          disposeRpcTarget(this.target);\n        }\n      }\n\n      this.target = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // TODO: Should RpcTargets be able to implement onRpcBroken?\n  }\n}\n\n// StubHook derived from a Promise for some other StubHook. Waits for the promise and then\n// forward calls, being careful to honor e-order.\nexport class PromiseStubHook extends StubHook {\n  private promise: Promise<StubHook>;\n  private resolution: StubHook | undefined;\n\n  constructor(promise: Promise<StubHook>) {\n    super();\n\n    this.promise = promise.then(res => { this.resolution = res; return res; });\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    // Note: We can't use `resolution` even if it's available because it could technically break\n    //   e-order: A call() that arrives just after the resolution could be delivered faster than\n    //   a call() that arrives just before. Keeping the promise around and always waiting on it\n    //   avoids the problem.\n    // TODO: Is there a way around this?\n\n    // Once call() returns (synchronously), we can no longer touch the original args. Since we\n    // can't serialize them yet, we have to deep-copy them now.\n    args.ensureDeepCopied();\n\n    return new PromiseStubHook(this.promise.then(hook => hook.call(path, args)));\n  }\n\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    // Not yet resolved — we don't know if this will be local or remote. Deep-copy args and wait.\n    // No size is returned because we can't know yet; this means the caller will await the promise,\n    // which is the safe default (serialized writes).\n    args.ensureDeepCopied();\n    let promise = this.promise.then(hook => {\n      let result = hook.stream(path, args);\n      return result.promise;\n    });\n    return { promise };\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    return new PromiseStubHook(this.promise.then(\n        hook => hook.map(path, captures, instructions),\n        err => {\n          for (let cap of captures) {\n            cap.dispose();\n          }\n          throw err;\n        }));\n  }\n\n  get(path: PropertyPath): StubHook {\n    // Note: e-order matters for get(), just like call(), in case the property has a getter.\n    return new PromiseStubHook(this.promise.then(hook => hook.get(path)));\n  }\n\n  dup(): StubHook {\n    if (this.resolution) {\n      return this.resolution.dup();\n    } else {\n      return new PromiseStubHook(this.promise.then(hook => hook.dup()));\n    }\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Luckily, resolutions are not subject to e-order, so it's safe to use `this.resolution`\n    // here. In fact, it is required to maintain e-order elsewhere: If this promise is being used\n    // as the input to some other local call (via promise pipelining), we need to make sure that\n    // other call is not delayed at all when this promise is already resolved.\n    if (this.resolution) {\n      return this.resolution.pull();\n    } else {\n      return this.promise.then(hook => hook.pull());\n    }\n  }\n\n  ignoreUnhandledRejections(): void {\n    if (this.resolution) {\n      this.resolution.ignoreUnhandledRejections();\n    } else {\n      this.promise.then(res => {\n        res.ignoreUnhandledRejections();\n      }, err => {\n        // Ignore the error!\n      });\n    }\n  }\n\n  dispose(): void {\n    if (this.resolution) {\n      this.resolution.dispose();\n    } else {\n      this.promise.then(hook => {\n        hook.dispose();\n      }, err => {\n        // nothing to dispose\n      });\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.resolution) {\n      this.resolution.onBroken(callback);\n    } else {\n      this.promise.then(hook => {\n        hook.onBroken(callback);\n      }, callback);\n    }\n  }\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\n/// <reference types=\"@cloudflare/workers-types\" />\n\n// Support for sending WebSockets over RPC, as the `webSocket` property of a `Response`\n// representing a completed HTTP upgrade. (`Response.webSocket` is a Cloudflare Workers extension\n// to the Fetch API.)\n//\n// A live socket can't literally be transferred, so we represent it as a pair of streams: the\n// sender wraps its socket in a ReadableStream (messages arriving on the socket) and a\n// WritableStream (messages to send on the socket), and those are serialized using Cap'n Web's\n// existing stream support. That means messages start streaming toward the receiver the moment\n// the Response is serialized -- before the receiver even knows they're coming -- and both\n// directions get the streams' flow control.\n//\n// Messages are chunks of type string (text frames) or Uint8Array (binary frames). Closure with a\n// code and reason is conveyed in-band as a final `{\"close\": {\"code\", \"reason\"}}` chunk, since\n// the streams themselves can only signal an undifferentiated end-of-stream.\n//\n// On the receiving side, the pair is wrapped back up in a WebSocket-like object\n// (TunneledWebSocket below). A tunneled socket is fully functional; in particular it can carry a\n// nested Cap'n Web session. __tests__/websocket-tunnel.test.ts proves transport equivalence by\n// running the shared session test battery (__tests__/session-battery.ts) over a tunneled socket,\n// mirroring how index.test.ts runs the same battery over a direct WebSocket connection.\n\nimport { StubHook, RpcPayload, streamImpl } from \"./core.js\";\n\n// The subset of the WebSocket API that we rely on. Covers browser WebSockets, the `ws` package,\n// Cloudflare Workers WebSockets (which add accept()), and TunneledWebSocket itself (which is\n// what we wrap when proxying an already-tunneled socket onward to a third party).\ninterface WebSocketLike {\n  send(data: string | Uint8Array): void;\n  close(code?: number, reason?: string): void;\n  accept?(): void;\n  addEventListener(type: string, listener: (event: any) => void): void;\n  binaryType?: string;\n}\n\n// A chunk conveying socket closure, sent as the final chunk before the stream ends.\ntype CloseRecord = { close: { code: number, reason: string } };\n\nfunction isCloseRecord(chunk: unknown): chunk is CloseRecord {\n  return typeof chunk === \"object\" && chunk !== null && \"close\" in chunk;\n}\n\n// Coerce a message payload to the types we send as chunks: text stays a string, binary data\n// becomes a Uint8Array.\nfunction toStringOrBytes(data: unknown): string | Uint8Array {\n  if (typeof data === \"string\") {\n    return data;\n  } else if (data instanceof Uint8Array) {\n    return data;\n  } else if (data instanceof ArrayBuffer) {\n    return new Uint8Array(data);\n  } else if (ArrayBuffer.isView(data)) {\n    return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n  } else {\n    throw new TypeError(\"Unsupported WebSocket message type.\");\n  }\n}\n\n// Close `socket`, propagating `code` and `reason` when possible. close() only accepts code 1000\n// or codes in the range 3000-4999, but a code being propagated from a close *event* can fall\n// outside that (e.g. 1005 \"no status received\" or 1006 \"abnormal closure\"); codes that can't be\n// re-sent are dropped.\nfunction closeSocket(socket: WebSocketLike, code?: number, reason?: string): void {\n  try {\n    if (code === 1000 || (code !== undefined && code >= 3000 && code <= 4999)) {\n      socket.close(code, reason);\n    } else {\n      socket.close();\n    }\n  } catch {\n    // Probably already closed or closing.\n  }\n}\n\n// Wraps the sender-side socket in a pair of streams suitable for serialization. Must be called\n// at most once per socket: it attaches the socket's event listeners.\nexport function webSocketToStreams(socket: WebSocketLike)\n    : { readable: ReadableStream, writable: WritableStream } {\n  // Workers WebSockets must be accept()ed before they can be used; conveniently, they also\n  // buffer incoming messages until then, so nothing is lost even though we only get to attach\n  // listeners when the Response is serialized. (Sockets without accept() -- e.g. `ws` -- may\n  // drop messages that arrive before that point; there's nothing we can do about those, as the\n  // serialization layer is the first to see the socket at all.)\n  socket.accept?.();\n\n  // Where the socket distinguishes (i.e. in browsers), ask for binary messages as ArrayBuffer\n  // rather than Blob, which can't be read synchronously.\n  try { socket.binaryType = \"arraybuffer\"; } catch {}\n\n  let closed = false;\n\n  let readable = new ReadableStream({\n    start(controller) {\n      socket.addEventListener(\"message\", (event: any) => {\n        if (closed) return;\n        try {\n          controller.enqueue(toStringOrBytes(event.data));\n        } catch (err) {\n          closed = true;\n          try { controller.error(err); } catch {}\n          closeSocket(socket);\n        }\n      });\n      socket.addEventListener(\"close\", (event: any) => {\n        if (closed) return;\n        closed = true;\n        try {\n          controller.enqueue(\n              { close: { code: event.code ?? 1005, reason: event.reason ?? \"\" } });\n          controller.close();\n        } catch {}\n      });\n      socket.addEventListener(\"error\", () => {\n        if (closed) return;\n        closed = true;\n        try { controller.error(new Error(\"WebSocket failed.\")); } catch {}\n      });\n    },\n\n    cancel() {\n      // The receiver released the socket without consuming it (or canceled mid-stream); there's\n      // no one left to talk to.\n      closed = true;\n      closeSocket(socket);\n    },\n  });\n\n  let writable = new WritableStream({\n    write(chunk) {\n      if (isCloseRecord(chunk)) {\n        closeSocket(socket, chunk.close.code, chunk.close.reason);\n      } else {\n        socket.send(toStringOrBytes(chunk));\n      }\n    },\n    close() {\n      closeSocket(socket);\n    },\n    abort() {\n      closeSocket(socket);\n    },\n  });\n\n  return { readable, writable };\n}\n\ntype Listener = (event: any) => void;\n\n// A WebSocket-like object wrapping the receiving ends of a tunneled socket's stream pair. It is\n// born in the OPEN state (the underlying socket was already connected when it was serialized)\n// and never fires an \"open\" event -- just like the sockets of a Cloudflare Workers\n// WebSocketPair. Implements enough of the WebSocket API to be passed to\n// newWebSocketRpcSession().\n//\n// Lifetime: the streams passed to the constructor are owned by the payload the Response arrived\n// in. The socket only takes its own references -- locking the readable and duplicating the\n// writable's hook -- when the application first interacts with it: accept(), attaching a\n// listener, send(), or close(). This mirrors how an unread ReadableStream is canceled when its\n// payload is disposed unless the app locks it: an upgrade Response whose socket nobody touched\n// releases both streams when the payload is disposed (e.g. when the RPC call it arrived in\n// returns), closing the underlying connection rather than holding it open for a receiver that\n// will never use it. In particular, an RPC method that receives an upgrade Response in params\n// and wants to keep the socket beyond the call must claim it -- most idiomatically with\n// accept(), just like a Workers WebSocket -- before returning.\n//\n// Note that messages stream in regardless of claiming: they accumulate in the readable's buffer\n// (bounded by the streams' flow-control window) so they're already on hand when the app attaches\n// its first listener.\nexport class TunneledWebSocket {\n  static readonly CONNECTING = 0;\n  static readonly OPEN = 1;\n  static readonly CLOSING = 2;\n  static readonly CLOSED = 3;\n\n  #readable: ReadableStream;\n  // Hook for the sender's WritableStream. Borrowed from the containing payload until #claim(),\n  // an owned dup() thereafter; undefined once released (or if claiming failed).\n  #writableHook?: StubHook;\n  #claimed = false;\n  #writer?: WritableStreamDefaultWriter;\n  #readyState: number = TunneledWebSocket.OPEN;\n  #listeners = new Map<string, { listener: Listener, once: boolean }[]>();\n  #onmessage: Listener | null = null;\n  #onclose: Listener | null = null;\n  #onerror: Listener | null = null;\n\n  constructor(readable: ReadableStream, writableHook: StubHook) {\n    this.#readable = readable;\n    this.#writableHook = writableHook;\n    writableHook.onBroken((error: any) => this.#fail(error));\n  }\n\n  get readyState(): number { return this.#readyState; }\n\n  // (Assigning null clears a handler; that's not an interaction with the socket, so it does not\n  // claim it.)\n  get onmessage() { return this.#onmessage; }\n  set onmessage(listener: Listener | null) { this.#onmessage = listener; if (listener) this.#claim(); }\n  get onclose() { return this.#onclose; }\n  set onclose(listener: Listener | null) { this.#onclose = listener; if (listener) this.#claim(); }\n  get onerror() { return this.#onerror; }\n  set onerror(listener: Listener | null) { this.#onerror = listener; if (listener) this.#claim(); }\n\n  // Claims the socket (see class comment). Otherwise a no-op, for compatibility with the Workers\n  // WebSocket API; the sender side accepted the real socket when it was serialized.\n  accept(): void {\n    this.#claim();\n  }\n\n  send(data: string | ArrayBuffer | ArrayBufferView): void {\n    if (this.#readyState !== TunneledWebSocket.OPEN) {\n      throw new Error(\"Can't call send() on a WebSocket that is closing or closed.\");\n    }\n    this.#claim();\n    this.#write(toStringOrBytes(data));\n  }\n\n  close(code?: number, reason?: string): void {\n    if (this.#readyState >= TunneledWebSocket.CLOSING) return;\n    this.#claim();\n    this.#readyState = TunneledWebSocket.CLOSING;\n\n    // Closing the sender's socket makes its close event come back through the readable,\n    // completing the close.\n    if (this.#writer) {\n      this.#write({ close: { code: code ?? 1005, reason: reason ?? \"\" } });\n      this.#writer.close().catch(() => {});\n    }\n  }\n\n  [Symbol.dispose](): void {\n    this.close();\n    this.#release();\n  }\n\n  addEventListener(type: string, listener: Listener, options?: { once?: boolean }): void {\n    let list = this.#listeners.get(type);\n    if (!list) {\n      list = [];\n      this.#listeners.set(type, list);\n    }\n    list.push({ listener, once: !!options?.once });\n\n    // Claim after registering, so that if the tunnel turns out to be gone, this listener still\n    // hears the resulting error/close events.\n    this.#claim();\n  }\n\n  removeEventListener(type: string, listener: Listener): void {\n    let list = this.#listeners.get(type);\n    let index = list?.findIndex(entry => entry.listener === listener) ?? -1;\n    if (index >= 0) {\n      list!.splice(index, 1);\n    }\n  }\n\n  #dispatchEvent(type: string, event: any): void {\n    for (let entry of [...this.#listeners.get(type) ?? []]) {\n      if (entry.once) this.removeEventListener(type, entry.listener);\n      entry.listener(event);\n    }\n    let handler = (this as any)[\"on\" + type];\n    if (typeof handler === \"function\") handler.call(this, event);\n  }\n\n  // Takes our own references to the stream pair and starts dispatching messages. Called on the\n  // app's first interaction with the socket; until then, the streams belong to the containing\n  // payload.\n  #claim(): void {\n    if (this.#claimed) return;\n    this.#claimed = true;\n\n    if (!this.#writableHook || this.#readyState === TunneledWebSocket.CLOSED) return;\n\n    let writableHook;\n    try {\n      writableHook = this.#writableHook.dup();\n    } catch (err) {\n      // The payload was disposed before the app claimed the socket, so the streams have already\n      // been released and the sender has closed the connection. Fail asynchronously so that a\n      // listener whose registration triggered this claim still hears about it.\n      this.#writableHook = undefined;\n      queueMicrotask(() => this.#fail(err));\n      return;\n    }\n    this.#writableHook = writableHook;\n\n    // Wrapping the hook in a proxy WritableStream gets us the streams' flow control on sends.\n    this.#writer = streamImpl.createWritableStreamFromHook(writableHook).getWriter();\n\n    // Locking the readable prevents payload disposal from canceling it.\n    this.#readLoop(this.#readable.getReader()).catch(err => this.#fail(err));\n  }\n\n  async #readLoop(reader: ReadableStreamDefaultReader): Promise<void> {\n    while (true) {\n      let { done, value } = await reader.read();\n      if (this.#readyState === TunneledWebSocket.CLOSED) return;\n\n      if (done) {\n        // Stream ended without a close record; treat as a closure with no status, like a\n        // WebSocket whose connection ended without a Close frame.\n        this.#close(1005, \"\");\n        return;\n      } else if (isCloseRecord(value)) {\n        this.#close(value.close.code, value.close.reason);\n        return;\n      } else {\n        this.#dispatchEvent(\"message\", { type: \"message\", data: toStringOrBytes(value) });\n      }\n    }\n  }\n\n  #close(code: number, reason: string): void {\n    this.#readyState = TunneledWebSocket.CLOSED;\n    this.#release();\n    this.#dispatchEvent(\"close\", { type: \"close\", code, reason });\n  }\n\n  // Called when the streams or the RPC session failed: act like a failed WebSocket.\n  #fail(error: any): void {\n    if (this.#readyState === TunneledWebSocket.CLOSED) return;\n    this.#readyState = TunneledWebSocket.CLOSED;\n    this.#release();\n    this.#dispatchEvent(\"error\", { type: \"error\", error });\n    this.#dispatchEvent(\"close\", { type: \"close\", code: 1006, reason: \"WebSocket tunnel failed.\" });\n  }\n\n  // Write a chunk, fire-and-forget. A rejection means the socket or session has failed, which\n  // we'll separately hear about through the readable or onBroken().\n  #write(chunk: unknown): void {\n    this.#writer?.write(chunk).catch(() => {});\n  }\n\n  #release(): void {\n    // Only dispose the hook if it's our own dup; before #claim() it belongs to the payload.\n    if (this.#claimed) this.#writableHook?.dispose();\n    this.#writableHook = undefined;\n    this.#writer?.close().catch(() => {});\n    this.#writer = undefined;\n  }\n}\n\n// Reconstructs an upgrade Response on the receiving side, given the receiving ends of the stream\n// pair.\n//\n// On Cloudflare Workers, the runtime requires a native WebSocket to complete an HTTP upgrade\n// (e.g. by returning the Response from a fetch handler), and can also mint Responses with status\n// 101. So there, we create a native WebSocketPair, pump one end to and from the tunneled socket,\n// and attach the other end to the Response.\n//\n// On other platforms the Response carries a TunneledWebSocket directly, and keeps the default\n// status 200, since the standard Response constructor refuses to produce 1xx statuses.\nexport function makeUpgradeResponse(\n    readable: ReadableStream, writableHook: StubHook, init: ResponseInit): Response {\n  let socket = new TunneledWebSocket(readable, writableHook);\n\n  if (typeof WebSocketPair !== \"undefined\") {\n    let pair = new WebSocketPair();\n    pumpNativeSocket(pair[1], socket);\n    return new Response(null, { ...init, status: 101, webSocket: pair[0] } as ResponseInit);\n  } else {\n    let response = new Response(null, init);\n    Object.defineProperty(response, \"webSocket\", { value: socket, configurable: true });\n    return response;\n  }\n}\n\n// Forward messages and closure between a native WebSocket (one end of a WebSocketPair) and a\n// tunneled socket, in both directions.\n//\n// Note that attaching the pump's listeners claims the tunneled socket immediately, so on Workers\n// an ignored upgrade Response does not release the tunnel when its payload is disposed -- we\n// can't observe whether the app ever accept()s the native end. The runtime cleans up the pair\n// when the session ends.\nfunction pumpNativeSocket(native: WebSocket, tunneled: TunneledWebSocket): void {\n  native.accept();\n\n  // Sends can race with closure from the other direction; messages that arrive after the\n  // destination has begun closing are dropped, as they would be on a direct connection.\n  native.addEventListener(\"message\", event => {\n    try { tunneled.send(toStringOrBytes(event.data)); } catch {}\n  });\n  tunneled.addEventListener(\"message\", event => {\n    try { native.send(event.data); } catch {}\n  });\n\n  native.addEventListener(\"close\", event => tunneled.close(event.code, event.reason));\n  native.addEventListener(\"error\", () => tunneled.close());\n\n  tunneled.addEventListener(\"close\", event => closeSocket(native, event.code, event.reason));\n  tunneled.addEventListener(\"error\", () => closeSocket(native));\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, RpcPayload, typeForRpc, RpcStub, RpcPromise, LocatedPromise, RpcTarget, unwrapStubAndPath, streamImpl, PromiseStubHook, PayloadStubHook, type RpcCallHandler } from \"./core.js\";\nimport { webSocketToStreams, makeUpgradeResponse } from \"./websocket-streams.js\";\n\nexport type ImportId = number;\nexport type ExportId = number;\n\n/**\n * Encoding levels determine what representation the RPC system hands to the transport.\n * Each level names what the transport can assume about message values.\n *\n * - `\"string\"`: JSON string. Default, used by HTTP batch and WebSocket transports.\n * - `\"jsonCompatible\"`: JSON-compatible JS value tree. For custom encoders.\n * - `\"jsonCompatibleWithBytes\"`: Like `\"jsonCompatible\"` but Uint8Array stays raw.\n * - `\"structuredClonable\"`: Structured-clonable native values pass through where possible.\n *\n * @example\n * ```ts\n * // What happens to Uint8Array([1, 2, 3]) at each level:\n * \"string\"          → '[\"bytes\",\"AQID\"]'           // JSON string with base64\n * \"jsonCompatible\"          → [\"bytes\", \"AQID\"]      // JS array with base64\n * \"jsonCompatibleWithBytes\" → [\"bytes\", Uint8Array]  // JS array with raw bytes\n * \"structuredClonable\"      → [\"bytes\", Uint8Array]  // + Date, BigInt stay native\n * ```\n */\nexport type EncodingLevel = \"string\" | \"jsonCompatible\" | \"jsonCompatibleWithBytes\" |\n    \"structuredClonable\";\n\n// =======================================================================================\n// Resource limits applied while deserializing messages from a peer.\n//\n// These guard against resource-exhaustion attacks from untrusted peers (see issue #184). They are\n// purely *local, receiver-side* decisions: the protocol has no negotiation step, so a peer cannot\n// learn or agree on these values. Consequently the defaults are chosen to be far larger than any\n// legitimate message, so that no honest sender is ever rejected. A peer that exceeds a limit has\n// its message rejected (a TypeError is thrown), which tears down the session via abort().\n\nexport interface RpcLimits {\n  // Maximum number of magnitude digits permitted in a [\"bigint\", \"...\"] wire value, excluding a\n  // leading \"-\" sign.\n  //\n  // Bigints are serialized as decimal strings. Decimal parsing via BigInt() is synchronous and\n  // superlinear in the number of digits, so this cap bounds the worst-case parse cost.\n  //\n  // The default is far larger than practical big-integer or cryptographic values, but far below\n  // the millions of decimal digits needed to cause meaningful blocking.\n  maxBigIntDigits: number;\n\n  // Maximum nesting depth of a single deserialized message. Guards against stack overflow from a\n  // deeply-nested payload (e.g. [[[[...]]]]). This is enforced uniformly across the whole message,\n  // including nested call arguments that are delivered as separate RpcPayloads.\n  maxDepth: number;\n\n  // Maximum size of a single incoming message string, measured in UTF-16 code units (JavaScript\n  // String.length), before it is JSON-parsed. This is not a byte count: a string of N code units\n  // may occupy more than N bytes when encoded as UTF-8. Enforced in the session read loop, after\n  // the transport has already returned a complete string, to bound JSON.parse and downstream\n  // deserialization work. True byte-level enforcement belongs in the transport/socket, so apps\n  // exposed to untrusted peers should also configure transport/socket-native payload limits where\n  // available.\n  maxMessageSize: number;\n}\n\nexport const DEFAULT_MAX_DEPTH = 256;\n\nexport const DEFAULT_LIMITS: RpcLimits = {\n  maxBigIntDigits: 16384,\n  maxDepth: DEFAULT_MAX_DEPTH,\n  maxMessageSize: 32 * 1024 * 1024,\n};\n\n// =======================================================================================\n\nconst NATIVE_LITTLE_ENDIAN = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n\nconst BYTE_CONTAINER_TYPE_NAMES = [\n  \"ArrayBuffer\",\n  \"DataView\",\n  \"Int8Array\",\n  \"Uint8Array\",\n  \"Uint8ClampedArray\",\n  \"Int16Array\",\n  \"Uint16Array\",\n  \"Int32Array\",\n  \"Uint32Array\",\n  \"BigInt64Array\",\n  \"BigUint64Array\",\n  \"Float32Array\",\n  \"Float64Array\",\n] as const;\n\ntype ByteContainerTypeName = typeof BYTE_CONTAINER_TYPE_NAMES[number];\ntype MarkedByteContainerTypeName = Exclude<ByteContainerTypeName, \"Uint8Array\">;\n\nfunction isValidByteContainerName(value: string): value is ByteContainerTypeName {\n  return (BYTE_CONTAINER_TYPE_NAMES as readonly string[]).includes(value);\n}\n\n// Listing every type, including those without multi-byte elements, makes adding\n// a new ByteContainerTypeName a compile error until its element size is considered.\nconst TYPED_ARRAY_ELEMENT_SIZE: Record<ByteContainerTypeName, number | undefined> = {\n  ArrayBuffer: undefined,\n  DataView: undefined,\n  Int8Array: undefined,\n  Uint8Array: undefined,\n  Uint8ClampedArray: undefined,\n  Int16Array: 2,\n  Uint16Array: 2,\n  Int32Array: 4,\n  Uint32Array: 4,\n  BigInt64Array: 8,\n  BigUint64Array: 8,\n  Float32Array: 4,\n  Float64Array: 8,\n};\n\n// Uint8Array intentionally isn't included because it uses the markerless legacy form.\nconst BYTE_CONTAINER_PROTOTYPES: Record<MarkedByteContainerTypeName, object> = {\n  ArrayBuffer: ArrayBuffer.prototype,\n  DataView: DataView.prototype,\n  Int8Array: Int8Array.prototype,\n  Uint8ClampedArray: Uint8ClampedArray.prototype,\n  Int16Array: Int16Array.prototype,\n  Uint16Array: Uint16Array.prototype,\n  Int32Array: Int32Array.prototype,\n  Uint32Array: Uint32Array.prototype,\n  BigInt64Array: BigInt64Array.prototype,\n  BigUint64Array: BigUint64Array.prototype,\n  Float32Array: Float32Array.prototype,\n  Float64Array: Float64Array.prototype,\n};\n\nconst BYTE_CONTAINER_TYPE_BY_PROTOTYPE = new Map<object, MarkedByteContainerTypeName>();\nfor (let type of Object.keys(BYTE_CONTAINER_PROTOTYPES) as MarkedByteContainerTypeName[]) {\n  BYTE_CONTAINER_TYPE_BY_PROTOTYPE.set(BYTE_CONTAINER_PROTOTYPES[type], type);\n}\n\n// Reverse each element's bytes in place. Production callers only need this on\n// big-endian hosts; it is exported solely so the behavior can be tested on\n// little-endian hosts.\nexport function swapByteOrder(bytes: Uint8Array, elementSize: number): void {\n  if (elementSize !== 2 && elementSize !== 4 && elementSize !== 8) {\n    throw new RangeError(`Unsupported element size: ${elementSize}`);\n  }\n\n  let view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n  for (let offset = 0; offset < bytes.byteLength; offset += elementSize) {\n    switch (elementSize) {\n      case 2:\n        view.setUint16(offset, view.getUint16(offset, false), true);\n        break;\n      case 4:\n        view.setUint32(offset, view.getUint32(offset, false), true);\n        break;\n      case 8:\n        view.setBigUint64(offset, view.getBigUint64(offset, false), true);\n        break;\n    }\n  }\n}\n\nexport interface Exporter {\n  exportStub(hook: StubHook): ExportId;\n  exportPromise(hook: StubHook): ExportId;\n  getImport(hook: StubHook): ImportId | undefined;\n\n  // If a serialization error occurs after having exported some capabilities, this will be called\n  // to roll back the exports.\n  unexport(ids: Array<ExportId>): void;\n\n  // Creates a pipe by sending a [\"pipe\"] message, then starts pumping the given ReadableStream\n  // into the pipe's writable end. Returns the import ID assigned to the pipe. `hook` should be\n  // disposed when the pipe finishes.\n  createPipe(readable: ReadableStream, hook: StubHook): ImportId;\n\n  onSendError(error: Error): Error | void;\n}\n\nclass NullExporter implements Exporter {\n  exportStub(stub: StubHook): never {\n    throw new Error(\"Cannot serialize RPC stubs without an RPC session.\");\n  }\n  exportPromise(stub: StubHook): never {\n    throw new Error(\"Cannot serialize RPC stubs without an RPC session.\");\n  }\n  getImport(hook: StubHook): ImportId | undefined {\n    return undefined;\n  }\n  unexport(ids: Array<ExportId>): void {}\n  createPipe(readable: ReadableStream): never {\n    throw new Error(\"Cannot create pipes without an RPC session.\");\n  }\n\n  onSendError(error: Error): Error | void {}\n}\n\nconst NULL_EXPORTER = new NullExporter();\n\n// Collect all bytes from a ReadableStream into a Blob with the given MIME type. Used on the\n// receive side to assemble a Blob from a pipe stream before delivering to user code.\n//\n// `Response` is a standard global in every runtime we support (Node >=18, browsers, workerd), so\n// we can rely on `Response.blob()` for the heavy lifting. `Response.blob()` may discard the\n// caller-specified MIME type, so we `slice()` to reattach it if needed.\nasync function streamToBlob(stream: ReadableStream, type: string): Promise<Blob> {\n  let b = await new Response(stream).blob();\n  return b.type === type ? b : b.slice(0, b.size, type);\n}\n\n// Maps error name to error class for deserialization. Null-prototype so a wire-supplied (untrusted)\n// name can't resolve to an inherited member like `constructor` (which would build a `String`\n// wrapper, not an `Error`) or `toString`; unknown names fall back to `Error`.\nconst ERROR_TYPES: Record<string, any> = {\n  __proto__: null,\n  Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, AggregateError,\n  // TODO: DOMError? Others?\n};\n\n// Converts fully-hydrated messages into object trees that are JSON-serializable for sending over\n// the wire. This is used to implement serialization -- but it doesn't take the last step of\n// actually converting to a string. (The name is meant to be the opposite of \"Evaluator\", which\n// implements the opposite direction.)\nexport class Devaluator {\n  private constructor(\n    private exporter: Exporter,\n    private source: RpcPayload | undefined,\n    private encodingLevel: EncodingLevel\n  ) {}\n\n  // Devaluate the given value.\n  // * value: The value to devaluate.\n  // * parent: The value's parent object, which would be used as `this` if the value were called\n  //     as a function.\n  // * exporter: Callbacks to the RPC session for exporting capabilities found in this message.\n  // * source: The RpcPayload which contains the value, and therefore owns stubs within.\n  // * encodingLevel: How much encoding to apply (default \"string\").\n  //\n  // Returns: The devaluated value, ready to be JSON-serialized (or passed to transport directly\n  // for non-string levels).\n  public static devaluate(\n      value: unknown, parent?: object, exporter: Exporter = NULL_EXPORTER, source?: RpcPayload,\n      encodingLevel: EncodingLevel = \"string\")\n      : unknown {\n    let devaluator = new Devaluator(exporter, source, encodingLevel);\n    try {\n      return devaluator.devaluateImpl(value, parent, 0);\n    } catch (err) {\n      if (devaluator.exports) {\n        try {\n          exporter.unexport(devaluator.exports);\n        } catch (err) {\n          // probably a side effect of the original error, ignore it\n        }\n      }\n      // TODO: This rollback only releases exports. Pipes created via `createPipe` (for\n      // ReadableStreams, Blobs, and the Firefox request-body fallback) have already sent a\n      // [\"pipe\"] frame and started pumping.\n      throw err;\n    }\n  }\n\n  private exports?: Array<ExportId>;\n\n  private devaluateImpl(value: unknown, parent: object | undefined, depth: number): unknown {\n    if (depth >= DEFAULT_MAX_DEPTH) {\n      throw new Error(\n          \"Serialization exceeded maximum allowed depth. (Does the message contain cycles?)\");\n    }\n\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\": {\n        let msg;\n        try {\n          msg = `Cannot serialize value: ${value}`;\n        } catch (err) {\n          msg = \"Cannot serialize value: (couldn't stringify value)\";\n        }\n        throw new TypeError(msg);\n      }\n\n      case \"primitive\":\n        if (typeof value === \"number\" && !isFinite(value)) {\n          // At structuredClonable level, keep Infinity/NaN as native values\n          if (this.encodingLevel === \"structuredClonable\") {\n            return value;\n          }\n          if (value === Infinity) {\n            return [\"inf\"];\n          } else if (value === -Infinity) {\n            return [\"-inf\"];\n          } else {\n            return [\"nan\"];\n          }\n        } else {\n          // Supported directly by JSON.\n          return value;\n        }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        let result: Record<string, unknown> = {};\n        for (let key in object) {\n          result[key] = this.devaluateImpl(object[key], object, depth + 1);\n        }\n        return result;\n      }\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        let result = new Array(len);\n        for (let i = 0; i < len; i++) {\n          result[i] = this.devaluateImpl(array[i], array, depth + 1);\n        }\n        // Wrap literal arrays in an outer one-element array, to \"escape\" them.\n        return [result];\n      }\n\n      case \"bigint\":\n        // At structuredClonable level, keep BigInt as native value\n        if (this.encodingLevel === \"structuredClonable\") {\n          return value;\n        }\n        return [\"bigint\", (<bigint>value).toString()];\n\n      case \"date\": {\n        // At structuredClonable level, keep Date as native value\n        if (this.encodingLevel === \"structuredClonable\") {\n          return value;\n        }\n        const time = (<Date>value).getTime();\n        return [\"date\", Number.isNaN(time) ? null : time];\n      }\n\n      case \"bytes\": {\n        let alternateTypeName = BYTE_CONTAINER_TYPE_BY_PROTOTYPE.get(Object.getPrototypeOf(value));\n        let bytes: Uint8Array;\n        if (alternateTypeName === \"ArrayBuffer\") {\n          bytes = new Uint8Array(value as ArrayBuffer);\n        } else if (alternateTypeName === undefined) {\n          bytes = value as Uint8Array;\n        } else {\n          let view = value as ArrayBufferView;\n          bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n          let elementSize = TYPED_ARRAY_ELEMENT_SIZE[alternateTypeName];\n          if (!NATIVE_LITTLE_ENDIAN && elementSize) {\n            bytes = bytes.slice();\n            swapByteOrder(bytes, elementSize);\n          }\n        }\n\n        // At structuredClonable or jsonCompatibleWithBytes level, keep the bytes raw.\n        if (this.encodingLevel === \"structuredClonable\" ||\n            this.encodingLevel === \"jsonCompatibleWithBytes\") {\n          return alternateTypeName === undefined\n              ? [\"bytes\", bytes] : [\"bytes\", bytes, alternateTypeName];\n        }\n\n        let b64: string;\n        if (bytes.toBase64) {\n          b64 = bytes.toBase64({omitPadding: true});\n        } else if (typeof Buffer !== \"undefined\") {\n          let buf = bytes instanceof Buffer ? bytes\n              : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n          b64 = buf.toString(\"base64\");\n        } else {\n          let binary = \"\";\n          for (let i = 0; i < bytes.length; i++) {\n            binary += String.fromCharCode(bytes[i]);\n          }\n          b64 = btoa(binary);\n        }\n        b64 = b64.replace(/=+$/, \"\");\n        return alternateTypeName === undefined ? [\"bytes\", b64] : [\"bytes\", b64, alternateTypeName];\n      }\n\n      case \"headers\":\n        // The `Headers` TS type apparently doesn't declare itself as being\n        // Iterable<[string, string]>, but it is.\n        return [\"headers\", [...<Iterable<[string, string]>>value]];\n\n      case \"request\": {\n        let req = <Request>value;\n        let init: Record<string, unknown> = {};\n\n        // For many properties below, the official Fetch spec says they must always be present,\n        // but some platforms don't support them. So, we check both whether the property exists,\n        // and whether it is equal to the default, before bothering to add it to `init`.\n\n        if (req.method !== \"GET\") init.method = req.method;\n\n        let headers = [...<Iterable<[string, string]>><any>req.headers];\n        if (headers.length > 0) {\n          // Note that we don't need to serialize this as [\"headers\", headers] because we are only\n          // trying to create a valid RequestInit object.\n          init.headers = headers;\n        }\n\n        if (req.body) {\n          init.body = this.devaluateImpl(req.body, req, depth + 1);\n\n          // Apparently the fetch spec technically requires that `duplex` be specified when a\n          // body is specified, and Chrome in fact requires this, and requires the value is \"half\".\n          // Workers hasn't implemented this (and actually supports full duplex by default, lol).\n          // The TS types for Request currently don't define this property, but it is there (on\n          // Chrome at least).\n          init.duplex = (<any>req).duplex || \"half\";\n        } else if (req.body === undefined &&\n            ![\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\", \"DELETE\"].includes(req.method)) {\n          // If the body is undefined rather than null, most likely we're on a platform that\n          // doesn't support request body streams (*cough*Firefox*cough*). We'll need to hack\n          // around this by using `req.arrayBuffer()` to get the body. Unfortunately this is async,\n          // so we can't just embed the resulting body into the message we are constructing. We\n          // will actually have to construct a ReadableStream. Ugh!\n\n          let bodyPromise = req.arrayBuffer();\n\n          let readable = new ReadableStream<Uint8Array>({\n            async start(controller) {\n              try {\n                // `as Uint8Array` is needed here to work around some sort of weird bug in the TS\n                // types where `new Uint8Array` somehow doesn't return a `Uint8Array`. Instead it\n                // somehow returns `Uint8Array<ArrayBuffer>` -- but `Uint8Array` is not a generic\n                // type! WTF?\n                // TODO(cleanup): This is apparently fixed in TS 6.\n                controller.enqueue(new Uint8Array(await bodyPromise) as Uint8Array);\n                controller.close();\n              } catch (err) {\n                controller.error(err);\n              }\n            }\n          });\n\n          // We can't recurse to devaluateImpl() to serialize the body because it'll call\n          // source.getHookForReadableStream(), adding a hook on the payload which isn't actually\n          // reachable by walking the payload, which will cause trouble later. So we have to\n          // inline it a bit here...\n          let hook = streamImpl.createReadableStreamHook(readable);\n          let importId = this.exporter.createPipe(readable, hook);\n          init.body = [\"readable\", importId];\n          init.duplex = (<any>req).duplex || \"half\";\n        }\n\n        if (req.cache && req.cache !== \"default\") init.cache = req.cache;\n        if (req.redirect !== \"follow\") init.redirect = req.redirect;\n        if (req.integrity) init.integrity = req.integrity;\n\n        // These properties are only meaningful in browsers and not supported by most WinterCG\n        // (server-side) platforms.\n        if (req.mode && req.mode !== \"cors\") init.mode = req.mode;\n        if (req.credentials && req.credentials !== \"same-origin\") {\n          init.credentials = req.credentials;\n        }\n        if (req.referrer && req.referrer !== \"about:client\") init.referrer = req.referrer;\n        if (req.referrerPolicy) init.referrerPolicy = req.referrerPolicy;\n        if (req.keepalive) init.keepalive = req.keepalive;\n\n        // These properties are specific to Cloudflare Workers. Cast the request to `any` to\n        // silence type errors on other platforms.\n        let cfReq = req as any;\n        if (cfReq.cf) init.cf = cfReq.cf;\n        if (cfReq.encodeResponseBody && cfReq.encodeResponseBody !== \"automatic\") {\n          init.encodeResponseBody = cfReq.encodeResponseBody;\n        }\n\n        // TODO: Support request.signal. Annoyingly, all `Request`s have a `signal` property even\n        //   if none was passed to the constructor, and there's no way to tell if it's a real\n        //   signal. So for now, since we don't support AbortSignal yet, all we can do is ignore\n        //   it; we can't throw an error if it's present.\n\n        return [\"request\", req.url, init];\n      }\n\n      case \"response\": {\n        let resp = <Response>value;\n        let cfResp = resp as any;\n\n        // `webSocket` is a Cloudflare Workers extension indicating that the response completed\n        // an HTTP/WebSocket upgrade. The socket can't be serialized as a value, so it is\n        // represented as a pair of streams; see websocket-streams.ts. (Bare WebSockets, outside\n        // of an upgrade Response, are intentionally not serializable.)\n        let webSocket = cfResp.webSocket;\n        if (webSocket && resp.body) {\n          throw new TypeError(\"A WebSocket upgrade Response can't have a body.\");\n        }\n\n        let body = this.devaluateImpl(resp.body, resp, depth + 1);\n        let init: Record<string, unknown> = {};\n\n        if (!webSocket) {\n          // An upgrade implies status 101, so we don't serialize status at all in that case.\n          // (We couldn't faithfully send 101 anyway: standard `Response` constructors refuse to\n          // produce 1xx statuses, so the receiver may have to substitute a default.)\n          if (resp.status !== 200) init.status = resp.status;\n          if (resp.statusText) init.statusText = resp.statusText;\n        }\n\n        let headers = [...<Iterable<[string, string]>><any>resp.headers];\n        if (headers.length > 0) {\n          // Note that we don't need to serialize this as [\"headers\", headers] because we are only\n          // trying to create a valid ResponseInit object.\n          init.headers = headers;\n        }\n\n        // These properties are specific to Cloudflare Workers. We already cast the response to\n        // `any` to silence type errors on other platforms.\n        if (cfResp.cf) init.cf = cfResp.cf;\n        if (cfResp.encodeBody && cfResp.encodeBody !== \"automatic\") {\n          init.encodeBody = cfResp.encodeBody;\n        }\n\n        if (webSocket) {\n          if (!this.source) {\n            throw new Error(\"Can't serialize a WebSocket upgrade in this context.\");\n          }\n\n          // The readable half is streamed through a pipe, exactly like a ReadableStream value:\n          // messages begin flowing to the receiver immediately, before it even knows they're\n          // coming, with the streams' usual flow control.\n          let readableId: ImportId;\n          let hook = this.source.getHookForWebSocket(webSocket, () => {\n            let streams = webSocketToStreams(webSocket);\n            let readableHook = streamImpl.createReadableStreamHook(streams.readable);\n            readableId = this.exporter.createPipe(streams.readable, readableHook);\n            return streamImpl.createWritableStreamHook(streams.writable);\n          });\n          init.webSocket = {\n            readable: [\"readable\", readableId!],\n            writable: this.devaluateHook(\"writable\", hook),\n          };\n        }\n\n        return [\"response\", body, init];\n      }\n\n      case \"blob\": {\n        // Blobs are streamed through a pipe. This allows very large blobs to be sent without\n        // causing excessively large individual messages nor blocking other messages in the\n        // meantime.\n        //\n        // Ideally, small Blobs would be inlined. But, there is no way to read a blob\n        // synchronously, and we MUST serialize the message synchronously. Hence, we have no choice\n        // but to use streaming even for small blobs.\n        let blob = value as Blob;\n        let readable = blob.stream();\n        let hook = streamImpl.createReadableStreamHook(readable);\n        let importId = this.exporter.createPipe(readable, hook);\n        return [\"blob\", blob.type, [\"readable\", importId]];\n      }\n\n      case \"error\": {\n        let e = <Error>value;\n\n        // TODO:\n        // - Determine type by checking prototype rather than `name`, which can be overridden?\n\n        let rewritten = this.exporter.onSendError(e);\n        if (rewritten) {\n          e = rewritten;\n        }\n\n        // Capture own enumerable properties plus the standard non-enumerable slots `cause`\n        // and (for AggregateError) `errors`. Each value is run through devaluateImpl so any\n        // supported type round-trips. If a property's value can't be serialized, drop the\n        // property: the error itself must always make it through. Use `onSendError` to scrub\n        // heavy or sensitive fields explicitly.\n        //\n        // On per-property failure we roll back any exports the partial walk produced by\n        // splicing them off `this.exports` and unexporting them.\n        //\n        // TODO: this can't roll back pipes created by `createPipe` (ReadableStream, Blob,\n        // Firefox request-body); the `[\"pipe\"]` frame and pump have already started, with\n        // no inverse on the `Exporter` interface, so they leak until session shutdown.\n        // Same caveat as the rollback in the static `devaluate` method above.\n        let anyE = <any>e;\n        let props: Record<string, unknown> | undefined;\n        let captureProp = (key: string, val: unknown) => {\n          let exportsBefore = this.exports?.length ?? 0;\n          try {\n            let encoded = this.devaluateImpl(val, e, depth + 1);\n            if (!props) props = {};\n            props[key] = encoded;\n          } catch (err) {\n            // Drop this property; the error itself still propagates. Roll back any exports\n            // the partial walk produced.\n            if (this.exports && this.exports.length > exportsBefore) {\n              let tail = this.exports.splice(exportsBefore);\n              try {\n                this.exporter.unexport(tail);\n              } catch (err2) {\n                // probably a side effect of the original error, ignore it\n              }\n            }\n          }\n        };\n        for (let key of Object.keys(e)) {\n          if (key === \"name\" || key === \"message\" || key === \"stack\") continue;\n          captureProp(key, anyE[key]);\n        }\n        // `cause` is normally non-enumerable, so Object.keys() misses it.\n        if (\"cause\" in e) {\n          captureProp(\"cause\", anyE.cause);\n        }\n        if (e instanceof AggregateError) {\n          captureProp(\"errors\", e.errors);\n        }\n\n        // Backwards-compat: only emit the new tail elements when there's something to add.\n        // Errors with no extras serialize to the legacy 3- or 4-element form, byte-identical\n        // to what previous versions produced.\n        let result: unknown[] = [\"error\", e.name, e.message];\n        if (props) {\n          // Normalize the stack slot to null so `props` is always at index 4.\n          result.push(rewritten && rewritten.stack ? rewritten.stack : null);\n          result.push(props);\n        } else if (rewritten && rewritten.stack) {\n          result.push(rewritten.stack);\n        }\n        return result;\n      }\n\n      case \"undefined\":\n        // At structuredClonable level, keep undefined as native value\n        if (this.encodingLevel === \"structuredClonable\") {\n          return undefined;\n        }\n        return [\"undefined\"];\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let {hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n        let importId = this.exporter.getImport(hook);\n        if (importId !== undefined) {\n          if (pathIfPromise) {\n            // It's a promise pointing back to the peer, so we are doing pipelining here.\n            if (pathIfPromise.length > 0) {\n              return [\"pipeline\", importId, pathIfPromise];\n            } else {\n              return [\"pipeline\", importId];\n            }\n          } else {\n            return [\"import\", importId];\n          }\n        }\n\n        if (pathIfPromise) {\n          hook = hook.get(pathIfPromise);\n        } else {\n          hook = hook.dup();\n        }\n\n        return this.devaluateHook(pathIfPromise ? \"promise\" : \"export\", hook);\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let hook = this.source.getHookForRpcTarget(<RpcTarget|Function>value, parent);\n        return this.devaluateHook(\"export\", hook);\n      }\n\n      case \"rpc-thenable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let hook = this.source.getHookForRpcTarget(<RpcTarget>value, parent);\n        return this.devaluateHook(\"promise\", hook);\n      }\n\n      case \"writable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize WritableStream in this context.\");\n        }\n\n        let hook = this.source.getHookForWritableStream(<WritableStream>value, parent);\n        return this.devaluateHook(\"writable\", hook);\n      }\n\n      case \"readable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize ReadableStream in this context.\");\n        }\n\n        let ws = <ReadableStream>value;\n        let hook = this.source.getHookForReadableStream(ws, parent);\n\n        // Create a pipe and start pumping the ReadableStream into it.\n        let importId = this.exporter.createPipe(ws, hook);\n\n        return [\"readable\", importId];\n      }\n\n      default:\n        kind satisfies never;\n        throw new Error(\"unreachable\");\n    }\n  }\n\n  private devaluateHook(type: \"export\" | \"promise\" | \"writable\", hook: StubHook): unknown {\n    if (!this.exports) this.exports = [];\n    let exportId = type === \"promise\" ? this.exporter.exportPromise(hook)\n                                      : this.exporter.exportStub(hook);\n    this.exports.push(exportId);\n    return [type, exportId];\n  }\n}\n\n/**\n * Serialize a value, using Cap'n Web's underlying serialization. This won't be able to serialize\n * RPC stubs, but it will support basic data types.\n */\nexport function serialize(value: unknown): string {\n  return JSON.stringify(Devaluator.devaluate(value));\n}\n\n// =======================================================================================\n\nexport interface Importer {\n  importStub(idx: ImportId): StubHook;\n  importPromise(idx: ImportId): StubHook;\n  getExport(idx: ExportId): StubHook | undefined;\n\n  // Retrieves the ReadableStream end of a pipe created by a [\"pipe\"] message.\n  // The exportId must refer to an export that was created as a pipe.\n  // This can only be called once per pipe.\n  getPipeReadable(exportId: ExportId): ReadableStream;\n\n  // The resource limits the Evaluator should enforce while deserializing. Surfaced through the\n  // Importer (rather than the Evaluator constructor) so that the per-session options reach the\n  // Evaluator without changing how Evaluators are constructed throughout the codebase.\n  getLimits(): RpcLimits;\n}\n\nclass NullImporter implements Importer {\n  importStub(idx: ImportId): never {\n    throw new Error(\"Cannot deserialize RPC stubs without an RPC session.\");\n  }\n  importPromise(idx: ImportId): never {\n    throw new Error(\"Cannot deserialize RPC stubs without an RPC session.\");\n  }\n  getExport(idx: ExportId): StubHook | undefined {\n    return undefined;\n  }\n  getPipeReadable(exportId: ExportId): never {\n    throw new Error(\"Cannot retrieve pipe readable without an RPC session.\");\n  }\n  getLimits(): RpcLimits {\n    // The standalone deserialize() entry point has no session and therefore no per-session\n    // overrides, but it must still be protected -- so it enforces the bare defaults.\n    return DEFAULT_LIMITS;\n  }\n}\n\nconst NULL_IMPORTER = new NullImporter();\n\n// Some runtimes (Firefox) don't support `request.body` as a stream, but we receive request bodies\n// as streams. We'll need to read the body into an ArrayBuffer and recreate the request. This is\n// asynchronous, so we'll have to swap in a promise here. This potentially breaks e-order but\n// that's something people will just have to live with when sending a Request to a Firefox\n// endpoint (probably rare).\nfunction fixBrokenRequestBody(request: Request, body: ReadableStream): RpcPromise {\n  // Reuse built-in code to read the stream into an array.\n  let promise = new Response(body).arrayBuffer().then(arrayBuffer => {\n    let bytes = new Uint8Array(arrayBuffer);\n    let result = new Request(request, {body: bytes});\n    return new PayloadStubHook(RpcPayload.fromAppReturn(result));\n  });\n  return new RpcPromise(new PromiseStubHook(promise), []);\n}\n\n// Unfortuntaely, even though Blobs can only be read asynchronously, there is no way to create\n// a blob backed by an asynchronous source; the bytes MUST all be provided upfront. This\n// effectively makes it impossible to manitain e-order when sending Blobs.\n//\n// As a compromise, we deliver a message as if it contained an RpcPromise that resolves to the\n// Blob. This has the effect that the RPC system will wait for the whole Blob to stream in before\n// delivering the message -- reusing the existing machinery for handling promises.\nfunction streamToBlobPromise(stream: ReadableStream, type: string): RpcPromise {\n  let promise = streamToBlob(stream, type).then(blob => {\n    return new PayloadStubHook(RpcPayload.fromAppReturn(blob));\n  });\n  return new RpcPromise(new PromiseStubHook(promise), []);\n}\n\n// Takes object trees parse from JSON and converts them into fully-hydrated JavaScript objects for\n// delivery to the app. This is used to implement deserialization, except that it doesn't actually\n// start from a raw string.\nexport class Evaluator {\n  private limits: RpcLimits;\n\n  constructor(private importer: Importer, private encodingLevel: EncodingLevel = \"string\",\n              private callHandler?: RpcCallHandler) {\n    this.limits = importer.getLimits();\n  }\n\n  private hooks: StubHook[] = [];\n  private promises: LocatedPromise[] = [];\n\n  public evaluate(value: unknown): RpcPayload {\n    return this.evaluateWithDepth(value, 0);\n  }\n\n  private evaluateWithDepth(value: unknown, depth: number): RpcPayload {\n    let payload = RpcPayload.forEvaluate(this.hooks, this.promises, this.callHandler);\n    try {\n      payload.value = this.evaluateImpl(value, payload, \"value\", depth);\n      return payload;\n    } catch (err) {\n      payload.dispose();\n      throw err;\n    }\n  }\n\n  // Evaluate the value without destroying it.\n  public evaluateCopy(value: unknown): RpcPayload {\n    return this.evaluate(structuredClone(value));\n  }\n\n  private evaluateImpl(\n      value: unknown, parent: object, property: string | number, depth: number): unknown {\n    let maxDepth = this.limits.maxDepth;\n    if (depth >= maxDepth) {\n      throw new TypeError(\n          `Deserialization exceeded maximum allowed message depth of ${maxDepth}.`);\n    }\n\n    // At structuredClonable level, some native types pass through devaluation unencoded: Date and\n    // BigInt (as well as undefined and non-finite numbers, which the generic paths below already\n    // handle). Note that bytes and errors are tuple-encoded at every level, so raw `Uint8Array`\n    // and `Error` values are intentionally *not* accepted here.\n    if (this.encodingLevel === \"structuredClonable\") {\n      if (value instanceof Date || typeof value === \"bigint\") {\n        return value;\n      }\n    }\n\n    if (value instanceof Array) {\n      if (value.length == 1 && value[0] instanceof Array) {\n        // Escaped array. Evaluate the contents.\n        let result = value[0];\n        for (let i = 0; i < result.length; i++) {\n          result[i] = this.evaluateImpl(result[i], result, i, depth + 1);\n        }\n        return result;\n      } else switch (value[0]) {\n        case \"bigint\":\n          if (typeof value[1] == \"string\") {\n            let digits = value[1];\n            let maxBigIntDigits = this.limits.maxBigIntDigits;\n            // Cap the length before the superlinear BigInt() parse (DoS guard).\n            if (digits.length > maxBigIntDigits) {\n              throw new TypeError(\n                  `Deserialized bigint exceeds maximum length of ${maxBigIntDigits} digits.`);\n            }\n            return BigInt(digits);\n          }\n          break;\n        case \"date\":\n          if (value[1] === null) {\n            return new Date(NaN);\n          }\n          if (typeof value[1] == \"number\") {\n            return new Date(value[1]);\n          }\n          break;\n        case \"bytes\": {\n          let bytes: Uint8Array;\n          // At jsonCompatibleWithBytes/structuredClonable level, bytes may already be raw.\n          if (value[1] instanceof Uint8Array) {\n            bytes = value[1];\n          } else if (typeof value[1] == \"string\") {\n            if (typeof Buffer !== \"undefined\") {\n              bytes = Buffer.from(value[1], \"base64\");\n            } else if (Uint8Array.fromBase64) {\n              bytes = Uint8Array.fromBase64(value[1]);\n            } else {\n              let bs = atob(value[1]);\n              let len = bs.length;\n              bytes = new Uint8Array(len);\n              for (let i = 0; i < len; i++) {\n                bytes[i] = bs.charCodeAt(i);\n              }\n            }\n          } else {\n            break;\n          }\n\n          if (value.length === 2) {\n            return bytes;\n          }\n          if (typeof value[2] !== \"string\") {\n            throw new TypeError(`Unknown bytes type marker type: ${typeof value[2]}`);\n          }\n\n          if (!isValidByteContainerName(value[2])) {\n            let marker = value[2].slice(0, 64);\n            throw new TypeError(`Unknown bytes type marker: ${marker}`);\n          }\n\n          let marker = value[2];\n          let elementSize = TYPED_ARRAY_ELEMENT_SIZE[marker];\n          if (elementSize !== undefined && bytes.byteLength % elementSize !== 0) {\n            throw new TypeError(\n                `Invalid byte length ${bytes.byteLength} for ${marker}; ` +\n                `expected a multiple of ${elementSize}`);\n          }\n\n          // Copy exactly the decoded range rather than exposing or aliasing a pooled Buffer.\n          let buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);\n          if (!NATIVE_LITTLE_ENDIAN && elementSize !== undefined) {\n            swapByteOrder(new Uint8Array(buffer), elementSize);\n          }\n          switch (marker) {\n            case \"ArrayBuffer\": return buffer;\n            case \"DataView\": return new DataView(buffer);\n            case \"Int8Array\": return new Int8Array(buffer);\n            case \"Uint8Array\": return new Uint8Array(buffer);\n            case \"Uint8ClampedArray\": return new Uint8ClampedArray(buffer);\n            case \"Int16Array\": return new Int16Array(buffer);\n            case \"Uint16Array\": return new Uint16Array(buffer);\n            case \"Int32Array\": return new Int32Array(buffer);\n            case \"Uint32Array\": return new Uint32Array(buffer);\n            case \"BigInt64Array\": return new BigInt64Array(buffer);\n            case \"BigUint64Array\": return new BigUint64Array(buffer);\n            case \"Float32Array\": return new Float32Array(buffer);\n            case \"Float64Array\": return new Float64Array(buffer);\n            default: marker satisfies never;\n          }\n        }\n        case \"error\":\n          if (value.length >= 3 && typeof value[1] === \"string\" && typeof value[2] === \"string\") {\n            let cls = ERROR_TYPES[value[1]] || Error;\n            // AggregateError's constructor takes (errors, message); we pass an empty array\n            // and patch `errors` from the props bag below.\n            let result = cls === AggregateError ? new cls([], value[2]) : new cls(value[2]);\n            if (typeof value[3] === \"string\") {\n              result.stack = value[3];\n            }\n            // Optional 5th element: own properties bag. Unknown keys are assigned as own\n            // enumerable properties so the receiver sees what the sender attached.\n            if (value.length >= 5) {\n              let props = value[4];\n              if (!props || typeof props !== \"object\" || Array.isArray(props)) {\n                break;  // malformed; fall through to the \"unknown special value\" throw\n              }\n              let anyResult = <any>result;\n              let propsObj = <Record<string, unknown>>props;\n              for (let key of Object.keys(propsObj)) {\n                if (key === \"name\" || key === \"message\" || key === \"stack\") continue;\n                if (key in Object.prototype || key === \"toJSON\") {\n                  // Consistent with the plain-object deserializer below: don't allow error\n                  // properties to override Object.prototype members (e.g. __proto__, toString,\n                  // valueOf) or toJSON. Still evaluate the inner value so any stubs are released.\n                  this.evaluateImpl(propsObj[key], result, key, depth + 1);\n                  continue;\n                }\n                anyResult[key] = this.evaluateImpl(propsObj[key], result, key, depth + 1);\n              }\n            }\n            return result;\n          }\n          break;\n        case \"undefined\":\n          if (value.length === 1) {\n            return undefined;\n          }\n          break;\n        case \"inf\":\n          return Infinity;\n        case \"-inf\":\n          return -Infinity;\n        case \"nan\":\n          return NaN;\n\n        case \"headers\":\n          // We only need to validate that the parameter is an array, so as not to invoke an\n          // unexpected variant of the Headers constructor. So long as it is an array then we can\n          // rely on the constructor to perform type checking.\n          if (value.length === 2 && value[1] instanceof Array) {\n            return new Headers(value[1] as [string, string][]);\n          }\n          break;\n\n        case \"request\": {\n          if (value.length !== 3 || typeof value[1] !== \"string\") break;\n          let url = value[1] as string;\n          let init = value[2];\n          if (typeof init !== \"object\" || init === null) break;\n\n          // Evaluate specific properties which are expected to contain non-trivial types.\n          if (init.body) {\n            init.body = this.evaluateImpl(init.body, init, \"body\", depth + 1);\n            if (init.body === null ||\n                typeof init.body === \"string\" ||\n                init.body instanceof Uint8Array ||\n                init.body instanceof ReadableStream) {\n              // Acceptable types.\n            } else {\n              throw new TypeError(\"Request body must be of type ReadableStream.\");\n            }\n          }\n          if (init.signal) {\n            init.signal = this.evaluateImpl(init.signal, init, \"signal\", depth + 1);\n            if (!(init.signal instanceof AbortSignal)) {\n              throw new TypeError(\"Request siganl must be of type AbortSignal.\");\n            }\n          }\n\n          // Type-check `headers` is an array because the constructor allows multiple\n          // representations and we don't want to allow the others.\n          if (init.headers && !(init.headers instanceof Array)) {\n            throw new TypeError(\"Request headers must be serialized as an array of pairs.\");\n          }\n\n          // We assume the `Request` constructor can type-check the remaining properties.\n          let result = new Request(url, init as RequestInit);\n\n          if (init.body instanceof ReadableStream && result.body === undefined) {\n            // Oh no! We must be on Firefox where request bodies are not supported, but we had a\n            // body.\n            let promise = fixBrokenRequestBody(result, init.body);\n            this.promises.push({promise, parent, property});\n            return promise;\n          } else {\n            return result;\n          }\n        }\n\n        case \"response\": {\n          if (value.length !== 3) break;\n\n          let body = this.evaluateImpl(value[1], parent, property, depth + 1);\n          if (body === null ||\n              typeof body === \"string\" ||\n              body instanceof Uint8Array ||\n              body instanceof ReadableStream) {\n            // Acceptable types.\n          } else {\n            throw new TypeError(\"Response body must be of type ReadableStream.\");\n          }\n\n          let init = value[2];\n          if (typeof init !== \"object\" || init === null) break;\n\n          // Type-check `headers` is an array because the constructor allows multiple\n          // representations and we don't want to allow the others.\n          if (init.headers && !(init.headers instanceof Array)) {\n            throw new TypeError(\"Request headers must be serialized as an array of pairs.\");\n          }\n\n          // Evaluate specific properties which are expected to contain non-trivial types.\n          if (init.webSocket) {\n            // `response.webSocket` is a Cloudflare Workers extension, indicating the response\n            // completed an HTTP/WebSocket upgrade. It is serialized as a pair of streams; see\n            // websocket-streams.ts.\n            if (body !== null) {\n              throw new TypeError(\"A WebSocket upgrade Response can't have a body.\");\n            }\n            let ws = init.webSocket;\n            if (typeof ws !== \"object\" || ws === null || ws instanceof Array) {\n              throw new TypeError(\"Response webSocket must be serialized as a pair of streams.\");\n            }\n\n            let readable = this.evaluateImpl(ws.readable, ws, \"readable\", depth + 1);\n            if (!(readable instanceof ReadableStream)) {\n              throw new TypeError(\"Response webSocket readable must be a ReadableStream.\");\n            }\n\n            // We import the writable's hook directly rather than wrapping it in a proxy\n            // WritableStream, because the receiving socket needs to manage the hook's lifetime\n            // itself (it takes its own reference when the app claims the socket; see\n            // TunneledWebSocket).\n            let writable = ws.writable;\n            if (!(writable instanceof Array) || writable.length !== 2 ||\n                writable[0] !== \"writable\" || typeof writable[1] !== \"number\") {\n              throw new TypeError(\"Response webSocket writable must be a WritableStream.\");\n            }\n            let writableHook = this.importer.importStub(writable[1]);\n            this.hooks.push(writableHook);\n\n            delete init.webSocket;\n            return makeUpgradeResponse(readable, writableHook, init as ResponseInit);\n          }\n\n          return new Response(body as BodyInit | null, init as ResponseInit);\n        }\n\n        case \"blob\": {\n          // Wire format is strictly [\"blob\", type, [\"readable\", id]] — the encoder always streams\n          // bytes through a pipe, so the content expression must evaluate to a ReadableStream.\n          if (value.length !== 3 || typeof value[1] !== \"string\") break;\n          let contentType = value[1] as string;\n          let content = this.evaluateImpl(value[2], parent, property, depth + 1);\n          if (!(content instanceof ReadableStream)) {\n            throw new TypeError(\"Blob content must be serialized as a ReadableStream.\");\n          }\n          // Reuse the RpcPromise infrastructure (same pattern as fixBrokenRequestBody): the\n          // payload-delivery machinery resolves the promise and substitutes the real Blob before\n          // user code sees the value.\n          let promise = streamToBlobPromise(content, contentType);\n          this.promises.push({promise, parent, property});\n          return promise;\n        }\n\n        case \"import\":\n        case \"pipeline\": {\n          // It's an \"import\" from the perspective of the sender, so it's an export from our\n          // side. In other words, the sender is passing our own object back to us.\n\n          if (value.length < 2 || value.length > 4) {\n            break;   // report error below\n          }\n\n          // First parameter is import ID (from the sender's perspective, so export ID from\n          // ours).\n          if (typeof value[1] != \"number\") {\n            break;   // report error below\n          }\n\n          let hook = this.importer.getExport(value[1]);\n          if (!hook) {\n            throw new Error(`no such entry on exports table: ${value[1]}`);\n          }\n\n          let isPromise = value[0] == \"pipeline\";\n\n          let addStub = (hook: StubHook) => {\n            if (isPromise) {\n              let promise = new RpcPromise(hook, []);\n              this.promises.push({promise, parent, property});\n              return promise;\n            } else {\n              this.hooks.push(hook);\n              return new RpcPromise(hook, []);\n            }\n          };\n\n          if (value.length == 2) {\n            // Just referencing the export itself.\n            if (isPromise) {\n              // We need to use hook.get([]) to make sure we get a promise hook.\n              return addStub(hook.get([]));\n            } else {\n              // dup() returns a stub hook.\n              return addStub(hook.dup());\n            }\n          }\n\n          // Second parameter, if given, is a property path.\n          let path = value[2];\n          if (!(path instanceof Array)) {\n            break;  // report error below\n          }\n          if (!path.every(\n              part => { return typeof part == \"string\" || typeof part == \"number\"; })) {\n            break;  // report error below\n          }\n\n          if (value.length == 3) {\n            // Just referencing the path, not a call.\n            return addStub(hook.get(path));\n          }\n\n          // Third parameter, if given, is call arguments. The sender has identified a function\n          // and wants us to call it.\n          //\n          // Usually this is used with \"pipeline\", in which case we evaluate to an\n          // RpcPromise. However, this can be used with \"import\", in which case the caller is\n          // asking that the result be coerced to RpcStub. This distinction matters if the\n          // result of this evaluation is to be passed as arguments to another call -- promises\n          // must be resolved in advance, but stubs can be passed immediately.\n          let args = value[3];\n          if (!(args instanceof Array)) {\n            break;  // report error below\n          }\n\n          // We need a new evaluator for the args, to build a separate payload.\n          let subEval = new Evaluator(this.importer, this.encodingLevel, this.callHandler);\n          args = subEval.evaluateWithDepth([args], depth);\n\n          return addStub(hook.call(path, args));\n        }\n\n        case \"remap\": {\n          if (value.length !== 5 ||\n              typeof value[1] !== \"number\" ||\n              !(value[2] instanceof Array) ||\n              !(value[3] instanceof Array) ||\n              !(value[4] instanceof Array)) {\n            break;   // report error below\n          }\n\n          let hook = this.importer.getExport(value[1]);\n          if (!hook) {\n            throw new Error(`no such entry on exports table: ${value[1]}`);\n          }\n\n          let path = value[2];\n          if (!path.every(\n              part => { return typeof part == \"string\" || typeof part == \"number\"; })) {\n            break;  // report error below\n          }\n\n          let captures: StubHook[] = value[3].map(cap => {\n            if (!(cap instanceof Array) ||\n                cap.length !== 2 ||\n                (cap[0] !== \"import\" && cap[0] !== \"export\") ||\n                typeof cap[1] !== \"number\") {\n              throw new TypeError(`unknown map capture: ${JSON.stringify(cap)}`);\n            }\n\n            if (cap[0] === \"export\") {\n              return this.importer.importStub(cap[1]);\n            } else {\n              let exp = this.importer.getExport(cap[1]);\n              if (!exp) {\n                throw new Error(`no such entry on exports table: ${cap[1]}`);\n              }\n              return exp.dup();\n            }\n          });\n\n          let instructions = value[4];\n\n          let resultHook = hook.map(path, captures, instructions);\n\n          let promise = new RpcPromise(resultHook, []);\n          this.promises.push({promise, parent, property});\n          return promise;\n        }\n\n        case \"export\":\n        case \"promise\":\n          // It's an \"export\" from the perspective of the sender, i.e. they sent us a new object\n          // which we want to import.\n          //\n          // \"promise\" is same as \"export\" but should not be delivered to the application. If any\n          // promises appear in a value, they must be resolved and substituted with their results\n          // before delivery. Note that if the value being evaluated appeared in call params, or\n          // appeared in a resolve message for a promise that is being pulled, then the new promise\n          // is automatically also being pulled, otherwise it is not.\n          if (typeof value[1] == \"number\") {\n            if (value[0] == \"promise\") {\n              let hook = this.importer.importPromise(value[1]);\n              let promise = new RpcPromise(hook, []);\n              this.promises.push({parent, property, promise});\n              return promise;\n            } else {\n              let hook = this.importer.importStub(value[1]);\n              this.hooks.push(hook);\n              return new RpcStub(hook);\n            }\n          }\n          break;\n\n        case \"writable\":\n          // It's a WritableStream export from the sender. We import it and create a proxy\n          // WritableStream that forwards writes to the remote end.\n          if (typeof value[1] == \"number\") {\n            let hook = this.importer.importStub(value[1]);\n            let stream = streamImpl.createWritableStreamFromHook(hook);\n            // Track the stream for disposal.\n            this.hooks.push(hook);\n            return stream;\n          }\n          break;\n\n        case \"readable\":\n          // References the readable end of a pipe. The import ID (from the sender's perspective)\n          // is our export ID.\n          if (typeof value[1] == \"number\") {\n            let stream = this.importer.getPipeReadable(value[1]);\n            // Track the stream for disposal so that if the payload is disposed before the\n            // app reads the stream, the ReadableStream is properly canceled.\n            let hook = streamImpl.createReadableStreamHook(stream);\n            this.hooks.push(hook);\n            return stream;\n          }\n          break;\n      }\n      throw new TypeError(`unknown special value: ${JSON.stringify(value)}`);\n    } else if (value instanceof Object) {\n      let result = <Record<string, unknown>>value;\n      for (let key in result) {\n        if (key in Object.prototype || key === \"toJSON\") {\n          // Out of an abundance of caution, we will ignore properties that override properties\n          // of Object.prototype. It's especially important that we don't allow `__proto__` as it\n          // may lead to prototype pollution. We also would rather not allow, e.g., `toString()`,\n          // as overriding this could lead to various mischief.\n          //\n          // We also block `toJSON()` for similar reasons -- even though Object.prototype doesn't\n          // actually define it, `JSON.stringify()` treats it specially and we don't want someone\n          // snooping on JSON calls.\n          //\n          // We do still evaluate the inner value so that we can properly release any stubs.\n          this.evaluateImpl(result[key], result, key, depth + 1);\n          delete result[key];\n        } else {\n          result[key] = this.evaluateImpl(result[key], result, key, depth + 1);\n        }\n      }\n      return result;\n    } else {\n      // Other JSON types just pass through.\n      return value;\n    }\n  }\n}\n\n/**\n * Deserialize a value serialized using serialize().\n */\nexport function deserialize(value: string): unknown {\n  let payload = new Evaluator(NULL_IMPORTER).evaluate(JSON.parse(value));\n  payload.dispose();  // should be no-op but just in case\n  return payload.value;\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, RpcPayload, RpcStub, PropertyPath, PayloadStubHook, ErrorStubHook, RpcTarget, unwrapStubAndPath, streamImpl, type RpcCallHandler } from \"./core.js\";\nimport { Devaluator, Evaluator, ExportId, ImportId, Exporter, Importer, serialize, EncodingLevel, RpcLimits, DEFAULT_LIMITS } from \"./serialize.js\";\n\n/**\n * Interface for a string-based RPC transport. This is the default transport type — no\n * `encodingLevel` field is needed. Messages are JSON strings. Implement this interface if the\n * built-in transports (e.g. for HTTP batch and WebSocket) don't meet your needs.\n */\nexport interface RpcTransport {\n  /**\n   * The encoding level this transport works with. For this interface it is always \"string\";\n   * it may be omitted. (See `RpcTransportWithCustomEncoding` for the other levels.)\n   */\n  readonly encodingLevel?: \"string\";\n\n  /**\n   * Sends a message to the other end. May optionally return a promise; if the promise rejects,\n   * the session is aborted.\n   */\n  send(message: string): void | Promise<void>;\n\n  /**\n   * Receives a message sent by the other end.\n   *\n   * If and when the transport becomes disconnected, this will reject. The thrown error will be\n   * propagated to all outstanding calls and future calls on any stubs associated with the session.\n   * If there are no outstanding calls (and none are made in the future), then the error does not\n   * propagate anywhere -- this is considered a \"clean\" shutdown.\n   */\n  receive(): Promise<string>;\n\n  /**\n   * Indicates that the RPC system has suffered an error that prevents the session from continuing.\n   * The transport should ideally try to send any queued messages if it can, and then close the\n   * connection. (It's not strictly necessary to deliver queued messages, but the last message sent\n   * before abort() is called is often an \"abort\" message, which communicates the error to the\n   * peer, so if that is dropped, the peer may have less information about what happened.)\n   */\n  abort?(reason: any): void;\n}\n\n/**\n * Interface for a transport that receives partially encoded JS values instead of JSON strings.\n * The selected `encodingLevel` describes what the transport can assume about message values.\n */\nexport interface RpcTransportWithCustomEncoding {\n  /**\n   * The encoding level this transport works with.\n   *\n   * - \"jsonCompatible\": JSON-compatible JS value tree; transport handles final serialization.\n   * - \"jsonCompatibleWithBytes\": Like \"jsonCompatible\" but Uint8Array values are left raw.\n   * - \"structuredClonable\": Structured-clonable native values pass through where possible.\n   */\n  readonly encodingLevel: \"jsonCompatible\" | \"jsonCompatibleWithBytes\" | \"structuredClonable\";\n\n  /**\n   * Encodes and sends a message to the other end. Returns the encoded byte size if known.\n   * If the size is unavailable, return void; Cap'n Web will estimate stream message sizes for\n   * flow control. Send errors should be propagated via `receive()` rejecting.\n   */\n  send(message: unknown): number | void;\n\n  /**\n   * Receives and decodes a message sent by the other end.\n   *\n   * If and when the transport becomes disconnected, this will reject. The thrown error will be\n   * propagated to all outstanding calls and future calls on any stubs associated with the session.\n   * If there are no outstanding calls (and none are made in the future), then the error does not\n   * propagate anywhere -- this is considered a \"clean\" shutdown.\n   */\n  receive(): Promise<unknown>;\n\n  /**\n   * Indicates that the RPC system has suffered an error that prevents the session from continuing.\n   * The transport should ideally try to send any queued messages if it can, and then close the\n   * connection. (It's not strictly necessary to deliver queued messages, but the last message sent\n   * before abort() is called is often an \"abort\" message, which communicates the error to the\n   * peer, so if that is dropped, the peer may have less information about what happened.)\n   */\n  abort?(reason: any): void;\n}\n\n/** Any supported transport type. */\nexport type AnyRpcTransport = RpcTransport | RpcTransportWithCustomEncoding;\n\nconst ESTIMATED_OBJECT_OVERHEAD = 16;\nconst ESTIMATED_ENTRY_OVERHEAD = 8;\nconst ESTIMATED_BINARY_OVERHEAD = 16;\nconst MAX_ESTIMATE_DEPTH = 64;\n\nfunction estimateStringSize(value: string): number {\n  // Bias high. UTF-8 uses up to 3 bytes for BMP code points, and surrogate pairs are 4 bytes for\n  // 2 UTF-16 code units.\n  return 2 + value.length * 3;\n}\n\nfunction estimateEncodedSize(value: unknown, seen?: WeakSet<object>, depth: number = 0): number {\n  if (depth >= MAX_ESTIMATE_DEPTH) return ESTIMATED_ENTRY_OVERHEAD;\n\n  switch (typeof value) {\n    case \"string\":\n      return estimateStringSize(value);\n    case \"number\":\n      return 16;\n    case \"bigint\":\n      return 16;\n    case \"boolean\":\n      return 8;\n    case \"undefined\":\n      return 16;\n    case \"object\": {\n      if (value === null) return 8;\n      if (ArrayBuffer.isView(value)) return ESTIMATED_BINARY_OVERHEAD + value.byteLength;\n      if (value instanceof ArrayBuffer) return ESTIMATED_BINARY_OVERHEAD + value.byteLength;\n      if (typeof Blob !== \"undefined\" && value instanceof Blob) {\n        return ESTIMATED_BINARY_OVERHEAD + value.size;\n      }\n      if (value instanceof Date) return 16;\n\n      // `seen` is only ever added to, never removed, so it dedupes by object identity across the\n      // entire traversal rather than just along the current path. This is intentional: it keeps the\n      // estimate safe against cyclic graphs (which would otherwise recurse forever). The trade-off\n      // is that a value reachable via two different paths (shared but acyclic) is counted in full\n      // the first time and only as ESTIMATED_ENTRY_OVERHEAD afterward, so shared substructure\n      // under-counts slightly. That's acceptable here — this is a flow-control estimate, not an\n      // exact serialized size, and it otherwise biases high.\n      seen ??= new WeakSet();\n      if (seen.has(value)) return ESTIMATED_ENTRY_OVERHEAD;\n      seen.add(value);\n\n      if (value instanceof Array) {\n        let size = ESTIMATED_OBJECT_OVERHEAD;\n        for (let item of value) {\n          size += ESTIMATED_ENTRY_OVERHEAD + estimateEncodedSize(item, seen, depth + 1);\n        }\n        return size;\n      }\n\n      if (value instanceof Error) {\n        let size = ESTIMATED_OBJECT_OVERHEAD + estimateStringSize(value.name) +\n            estimateStringSize(value.message) + estimateStringSize(value.stack ?? \"\");\n        for (let key of Object.keys(value)) {\n          size += ESTIMATED_ENTRY_OVERHEAD + estimateStringSize(key) +\n              estimateEncodedSize((value as any)[key], seen, depth + 1);\n        }\n        return size;\n      }\n\n      let size = ESTIMATED_OBJECT_OVERHEAD;\n      for (let key of Object.keys(value)) {\n        size += ESTIMATED_ENTRY_OVERHEAD + estimateStringSize(key) +\n            estimateEncodedSize((value as Record<string, unknown>)[key], seen, depth + 1);\n      }\n      return size;\n    }\n    default:\n      return 16;\n  }\n}\n\n// Entry on the exports table.\ntype ExportTableEntry = {\n  hook: StubHook,\n  refcount: number,\n  pull?: Promise<void>,\n\n  // If true, the export should be automatically released (with refcount 1) after its \"resolve\"\n  // or \"reject\" message is sent. This is set for exports created by [\"stream\"] messages.\n  autoRelease?: boolean,\n\n  // If this export was created by a [\"pipe\"] message, this holds the ReadableStream end of the\n  // pipe. It is consumed (and set to undefined) when a [\"readable\", importId] expression\n  // references this export.\n  pipeReadable?: ReadableStream\n};\n\n// Entry on the imports table.\nclass ImportTableEntry {\n  constructor(public session: RpcSessionImpl, public importId: number, pulling: boolean) {\n    if (pulling) {\n      this.activePull = Promise.withResolvers<void>();\n    }\n  }\n\n  public localRefcount: number = 0;\n  public remoteRefcount: number = 1;\n\n  private activePull?: PromiseWithResolvers<void>;\n  public resolution?: StubHook;\n\n  // List of integer indexes into session.onBrokenCallbacks which are callbacks registered on\n  // this import. Initialized on first use (so `undefined` is the same as an empty list).\n  private onBrokenRegistrations?: number[];\n\n  resolve(resolution: StubHook) {\n    // TODO: Need embargo handling here? PayloadStubHook needs to be wrapped in a\n    // PromiseStubHook awaiting the embargo I suppose. Previous notes on embargoes:\n    // - Resolve message specifies last call that was received before the resolve. The introducer is\n    //   responsible for any embargoes up to that point.\n    // - Any further calls forwarded by the introducer after that point MUST immediately resolve to\n    //   a forwarded call. The caller is responsible for ensuring the last of these is handed off\n    //   before direct calls can be delivered.\n\n    if (this.localRefcount == 0) {\n      // Already disposed (canceled), so ignore the resolution and don't send a redundant release.\n      resolution.dispose();\n      return;\n    }\n\n    this.resolution = resolution;\n    this.sendRelease();\n\n    if (this.onBrokenRegistrations) {\n      // Delete all our callback registrations from this session and re-register them on the\n      // target stub.\n      for (let i of this.onBrokenRegistrations) {\n        let callback = this.session.onBrokenCallbacks[i];\n        let endIndex = this.session.onBrokenCallbacks.length;\n        resolution.onBroken(callback);\n        if (this.session.onBrokenCallbacks[endIndex] === callback) {\n          // Oh, calling onBroken() just registered the callback back on this connection again.\n          // But when the connection dies, we want all the callbacks to be called in the order in\n          // which they were registered. So we don't want this one pushed to the back of the line\n          // here. So, let's remove the newly-added registration and keep the original.\n          // TODO: This is quite hacky, think about whether this is really the right answer.\n          delete this.session.onBrokenCallbacks[endIndex];\n        } else {\n          // The callback is now registered elsewhere, so delete it from our session.\n          delete this.session.onBrokenCallbacks[i];\n        }\n      }\n      this.onBrokenRegistrations = undefined;\n    }\n\n    if (this.activePull) {\n      this.activePull.resolve();\n      this.activePull = undefined;\n    }\n  }\n\n  async awaitResolution(): Promise<RpcPayload> {\n    if (!this.activePull) {\n      this.session.sendPull(this.importId);\n      this.activePull = Promise.withResolvers<void>();\n    }\n    await this.activePull.promise;\n    return this.resolution!.pull();\n  }\n\n  dispose() {\n    if (this.resolution) {\n      this.resolution.dispose();\n    } else {\n      this.abort(new Error(\"RPC was canceled because the RpcPromise was disposed.\"));\n      this.sendRelease();\n    }\n  }\n\n  abort(error: any) {\n    if (!this.resolution) {\n      this.resolution = new ErrorStubHook(error);\n\n      if (this.activePull) {\n        this.activePull.reject(error);\n        this.activePull = undefined;\n      }\n\n      // The RpcSession itself will have called all our callbacks so we don't need to track the\n      // registrations anymore.\n      this.onBrokenRegistrations = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.resolution) {\n      this.resolution.onBroken(callback);\n    } else {\n      let index = this.session.onBrokenCallbacks.length;\n      this.session.onBrokenCallbacks.push(callback);\n\n      if (!this.onBrokenRegistrations) this.onBrokenRegistrations = [];\n      this.onBrokenRegistrations.push(index);\n    }\n  }\n\n  private sendRelease() {\n    if (this.remoteRefcount > 0) {\n      this.session.sendRelease(this.importId, this.remoteRefcount);\n      this.remoteRefcount = 0;\n    }\n  }\n};\n\nclass RpcImportHook extends StubHook {\n  public entry?: ImportTableEntry;  // undefined when we're disposed\n\n  // `pulling` is true if we already expect that this import is going to be resolved later, and\n  // null if this import is not allowed to be pulled (i.e. it's a stub not a promise).\n  constructor(public isPromise: boolean, entry: ImportTableEntry) {\n    super();\n    ++entry.localRefcount;\n    this.entry = entry;\n  }\n\n  collectPath(path: PropertyPath): RpcImportHook {\n    return this;\n  }\n\n  getEntry(): ImportTableEntry {\n    if (this.entry) {\n      return this.entry;\n    } else {\n      // Shouldn't get here in practice since the holding stub should have replaced the hook when\n      // disposed.\n      throw new Error(\"This RpcImportHook was already disposed.\");\n    }\n  }\n\n  // -------------------------------------------------------------------------------------\n  // implements StubHook\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.call(path, args);\n    } else {\n      return entry.session.sendCall(entry.importId, path, args);\n    }\n  }\n\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.stream(path, args);\n    } else {\n      return entry.session.sendStream(entry.importId, path, args);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    let entry: ImportTableEntry;\n    try {\n      entry = this.getEntry();\n    } catch (err) {\n      for (let cap of captures) {\n        cap.dispose();\n      }\n      throw err;\n    }\n\n    if (entry.resolution) {\n      return entry.resolution.map(path, captures, instructions);\n    } else {\n      return entry.session.sendMap(entry.importId, path, captures, instructions);\n    }\n  }\n\n  get(path: PropertyPath): StubHook {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.get(path);\n    } else {\n      return entry.session.sendCall(entry.importId, path);\n    }\n  }\n\n  dup(): RpcImportHook {\n    return new RpcImportHook(false, this.getEntry());\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    let entry = this.getEntry();\n\n    if (!this.isPromise) {\n      throw new Error(\"Can't pull this hook because it's not a promise hook.\");\n    }\n\n    if (entry.resolution) {\n      return entry.resolution.pull();\n    }\n\n    return entry.awaitResolution();\n  }\n\n  ignoreUnhandledRejections(): void {\n    // We don't actually have to do anything here because this method only has to ignore rejections\n    // if pull() is *not* called, and if pull() is not called then we won't generate any rejections\n    // anyway.\n  }\n\n  dispose(): void {\n    let entry = this.entry;\n    this.entry = undefined;\n    if (entry) {\n      if (--entry.localRefcount === 0) {\n        entry.dispose();\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.entry) {\n      this.entry.onBroken(callback);\n    }\n  }\n}\n\nclass RpcMainHook extends RpcImportHook {\n  private session?: RpcSessionImpl;\n\n  constructor(entry: ImportTableEntry) {\n    super(false, entry);\n    this.session = entry.session;\n  }\n\n  dispose(): void {\n    if (this.session) {\n      let session = this.session;\n      this.session = undefined;\n      session.shutdown();\n    }\n  }\n}\n\n/**\n * Options to customize behavior of an RPC session. All functions which start a session should\n * optionally accept this.\n */\nexport type RpcSessionOptions = {\n  /**\n   * If provided, this function will be called whenever an `Error` object is serialized (for any\n   * reason, not just because it was thrown). This can be used to log errors, and also to redact\n   * them.\n   *\n   * If `onSendError` returns an Error object, than object will be substituted in place of the\n   * original. If it has a stack property, the stack will be sent to the client.\n   *\n   * If `onSendError` doesn't return anything (or is not provided at all), the default behavior is\n   * to serialize the error with the stack omitted.\n   */\n  onSendError?: (error: Error) => Error | void;\n\n  /**\n   * Overrides for the resource limits enforced while deserializing messages from the peer. Any\n   * field left unset falls back to `DEFAULT_LIMITS`. These guard against resource-exhaustion\n   * attacks from untrusted peers; see `RpcLimits` for the meaning and defaults of each field.\n   *\n   * Limits are a purely local, receiver-side decision -- the protocol has no negotiation step, so\n   * the peer never learns these values. A message that exceeds a limit is rejected, aborting the\n   * session.\n   */\n  limits?: Partial<RpcLimits>;\n\n  /**\n   * Wrap every local application function invoked by the peer. The handler must invoke\n   * `invoke()` synchronously to preserve e-order, and should return its promise so the wrapper\n   * spans the full asynchronous call. The hook is propagated through promise pipelining.\n   */\n  onCall?: RpcCallHandler;\n};\n\nclass RpcSessionImpl implements Importer, Exporter {\n  private exports: Array<ExportTableEntry> = [];\n  private reverseExports: Map<StubHook, ExportId> = new Map();\n  private imports: Array<ImportTableEntry> = [];\n  private abortReason?: any;\n  private cancelReadLoop?: (error: any) => void;\n\n  // We assign positive numbers to imports we initiate, and negative numbers to exports we\n  // initiate. So the next import ID is just `imports.length`, but the next export ID needs\n  // to be tracked explicitly.\n  private nextExportId = -1;\n\n  // If set, call this when all incoming calls are complete.\n  private onBatchDone?: Omit<PromiseWithResolvers<void>, \"promise\">;\n\n  // How many promises is our peer expecting us to resolve?\n  private pullCount = 0;\n\n  // Sparse array of onBrokenCallback registrations. Items are strictly appended to the end but\n  // may be deleted from the middle (hence leaving the array sparse).\n  onBrokenCallbacks: ((error: any) => void)[] = [];\n\n  // Encoding level from the transport (defaults to \"string\")\n  private encodingLevel: EncodingLevel;\n\n  // Resource limits enforced on incoming messages, resolved once from the defaults plus any\n  // per-session overrides.\n  private limits: RpcLimits;\n\n  constructor(private transport: AnyRpcTransport, mainHook: StubHook,\n      private options: RpcSessionOptions) {\n    // `RpcTransport` has no `encodingLevel` field, so its presence is what marks a custom-encoding\n    // transport. Read it defensively: treat a present-but-`undefined` value (e.g. an uninitialized\n    // class field) as the default string level rather than mis-routing it down the custom-encoding\n    // path, and reject any other unrecognized value (e.g. a stale pre-rename level name) loudly\n    // instead of silently corrupting the wire.\n    let level: EncodingLevel = \"string\";\n    if ('encodingLevel' in transport) {\n      let raw = transport.encodingLevel as unknown;\n      if (raw !== undefined) {\n        if (raw !== \"string\" && raw !== \"jsonCompatible\" &&\n            raw !== \"jsonCompatibleWithBytes\" && raw !== \"structuredClonable\") {\n          throw new TypeError(`Unknown transport encodingLevel: ${String(raw)}`);\n        }\n        level = raw;\n      }\n    }\n    this.encodingLevel = level;\n\n    this.limits = { ...DEFAULT_LIMITS, ...options.limits };\n\n    // Export zero is automatically the bootstrap object.\n    this.exports.push({hook: mainHook, refcount: 1});\n\n    // Import zero is the other side's bootstrap object.\n    this.imports.push(new ImportTableEntry(this, 0, false));\n\n    this.readLoop().catch(err => this.abort(err));\n  }\n\n  // Should only be called once immediately after construction.\n  getMainImport(): RpcImportHook {\n    return new RpcMainHook(this.imports[0]);\n  }\n\n  shutdown(): void {\n    // TODO(someday): Should we add some sort of \"clean shutdown\" mechanism? This gets the job\n    //   done just fine for the moment.\n    this.abort(new Error(\"RPC session was shut down by disposing the main stub\"), false);\n  }\n\n  exportStub(hook: StubHook): ExportId {\n    if (this.abortReason) throw this.abortReason;\n\n    let existingExportId = this.reverseExports.get(hook);\n    if (existingExportId !== undefined) {\n      ++this.exports[existingExportId].refcount;\n      return existingExportId;\n    } else {\n      let exportId = this.nextExportId--;\n      this.exports[exportId] = { hook, refcount: 1 };\n      this.reverseExports.set(hook, exportId);\n      // TODO: Use onBroken().\n      return exportId;\n    }\n  }\n\n  exportPromise(hook: StubHook): ExportId {\n    if (this.abortReason) throw this.abortReason;\n\n    // Promises always use a new ID because otherwise the recipient could miss the resolution.\n    let exportId = this.nextExportId--;\n    this.exports[exportId] = { hook, refcount: 1 };\n    this.reverseExports.set(hook, exportId);\n\n    // Automatically start resolving any promises we send.\n    this.ensureResolvingExport(exportId);\n    return exportId;\n  }\n\n  unexport(ids: Array<ExportId>): void {\n    for (let id of ids) {\n      this.releaseExport(id, 1);\n    }\n  }\n\n  private releaseExport(exportId: ExportId, refcount: number) {\n    let entry = this.exports[exportId];\n    if (!entry) {\n      throw new Error(`no such export ID: ${exportId}`);\n    }\n    if (entry.refcount < refcount) {\n      throw new Error(`refcount would go negative: ${entry.refcount} < ${refcount}`);\n    }\n    entry.refcount -= refcount;\n    if (entry.refcount === 0) {\n      delete this.exports[exportId];\n      this.reverseExports.delete(entry.hook);\n      entry.hook.dispose();\n    }\n  }\n\n  onSendError(error: Error): Error | void {\n    if (this.options.onSendError) {\n      return this.options.onSendError(error);\n    }\n  }\n\n  private ensureResolvingExport(exportId: ExportId) {\n    let exp = this.exports[exportId];\n    if (!exp) {\n      throw new Error(`no such export ID: ${exportId}`);\n    }\n    if (!exp.pull) {\n      let resolve = async () => {\n        let hook = exp.hook;\n        for (;;) {\n          let payload = await hook.pull();\n          if (payload.value instanceof RpcStub) {\n            let {hook: inner, pathIfPromise} = unwrapStubAndPath(payload.value);\n            if (pathIfPromise && pathIfPromise.length == 0) {\n              if (this.getImport(hook) === undefined) {\n                // Optimization: The resolution is just another promise, and it is not a promise\n                // pointing back to the peer. So if we send a resolve message, it's just going to\n                // resolve to another new promise export, which is just going to have to wait for\n                // another resolve message later. This intermediate resolve message gives the peer\n                // no useful information, so let's skip it and just wait for the chained\n                // resolution.\n                hook = inner;\n                continue;\n              }\n            }\n          }\n\n          return payload;\n        }\n      };\n\n      let autoRelease = exp.autoRelease;\n\n      ++this.pullCount;\n      exp.pull = resolve().then(\n        payload => {\n          // We don't transfer ownership of stubs in the payload since the payload\n          // belongs to the hook which sticks around to handle pipelined requests.\n          let value = Devaluator.devaluate(payload.value, undefined, this, payload, this.encodingLevel);\n          this.send([\"resolve\", exportId, value]);\n          if (autoRelease) this.releaseExport(exportId, 1);\n        },\n        error => {\n          this.send([\"reject\", exportId, Devaluator.devaluate(error, undefined, this, undefined, this.encodingLevel)]);\n          if (autoRelease) this.releaseExport(exportId, 1);\n        }\n      ).catch(\n        error => {\n          // If serialization failed, report the serialization error, which should\n          // itself always be serializable.\n          try {\n            this.send([\"reject\", exportId, Devaluator.devaluate(error, undefined, this, undefined, this.encodingLevel)]);\n            if (autoRelease) this.releaseExport(exportId, 1);\n          } catch (error2) {\n            // TODO: Shouldn't happen, now what?\n            this.abort(error2);\n          }\n        }\n      ).finally(() => {\n        if (--this.pullCount === 0) {\n          if (this.onBatchDone) {\n            this.onBatchDone.resolve();\n          }\n        }\n      });\n    }\n  }\n\n  getImport(hook: StubHook): ImportId | undefined {\n    if (hook instanceof RpcImportHook && hook.entry && hook.entry.session === this) {\n      return hook.entry.importId;\n    } else {\n      return undefined;\n    }\n  }\n\n  importStub(idx: ImportId): RpcImportHook {\n    if (this.abortReason) throw this.abortReason;\n\n    let entry = this.imports[idx];\n    if (!entry) {\n      entry = new ImportTableEntry(this, idx, false);\n      this.imports[idx] = entry;\n    }\n    return new RpcImportHook(/*isPromise=*/false, entry);\n  }\n\n  importPromise(idx: ImportId): StubHook {\n    if (this.abortReason) throw this.abortReason;\n\n    if (this.imports[idx]) {\n      // Can't reuse an existing ID for a promise!\n      return new ErrorStubHook(new Error(\n          \"Bug in RPC system: The peer sent a promise reusing an existing export ID.\"));\n    }\n\n    // Create an already-pulling hook.\n    let entry = new ImportTableEntry(this, idx, true);\n    this.imports[idx] = entry;\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  getExport(idx: ExportId): StubHook | undefined {\n    return this.exports[idx]?.hook;\n  }\n\n  getPipeReadable(exportId: ExportId): ReadableStream {\n    let entry = this.exports[exportId];\n    if (!entry || !entry.pipeReadable) {\n      throw new Error(`Export ${exportId} is not a pipe or its readable end was already consumed.`);\n    }\n    let readable = entry.pipeReadable;\n    entry.pipeReadable = undefined;\n    return readable;\n  }\n\n  getLimits(): RpcLimits {\n    return this.limits;\n  }\n\n  createPipe(readable: ReadableStream, readableHook: StubHook): ImportId {\n    if (this.abortReason) throw this.abortReason;\n\n    this.send([\"pipe\"]);\n\n    let importId = this.imports.length;\n    // The pipe import is not a promise -- it's immediately usable as a writable stream.\n    let entry = new ImportTableEntry(this, importId, false);\n    this.imports.push(entry);\n\n    // Create a proxy WritableStream from the import hook and pump the ReadableStream into it.\n    let hook = new RpcImportHook(/*isPromise=*/false, entry);\n    let writable = streamImpl.createWritableStreamFromHook(hook);\n    readable.pipeTo(writable).catch(() => {\n      // Errors are handled by the writable stream's error handling -- either the write fails\n      // and the writable side reports it, or the readable side errors and pipeTo aborts the\n      // writable side. Either way, the hook's disposal will handle cleanup.\n    }).finally(() => readableHook.dispose());\n\n    return importId;\n  }\n\n  // Serializes and sends a message. Returns the byte length reported by the transport, or\n  // undefined if the transport doesn't report size.\n  private send(msg: any): number | undefined {\n    if (this.abortReason !== undefined) {\n      // Ignore sends after we've aborted.\n      return 0;\n    }\n\n    if (this.encodingLevel === \"string\") {\n      let msgText: string;\n      try {\n        msgText = JSON.stringify(msg);\n      } catch (err) {\n        // If JSON stringification failed, there's something wrong with the devaluator, as it\n        // should not allow non-JSONable values to be injected in the first place.\n        try { this.abort(err); } catch (err2) {}\n        throw err;\n      }\n\n      try {\n        let sent = (this.transport as RpcTransport).send(msgText) as Promise<void> | undefined;\n        if (sent !== undefined && typeof sent.catch === \"function\") {\n          // If send fails, abort the connection, but don't try to send an abort message since\n          // that'll probably also fail.\n          sent.catch(err => this.abort(err, false));\n        }\n      } catch (err) {\n        // The transport threw synchronously. Treat it like an async send failure: abort the\n        // session (without trying to send an abort message over the broken transport), but\n        // defer to a microtask so the caller finishes its own bookkeeping first, matching the\n        // timing of a rejected promise from an async transport.\n        queueMicrotask(() => this.abort(err, false));\n      }\n      return msgText.length;\n    } else {\n      // Custom encoding transport encodes and returns the actual encoded size, or void if size\n      // is unavailable (e.g. structured clone).\n      try {\n        let size = (this.transport as RpcTransportWithCustomEncoding).send(msg);\n        if (typeof size === \"number\") {\n          return size;\n        }\n        // Defend against transports that return something other than a number, e.g. an\n        // accidentally-async `send()` returning a promise: treat the size as unknown, and\n        // observe any returned thenable so a rejection aborts the session rather than going\n        // unhandled. (The documented contract is to report errors via `receive()`.)\n        let thenable = size as unknown;\n        if (thenable && typeof (thenable as PromiseLike<unknown>).then === \"function\") {\n          Promise.resolve(thenable).catch(err => this.abort(err, false));\n        }\n        return undefined;\n      } catch (err) {\n        // Same as the synchronous failure case above.\n        queueMicrotask(() => this.abort(err, false));\n        return undefined;\n      }\n    }\n  }\n\n  sendCall(id: ImportId, path: PropertyPath, args?: RpcPayload): RpcImportHook {\n    if (this.abortReason) throw this.abortReason;\n\n    let value: Array<any> = [\"pipeline\", id, path];\n    if (args) {\n      let devalue = Devaluator.devaluate(args.value, undefined, this, args, this.encodingLevel);\n\n      // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n      // TODO: Clean this up somehow.\n      value.push((<Array<unknown>>devalue)[0]);\n\n      // Serializing the payload takes ownership of all stubs within, so the payload itself does\n      // not need to be disposed.\n    }\n    this.send([\"push\", value]);\n\n    let entry = new ImportTableEntry(this, this.imports.length, false);\n    this.imports.push(entry);\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  sendStream(id: ImportId, path: PropertyPath, args: RpcPayload)\n      : {promise: Promise<void>, size: number} {\n    if (this.abortReason) throw this.abortReason;\n\n    let value: Array<any> = [\"pipeline\", id, path];\n    let devalue = Devaluator.devaluate(args.value, undefined, this, args, this.encodingLevel);\n\n    // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n    // TODO: Clean this up somehow.\n    value.push((<Array<unknown>>devalue)[0]);\n\n    let msg = [\"stream\", value];\n    let size = this.send(msg);\n    if (size === undefined) {\n      size = estimateEncodedSize(msg);\n    }\n\n    // Create the import entry in \"already pulling\" state (pulling=true), since stream messages\n    // are automatically pulled. Set remoteRefcount to 0 so that resolve() won't send a release\n    // message — the server implicitly releases the export after sending the resolve. Set\n    // localRefcount to 1 so that resolve() doesn't treat this as already-disposed.\n    let importId = this.imports.length;\n    let entry = new ImportTableEntry(this, importId, /*pulling=*/true);\n    entry.remoteRefcount = 0;\n    entry.localRefcount = 1;\n    this.imports.push(entry);\n\n    // Await the resolution, then dispose the result payload and clean up the import table entry.\n    // (Normally, sendRelease() cleans up the import table, but since remoteRefcount is 0, we\n    // need to do it manually.)\n    let promise = entry.awaitResolution().then(\n      p => { p.dispose(); delete this.imports[importId]; },\n      err => { delete this.imports[importId]; throw err; }\n    );\n\n    return { promise, size };\n  }\n\n  sendMap(id: ImportId, path: PropertyPath, captures: StubHook[], instructions: unknown[])\n      : RpcImportHook {\n    if (this.abortReason) {\n      for (let cap of captures) {\n        cap.dispose();\n      }\n      throw this.abortReason;\n    }\n\n    let devaluedCaptures = captures.map(hook => {\n      let importId = this.getImport(hook);\n      if (importId !== undefined) {\n        return [\"import\", importId];\n      } else {\n        return [\"export\", this.exportStub(hook)];\n      }\n    });\n\n    let value = [\"remap\", id, path, devaluedCaptures, instructions];\n\n    this.send([\"push\", value]);\n\n    let entry = new ImportTableEntry(this, this.imports.length, false);\n    this.imports.push(entry);\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  sendPull(id: ImportId) {\n    if (this.abortReason) throw this.abortReason;\n\n    this.send([\"pull\", id]);\n  }\n\n  sendRelease(id: ImportId, remoteRefcount: number) {\n    if (this.abortReason) return;\n\n    this.send([\"release\", id, remoteRefcount]);\n    delete this.imports[id];\n  }\n\n  abort(error: any, trySendAbortMessage: boolean = true) {\n    // Don't double-abort.\n    if (this.abortReason !== undefined) return;\n\n    this.cancelReadLoop?.(error);\n    this.cancelReadLoop = undefined;\n\n    if (trySendAbortMessage) {\n      try {\n        let abortMsg = [\"abort\", Devaluator.devaluate(error, undefined, this, undefined, this.encodingLevel)];\n        if (this.encodingLevel === \"string\") {\n          let sent = (this.transport as RpcTransport)\n              .send(JSON.stringify(abortMsg)) as Promise<void> | undefined;\n          if (sent !== undefined && typeof sent.catch === \"function\") {\n            sent.catch(err => {});\n          }\n        } else {\n          let result = (this.transport as RpcTransportWithCustomEncoding).send(abortMsg) as unknown;\n          if (result && typeof (result as PromiseLike<unknown>).then === \"function\") {\n            Promise.resolve(result).catch(err => {});\n          }\n        }\n      } catch (err) {\n        // ignore, probably the whole reason we're aborting is because the transport is broken\n      }\n    }\n\n    if (error === undefined) {\n      // Shouldn't happen, but if it does, avoid setting `abortReason` to `undefined`.\n      error = \"undefined\";\n    }\n\n    this.abortReason = error;\n    if (this.onBatchDone) {\n      this.onBatchDone.reject(error);\n    }\n\n    if (this.transport.abort) {\n      // Call transport's abort handler, but guard against buggy app code.\n      try {\n        this.transport.abort(error);\n      } catch (err) {\n        // Treat as unhandled rejection.\n        Promise.resolve(err);\n      }\n    }\n\n    // WATCH OUT: these are sparse arrays. `for/let/of` will iterate only positive indexes\n    // including deleted indexes -- bad. We need to use `for/let/in` instead.\n    for (let i in this.onBrokenCallbacks) {\n      try {\n        this.onBrokenCallbacks[i](error);\n      } catch (err) {\n        // Treat as unhandled rejection.\n        Promise.resolve(err);\n      }\n    }\n    for (let i in this.imports) {\n      this.imports[i].abort(error);\n    }\n    for (let i in this.exports) {\n      this.exports[i].hook.dispose();\n    }\n  }\n\n  private async readLoop() {\n    while (!this.abortReason) {\n      // Each receive needs its own abort promise so Promise.race() doesn't keep old reads.\n      let readCanceled = Promise.withResolvers<never>();\n      this.cancelReadLoop = readCanceled.reject;\n\n      let raw: unknown;\n\n      try {\n        raw = await Promise.race([this.transport.receive(), readCanceled.promise]);\n      } finally {\n        if (this.cancelReadLoop === readCanceled.reject) {\n          this.cancelReadLoop = undefined;\n        }\n      }\n\n      // Bound a single string message before parsing it. At this point the transport has already\n      // buffered the complete message; true byte-level / pre-read enforcement belongs in the\n      // transport/socket. This backstop still prevents oversized messages from reaching JSON.parse\n      // and downstream deserialization work, and a throw here propagates out of readLoop and aborts\n      // the session. Only \"string\"-level transports hand us a measurable wire string; richer\n      // encoding levels deliver an already-decoded value, so the size cap does not apply.\n      if (this.encodingLevel === \"string\" &&\n          (raw as string).length > this.limits.maxMessageSize) {\n        throw new TypeError(\n            `Incoming message exceeds maximum size of ${this.limits.maxMessageSize} UTF-16 code ` +\n            `units.`);\n      }\n\n      if (this.abortReason) break;  // check again before processing\n\n      // Only parse JSON at \"string\" level; otherwise message is already an object\n      let msg = this.encodingLevel === \"string\" ? JSON.parse(raw as string) : raw;\n\n      if (msg instanceof Array) {\n        switch (msg[0]) {\n          case \"push\":  // [\"push\", Expression]\n            if (msg.length > 1) {\n              let payload = new Evaluator(this, this.encodingLevel, this.options.onCall).evaluate(msg[1]);\n              let hook = new PayloadStubHook(payload);\n\n              // It's possible for a rejection to occur before the client gets a chance to send\n              // a \"pull\" message or to use the promise in a pipeline. We don't want that to be\n              // treated as an unhandled rejection on our end.\n              hook.ignoreUnhandledRejections();\n\n              this.exports.push({ hook, refcount: 1 });\n              continue;\n            }\n            break;\n\n          case \"stream\": {  // [\"stream\", Expression]\n            // Like \"push\", but:\n            // - Promise pipelining on the result is not supported.\n            // - The export is automatically considered \"pulled\".\n            // - Once the \"resolve\" is sent, the export is implicitly released.\n            if (msg.length > 1) {\n              let payload = new Evaluator(this, this.encodingLevel, this.options.onCall).evaluate(msg[1]);\n              let hook = new PayloadStubHook(payload);\n              hook.ignoreUnhandledRejections();\n\n              let exportId = this.exports.length;\n              this.exports.push({ hook, refcount: 1, autoRelease: true });\n\n              // Automatically pull since stream messages are always pulled.\n              this.ensureResolvingExport(exportId);\n              continue;\n            }\n            break;\n          }\n\n          case \"pipe\": {  // [\"pipe\"]\n            // Create a TransformStream. The writable end becomes the export (so the sender can\n            // write/close/abort it). The readable end is stashed for later retrieval via\n            // [\"readable\", importId].\n            let { readable, writable } = new TransformStream();\n            let hook = streamImpl.createWritableStreamHook(writable);\n            this.exports.push({ hook, refcount: 1, pipeReadable: readable });\n            continue;\n          }\n\n          case \"pull\": {  // [\"pull\", ImportId]\n            let exportId = msg[1];\n            if (typeof exportId == \"number\") {\n              this.ensureResolvingExport(exportId);\n              continue;\n            }\n            break;\n          }\n\n          case \"resolve\":   // [\"resolve\", ExportId, Expression]\n          case \"reject\": {  // [\"reject\", ExportId, Expression]\n            let importId = msg[1];\n            if (typeof importId == \"number\" && msg.length > 2) {\n              let imp = this.imports[importId];\n              if (imp) {\n                if (msg[0] == \"resolve\") {\n                  imp.resolve(new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[2])));\n                } else {\n                  // HACK: We expect errors are always simple values (no stubs) so we can just\n                  //   pull the value out of the payload.\n                  let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[2]);\n                  payload.dispose();  // just in case -- should be no-op\n                  imp.resolve(new ErrorStubHook(payload.value));\n                }\n              } else {\n                // Import ID is not found on the table. Probably we released it already, in which\n                // case we do not care about the resolution, so whatever.\n\n                if (msg[0] == \"resolve\") {\n                  // We need to evaluate the resolution and immediately dispose it so that we\n                  // release any stubs it contains.\n                  new Evaluator(this, this.encodingLevel).evaluate(msg[2]).dispose();\n                }\n              }\n              continue;\n            }\n            break;\n          }\n\n          case \"release\": {\n            let exportId = msg[1];\n            let refcount = msg[2];\n            if (typeof exportId == \"number\" && typeof refcount == \"number\") {\n              this.releaseExport(exportId, refcount);\n              continue;\n            }\n            break;\n          }\n\n          case \"abort\": {\n            let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[1]);\n            payload.dispose();  // just in case -- should be no-op\n            this.abort(payload.value, false);\n            break;\n          }\n        }\n      }\n\n      throw new Error(`bad RPC message: ${JSON.stringify(msg)}`);\n    }\n  }\n\n  async drain(): Promise<void> {\n    if (this.abortReason) {\n      throw this.abortReason;\n    }\n\n    if (this.pullCount > 0) {\n      let {promise, resolve, reject} = Promise.withResolvers<void>();\n      this.onBatchDone = {resolve, reject};\n      await promise;\n    }\n  }\n\n  getStats(): {imports: number, exports: number} {\n    let result = {imports: 0, exports: 0};\n    // We can't just use `.length` because the arrays can be sparse and can have negative indexes.\n    for (let i in this.imports) {\n      ++result.imports;\n    }\n    for (let i in this.exports) {\n      ++result.exports;\n    }\n    return result;\n  }\n}\n\n// Public interface that wraps RpcSession and hides private implementation details (even from\n// JavaScript with no type enforcement).\nexport class RpcSession {\n  #session: RpcSessionImpl;\n  #mainStub: RpcStub;\n\n  constructor(transport: AnyRpcTransport, localMain?: any, options: RpcSessionOptions = {}) {\n    let mainHook: StubHook;\n    if (localMain) {\n      mainHook = new PayloadStubHook(RpcPayload.fromAppReturn(localMain));\n    } else {\n      mainHook = new ErrorStubHook(new Error(\"This connection has no main object.\"));\n    }\n    this.#session = new RpcSessionImpl(transport, mainHook, options);\n    this.#mainStub = new RpcStub(this.#session.getMainImport());\n  }\n\n  getRemoteMain(): RpcStub {\n    return this.#mainStub;\n  }\n\n  getStats(): {imports: number, exports: number} {\n    return this.#session.getStats();\n  }\n\n  drain(): Promise<void> {\n    return this.#session.drain();\n  }\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\n/// <reference types=\"@cloudflare/workers-types\" />\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcSession, RpcSessionOptions } from \"./rpc.js\";\n\n/** Close-frame reason max UTF-8 bytes: 125 payload − 2-byte status (RFC 6455 §5.5). */\nexport const MAX_CLOSE_REASON_BYTES = 125 - 2;\n\nexport function newWebSocketRpcSession(\n    webSocket: WebSocket | string, localMain?: any, options?: RpcSessionOptions): RpcStub {\n  if (typeof webSocket === \"string\") {\n    webSocket = new WebSocket(webSocket);\n  }\n\n  let transport = new WebSocketTransport(webSocket);\n  let rpc = new RpcSession(transport, localMain, options);\n  return rpc.getRemoteMain();\n}\n\n/**\n * For use in Cloudflare Workers: Construct an HTTP response that starts a WebSocket RPC session\n * with the given `localMain`.\n */\nexport function newWorkersWebSocketRpcResponse(\n    request: Request, localMain?: any, options?: RpcSessionOptions): Response {\n  if (request.headers.get(\"Upgrade\")?.toLowerCase() !== \"websocket\") {\n    return new Response(\"This endpoint only accepts WebSocket requests.\", { status: 400 });\n  }\n\n  let pair = new WebSocketPair();\n  let server = pair[0];\n  server.accept()\n  newWebSocketRpcSession(server, localMain, options);\n  return new Response(null, {\n    status: 101,\n    webSocket: pair[1],\n  });\n}\n\n/**\n * Generic WebSocket transport. Default `T = string` is backward-compatible and satisfies\n * `RpcTransport`. Use `T = ArrayBuffer` as a building block for binary transports.\n */\nexport class WebSocketTransport<T extends string | ArrayBuffer = string> {\n  constructor (webSocket: WebSocket) {\n    this.#webSocket = webSocket;\n\n    // Always set binaryType — harmless for string mode, required for ArrayBuffer mode.\n    webSocket.binaryType = \"arraybuffer\";\n\n    if (webSocket.readyState === WebSocket.CONNECTING) {\n      this.#sendQueue = [];\n      webSocket.addEventListener(\"open\", event => {\n        try {\n          for (let message of this.#sendQueue!) {\n            webSocket.send(message);\n          }\n        } catch (err) {\n          this.#receivedError(err);\n        }\n        this.#sendQueue = undefined;\n      });\n    }\n\n    webSocket.addEventListener(\"message\", (event: MessageEvent<any>) => {\n      if (this.#error) {\n        // Ignore further messages.\n      } else if (typeof event.data === \"string\" || event.data instanceof ArrayBuffer) {\n        if (this.#receiveResolver) {\n          this.#receiveResolver(event.data as T);\n          this.#receiveResolver = undefined;\n          this.#receiveRejecter = undefined;\n        } else {\n          this.#receiveQueue.push(event.data as T);\n        }\n      } else {\n        this.#receivedError(new TypeError(\"Received unexpected message type from WebSocket.\"));\n      }\n    });\n\n    webSocket.addEventListener(\"close\", (event: CloseEvent) => {\n      this.#receivedError(new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`));\n    });\n\n    webSocket.addEventListener(\"error\", (event: Event) => {\n      this.#receivedError(new Error(`WebSocket connection failed.`));\n    });\n  }\n\n  #webSocket: WebSocket;\n  #sendQueue?: T[];  // only if not opened yet\n  #receiveResolver?: (message: T) => void;\n  #receiveRejecter?: (err: any) => void;\n  #receiveQueue: T[] = [];\n  #error?: any;\n\n  send(message: T): void {\n    if (this.#sendQueue === undefined) {\n      this.#webSocket.send(message);\n    } else {\n      // Not open yet, queue for later.\n      this.#sendQueue.push(message);\n    }\n  }\n\n  receive(): Promise<T> {\n    if (this.#receiveQueue.length > 0) {\n      return Promise.resolve(this.#receiveQueue.shift()!);\n    } else if (this.#error) {\n      return Promise.reject(this.#error);\n    } else {\n      return new Promise<T>((resolve, reject) => {\n        this.#receiveResolver = resolve;\n        this.#receiveRejecter = reject;\n      });\n    }\n  }\n\n  abort(reason: any): void {\n    let message: string;\n    if (reason instanceof Error) {\n      message = reason.message;\n    } else {\n      message = `${reason}`;\n    }\n    // `stream: true` drops a trailing partial code point rather than emitting a replacement char.\n    let reasonBytes = new TextEncoder().encode(message);\n    if (reasonBytes.length > MAX_CLOSE_REASON_BYTES) {\n      message = new TextDecoder().decode(reasonBytes.subarray(0, MAX_CLOSE_REASON_BYTES), { stream: true });\n    }\n    this.#webSocket.close(3000, message);\n\n    if (!this.#error) {\n      this.#error = reason;\n      // No need to call receiveRejecter(); RPC implementation will stop listening anyway.\n    }\n  }\n\n  #receivedError(reason: any) {\n    if (!this.#error) {\n      this.#error = reason;\n      if (this.#receiveRejecter) {\n        this.#receiveRejecter(reason);\n        this.#receiveResolver = undefined;\n        this.#receiveRejecter = undefined;\n      }\n    }\n  }\n}\n\n// This class is generic, so it can't `implements RpcTransport` (that would require every `T` to\n// conform, but the ArrayBuffer instantiation intentionally doesn't). The default string\n// instantiation's conformance is asserted in __type-tests__/rpc-types.test.ts.\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcTransport, RpcSession, RpcSessionOptions } from \"./rpc.js\";\nimport type { IncomingMessage, ServerResponse, OutgoingHttpHeader, OutgoingHttpHeaders } from \"node:http\";\n\ntype SendBatchFunc = (batch: string[]) => Promise<string[]>;\n\nclass BatchClientTransport implements RpcTransport {\n  constructor(sendBatch: SendBatchFunc) {\n    this.#promise = this.#scheduleBatch(sendBatch);\n  }\n\n  #promise: Promise<void>;\n  #aborted: any;\n\n  #batchToSend: string[] | null = [];\n  #batchToReceive: string[] | null = null;\n\n  send(message: string): void {\n    // If the batch was already sent, we just ignore the message, because throwing may cause the\n    // RPC system to abort prematurely. Once the last receive() is done then we'll throw an error\n    // that aborts the RPC system at the right time and will propagate to all other requests.\n    if (this.#batchToSend !== null) {\n      this.#batchToSend.push(message);\n    }\n  }\n\n  async receive(): Promise<string> {\n    if (!this.#batchToReceive) {\n      await this.#promise;\n    }\n\n    let msg = this.#batchToReceive!.shift();\n    if (msg !== undefined) {\n      return msg;\n    } else {\n      // No more messages. An error thrown here will propagate out of any calls that are still\n      // open.\n      throw new Error(\"Batch RPC request ended.\");\n    }\n  }\n\n  abort?(reason: any): void {\n    this.#aborted = reason;\n  }\n\n  async #scheduleBatch(sendBatch: SendBatchFunc) {\n    // Wait for microtask queue to clear before sending a batch.\n    //\n    // Note that simply waiting for one turn of the microtask queue (await Promise.resolve()) is\n    // not good enough here as the application needs a chance to call `.then()` on every RPC\n    // promise in order to explicitly indicate they want the results. Unfortunately, `await`ing\n    // a thenable does not call `.then()` immediately -- for some reason it waits for a turn of\n    // the microtask queue first, *then* calls `.then()`.\n    await new Promise(resolve => setTimeout(resolve, 0));\n\n    if (this.#aborted !== undefined) {\n      throw this.#aborted;\n    }\n\n    let batch = this.#batchToSend!;\n    this.#batchToSend = null;\n    this.#batchToReceive = await sendBatch(batch);\n  }\n}\n\nexport function newHttpBatchRpcSession(\n    urlOrRequest: string | Request, options?: RpcSessionOptions): RpcStub {\n  let sendBatch: SendBatchFunc = async (batch: string[]) => {\n    let response = await fetch(urlOrRequest, {\n      method: \"POST\",\n      body: batch.join(\"\\n\"),\n    });\n\n    if (!response.ok) {\n      response.body?.cancel();\n      throw new Error(`RPC request failed: ${response.status} ${response.statusText}`);\n    }\n\n    let body = await response.text();\n    return body == \"\" ? [] : body.split(\"\\n\");\n  };\n\n  let transport = new BatchClientTransport(sendBatch);\n  let rpc = new RpcSession(transport, undefined, options);\n  return rpc.getRemoteMain();\n}\n\nclass BatchServerTransport implements RpcTransport {\n  constructor(batch: string[]) {\n    this.#batchToReceive = batch;\n  }\n\n  #batchToSend: string[] = [];\n  #batchToReceive: string[];\n  #allReceived: PromiseWithResolvers<void> = Promise.withResolvers<void>();\n\n  send(message: string): void {\n    this.#batchToSend.push(message);\n  }\n\n  async receive(): Promise<string> {\n    let msg = this.#batchToReceive!.shift();\n    if (msg !== undefined) {\n      return msg;\n    } else {\n      // No more messages.\n      this.#allReceived.resolve();\n      return new Promise(r => {});\n    }\n  }\n\n  abort?(reason: any): void {\n    this.#allReceived.reject(reason);\n  }\n\n  whenAllReceived() {\n    return this.#allReceived.promise;\n  }\n\n  getResponseBody(): string {\n    return this.#batchToSend.join(\"\\n\");\n  }\n}\n\n/**\n * Implements the server end of an HTTP batch session, using standard Fetch API types to represent\n * HTTP requests and responses.\n *\n * @param request The request received from the client initiating the session.\n * @param localMain The main stub or RpcTarget which the server wishes to expose to the client.\n * @param options Optional RPC session options.\n * @returns The HTTP response to return to the client. Note that the returned object has mutable\n *     headers, so you can modify them using e.g. `response.headers.set(\"Foo\", \"bar\")`.\n */\nexport async function newHttpBatchRpcResponse(\n    request: Request, localMain: any, options?: RpcSessionOptions): Promise<Response> {\n  if (request.method !== \"POST\") {\n    return new Response(\"This endpoint only accepts POST requests.\", { status: 405 });\n  }\n\n  let body = await request.text();\n  let batch = body === \"\" ? [] : body.split(\"\\n\");\n\n  let transport = new BatchServerTransport(batch);\n  let rpc = new RpcSession(transport, localMain, options);\n\n  // TODO: Arguably we should arrange so any attempts to pull promise resolutions from the client\n  //   will reject rather than just hang. But it IS valid to make server->client calls in order to\n  //   then pipeline the result into something returned to the client. We don't want the errors to\n  //   prematurely cancel anything that would eventually complete. So for now we just say, it's the\n  //   app's responsibility to not wait on any server -> client calls since they will never\n  //   complete.\n\n  await transport.whenAllReceived();\n  await rpc.drain();\n\n  // TODO: Ask RpcSession to dispose everything it is still holding on to?\n\n  return new Response(transport.getResponseBody());\n}\n\n/**\n * Implements the server end of an HTTP batch session using traditional Node.js HTTP APIs.\n *\n * @param request The request received from the client initiating the session.\n * @param response The response object, to which the response should be written.\n * @param localMain The main stub or RpcTarget which the server wishes to expose to the client.\n * @param options Optional RPC session options. You can also pass headers to set on the response.\n */\nexport async function nodeHttpBatchRpcResponse(\n    request: IncomingMessage, response: ServerResponse,\n    localMain: any,\n    options?: RpcSessionOptions & {\n      headers?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n    }): Promise<void> {\n  if (request.method !== \"POST\") {\n    response.writeHead(405, \"This endpoint only accepts POST requests.\", options?.headers);\n    response.end();\n    return;\n  }\n\n  let body = await new Promise<string>((resolve, reject) => {\n    let chunks: Buffer[] = [];\n    request.on(\"data\", chunk => {\n      chunks.push(chunk);\n    });\n    request.on(\"end\", () => {\n      resolve(Buffer.concat(chunks).toString());\n    });\n    request.on(\"error\", reject);\n  });\n  let batch = body === \"\" ? [] : body.split(\"\\n\");\n\n  let transport = new BatchServerTransport(batch);\n  let rpc = new RpcSession(transport, localMain, options);\n\n  await transport.whenAllReceived();\n  await rpc.drain();\n\n  response.writeHead(200, options?.headers);\n  response.end(transport.getResponseBody());\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcTransportWithCustomEncoding, RpcSession, RpcSessionOptions } from \"./rpc.js\";\n\n// Start a MessagePort session given a MessagePort or a pair of MessagePorts.\n//\n// `localMain` is the main RPC interface to expose to the peer. Returns a stub for the main\n// interface exposed from the peer.\nexport function newMessagePortRpcSession(\n    port: MessagePort, localMain?: any, options?: RpcSessionOptions): RpcStub {\n  let transport = new MessagePortTransport(port);\n  let rpc = new RpcSession(transport, localMain, options);\n  return rpc.getRemoteMain();\n}\n\nclass MessagePortTransport implements RpcTransportWithCustomEncoding {\n  readonly encodingLevel = \"structuredClonable\" as const;\n\n  constructor (port: MessagePort) {\n    this.#port = port;\n\n    // Start listening for messages\n    port.start();\n\n    port.addEventListener(\"message\", (event: MessageEvent<any>) => {\n      if (this.#error) {\n        // Ignore further messages.\n      } else if (event.data === null) {\n        // Peer is signaling that they're closing the connection\n        this.#receivedError(new Error(\"Peer closed MessagePort connection.\"));\n      } else {\n        // Accept any structured-clonable data\n        if (this.#receiveResolver) {\n          this.#receiveResolver(event.data);\n          this.#receiveResolver = undefined;\n          this.#receiveRejecter = undefined;\n        } else {\n          this.#receiveQueue.push(event.data);\n        }\n      }\n    });\n\n    port.addEventListener(\"messageerror\", (event: MessageEvent) => {\n      this.#receivedError(new Error(\"MessagePort message error.\"));\n    });\n  }\n\n  #port: MessagePort;\n  #receiveResolver?: (message: unknown) => void;\n  #receiveRejecter?: (err: any) => void;\n  #receiveQueue: unknown[] = [];\n  #error?: any;\n\n  send(message: unknown): void {\n    if (this.#error) {\n      throw this.#error;\n    }\n    this.#port.postMessage(message);\n  }\n\n  async receive(): Promise<unknown> {\n    if (this.#receiveQueue.length > 0) {\n      return this.#receiveQueue.shift()!;\n    } else if (this.#error) {\n      throw this.#error;\n    } else {\n      return new Promise<unknown>((resolve, reject) => {\n        this.#receiveResolver = resolve;\n        this.#receiveRejecter = reject;\n      });\n    }\n  }\n\n  abort(reason: any): void {\n    // Send close signal to peer before closing\n    try {\n      this.#port.postMessage(null);\n    } catch (err) {\n      // Ignore errors when sending close signal - port might already be closed\n    }\n\n    this.#port.close();\n\n    if (!this.#error) {\n      this.#error = reason;\n      // No need to call receiveRejecter(); RPC implementation will stop listening anyway.\n    }\n  }\n\n  #receivedError(reason: any) {\n    if (!this.#error) {\n      this.#error = reason;\n      if (this.#receiveRejecter) {\n        this.#receiveRejecter(reason);\n        this.#receiveResolver = undefined;\n        this.#receiveRejecter = undefined;\n      }\n    }\n  }\n}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, PropertyPath, RpcPayload, RpcStub, RpcPromise, withCallInterceptor, ErrorStubHook, mapImpl, PayloadStubHook, unwrapStubAndPath, unwrapStubNoProperties } from \"./core.js\";\nimport { Devaluator, Exporter, Importer, ExportId, ImportId, Evaluator, RpcLimits, DEFAULT_LIMITS } from \"./serialize.js\";\n\nlet currentMapBuilder: MapBuilder | undefined;\n\n// We use this type signature when building the instructions for type checking purposes. It\n// describes a subset of the overall RPC protocol.\nexport type MapInstruction =\n    | [\"pipeline\", number, PropertyPath]\n    | [\"pipeline\", number, PropertyPath, unknown]\n    | [\"remap\", number, PropertyPath, [\"import\", number][], MapInstruction[]]\n\nclass MapBuilder implements Exporter {\n  private context:\n    | {parent: undefined, captures: StubHook[], subject: StubHook, path: PropertyPath}\n    | {parent: MapBuilder, captures: number[], subject: number, path: PropertyPath};\n  private captureMap: Map<StubHook, number> = new Map();\n\n  private instructions: MapInstruction[] = [];\n\n  constructor(subject: StubHook, path: PropertyPath) {\n    if (currentMapBuilder) {\n      this.context = {\n        parent: currentMapBuilder,\n        captures: [],\n        subject: currentMapBuilder.capture(subject),\n        path\n      };\n    } else {\n      this.context = {\n        parent: undefined,\n        captures: [],\n        subject,\n        path\n      };\n    }\n\n    currentMapBuilder = this;\n  }\n\n  unregister() {\n    currentMapBuilder = this.context.parent;\n  }\n\n  makeInput(): MapVariableHook {\n    return new MapVariableHook(this, 0);\n  }\n\n  makeOutput(result: RpcPayload): StubHook {\n    let devalued: unknown;\n    try {\n      devalued = Devaluator.devaluate(result.value, undefined, this, result);\n    } finally {\n      result.dispose();\n    }\n\n    // The result is the final instruction. This doesn't actually fit our MapInstruction type\n    // signature, so we cheat a bit.\n    this.instructions.push(<any>devalued);\n\n    if (this.context.parent) {\n      this.context.parent.instructions.push(\n        [\"remap\", this.context.subject, this.context.path,\n                  this.context.captures.map(cap => [\"import\", cap]),\n                  this.instructions]\n      );\n      return new MapVariableHook(this.context.parent, this.context.parent.instructions.length);\n    } else {\n      return this.context.subject.map(this.context.path, this.context.captures, this.instructions);\n    }\n  }\n\n  pushCall(hook: StubHook, path: PropertyPath, params: RpcPayload): StubHook {\n    let devalued = Devaluator.devaluate(params.value, undefined, this, params);\n    // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n    // TODO: Clean this up somehow.\n    devalued = (<Array<unknown>>devalued)[0];\n\n    let subject = this.capture(hook.dup());\n    this.instructions.push([\"pipeline\", subject, path, devalued]);\n    return new MapVariableHook(this, this.instructions.length);\n  }\n\n  pushGet(hook: StubHook, path: PropertyPath): StubHook {\n    let subject = this.capture(hook.dup());\n    this.instructions.push([\"pipeline\", subject, path]);\n    return new MapVariableHook(this, this.instructions.length);\n  }\n\n  capture(hook: StubHook): number {\n    if (hook instanceof MapVariableHook && hook.mapper === this) {\n      // Oh, this is already our own hook.\n      return hook.idx;\n    }\n\n    // TODO: Well, the hooks passed in are always unique, so they'll never exist in captureMap.\n    //   I suppose this is a problem with RPC as well. We need a way to identify hooks that are\n    //   dupes of the same target.\n    let result = this.captureMap.get(hook);\n    if (result === undefined) {\n      if (this.context.parent) {\n        let parentIdx = this.context.parent.capture(hook);\n        this.context.captures.push(parentIdx);\n      } else {\n        this.context.captures.push(hook);\n      }\n      result = -this.context.captures.length;\n      this.captureMap.set(hook, result);\n    }\n    return result;\n  }\n\n  // ---------------------------------------------------------------------------\n  // implements Exporter\n\n  exportStub(hook: StubHook): ExportId {\n    // It appears someone did something like:\n    //\n    //     stub.map(x => { return x.doSomething(new MyRpcTarget()); })\n    //\n    // That... won't work. They need to do this instead:\n    //\n    //     using myTargetStub = new RpcStub(new MyRpcTarget());\n    //     stub.map(x => { return x.doSomething(myTargetStub.dup()); })\n    //\n    // TODO(someday): Consider carefully if the inline syntax is maybe OK. If so, perhaps the\n    //   serializer could try calling `getImport()` even for known-local hooks.\n    // TODO(someday): Do we need to support rpc-thenable somehow?\n    throw new Error(\n        \"Can't construct an RpcTarget or RPC callback inside a mapper function. Try creating a \" +\n        \"new RpcStub outside the callback first, then using it inside the callback.\");\n  }\n  exportPromise(hook: StubHook): ExportId {\n    return this.exportStub(hook);\n  }\n  getImport(hook: StubHook): ImportId | undefined {\n    return this.capture(hook);\n  }\n\n  unexport(ids: Array<ExportId>): void {\n    // Presumably this MapBuilder is cooked anyway, so we don't really have to release anything.\n  }\n\n  createPipe(readable: ReadableStream): never {\n    throw new Error(\"Cannot send ReadableStream inside a mapper function.\");\n  }\n\n  onSendError(error: Error): Error | void {\n    // TODO(someday): Can we use the error-sender hook from the RPC system somehow?\n  }\n};\n\nmapImpl.sendMap = (hook: StubHook, path: PropertyPath, func: (promise: RpcPromise) => unknown) => {\n  let builder = new MapBuilder(hook, path);\n  let result: RpcPayload;\n  try {\n    result = RpcPayload.fromAppReturn(withCallInterceptor(builder.pushCall.bind(builder), () => {\n      return func(new RpcPromise(builder.makeInput(), []));\n    }));\n  } finally {\n    builder.unregister();\n  }\n\n  // Detect misuse: Map callbacks cannot be async.\n  if (result instanceof Promise) {\n    // Squelch unhandled rejections from the map function itself -- it'll probably just throw\n    // something about pulling a MapVariableHook.\n    result.catch(err => {});\n\n    // Throw an understandable error.\n    throw new Error(\"RPC map() callbacks cannot be async.\");\n  }\n\n  return new RpcPromise(builder.makeOutput(result), []);\n}\n\nfunction throwMapperBuilderUseError(): never {\n  throw new Error(\n      \"Attempted to use an abstract placeholder from a mapper function. Please make sure your \" +\n      \"map function has no side effects.\");\n}\n\n// StubHook which represents a variable in a map function.\nclass MapVariableHook extends StubHook {\n  constructor(public mapper: MapBuilder, public idx: number) {\n    super();\n  }\n\n  // We don't have anything we actually need to dispose, so dup() can just return the same hook.\n  dup(): StubHook { return this; }\n  dispose(): void {}\n\n  get(path: PropertyPath): StubHook {\n    // This can actually be invoked as part of serialization, so we'll need to support it.\n    if (path.length == 0) {\n      // Since this hook cannot be pulled anyway, and dispose() is a no-op, we can actually just\n      // return the same hook again to represent getting the empty path.\n      return this;\n    } else if (currentMapBuilder) {\n      return currentMapBuilder.pushGet(this, path);\n    } else {\n      throwMapperBuilderUseError();\n    }\n  }\n\n  // Other methods should never be called.\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    // Can't be called; all calls are intercepted.\n    throwMapperBuilderUseError();\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    // Can't be called; all map()s are intercepted.\n    throwMapperBuilderUseError();\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Map functions cannot await.\n    throwMapperBuilderUseError();\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Probably never called but whatever.\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    throwMapperBuilderUseError();\n  }\n}\n\n// =======================================================================================\n\nclass MapApplicator implements Importer {\n  private variables: StubHook[];\n\n  constructor(private captures: StubHook[], input: StubHook) {\n    this.variables = [input];\n  }\n\n  dispose() {\n    for (let variable of this.variables) {\n      variable.dispose();\n    }\n  }\n\n  apply(instructions: unknown[]): RpcPayload {\n    try {\n      if (instructions.length < 1) {\n        throw new Error(\"Invalid empty mapper function.\");\n      }\n\n      for (let instruction of instructions.slice(0, -1)) {\n        let payload = new Evaluator(this).evaluateCopy(instruction);\n\n        // The payload almost always contains a single stub. As an optimization, unwrap it.\n        if (payload.value instanceof RpcStub) {\n          let hook = unwrapStubNoProperties(payload.value);\n          if (hook) {\n            this.variables.push(hook);\n            continue;\n          }\n        }\n\n        this.variables.push(new PayloadStubHook(payload));\n      }\n\n      return new Evaluator(this).evaluateCopy(instructions[instructions.length - 1]);\n    } finally {\n      for (let variable of this.variables) {\n        variable.dispose();\n      }\n    }\n  }\n\n  importStub(idx: ImportId): StubHook {\n    // This implies we saw an \"export\" appear inside the body of a mapper function. This should be\n    // impossible because exportStub()/exportPromise() throw exceptions in MapBuilder.\n    throw new Error(\"A mapper function cannot refer to exports.\");\n  }\n  importPromise(idx: ImportId): StubHook {\n    return this.importStub(idx);\n  }\n\n  getExport(idx: ExportId): StubHook | undefined {\n    if (idx < 0) {\n      return this.captures[-idx - 1];\n    } else {\n      return this.variables[idx];\n    }\n  }\n\n  getPipeReadable(exportId: ExportId): never {\n    throw new Error(\"A mapper function cannot use pipe readables.\");\n  }\n\n  getLimits(): RpcLimits {\n    // A mapper's instructions arrived inside a [\"remap\"] message that was itself deserialized\n    // under the session's limits, so the default floor is sufficient protection here without\n    // threading per-session overrides through the several layers between the session and the\n    // mapper.\n    return DEFAULT_LIMITS;\n  }\n}\n\nfunction applyMapToElement(input: unknown, parent: object | undefined, owner: RpcPayload | null,\n                           captures: StubHook[], instructions: unknown[]): RpcPayload {\n  // TODO(perf): I wonder if we could use .fromAppParams() instead of .deepCopyFrom()? It\n  //   maybe wouldn't correctly handle the case of RpcTargets in the input, so we need a variant\n  //   which takes an `owner`, which does add some complexity.\n  let inputHook = new PayloadStubHook(RpcPayload.deepCopyFrom(input, parent, owner));\n  let mapper = new MapApplicator(captures, inputHook);\n  try {\n    return mapper.apply(instructions);\n  } finally {\n    mapper.dispose();\n  }\n}\n\nmapImpl.applyMap = (input: unknown, parent: object | undefined, owner: RpcPayload | null,\n                    captures: StubHook[], instructions: unknown[]) => {\n  try {\n    let result: RpcPayload;\n    if (input instanceof RpcPromise) {\n      // The caller is responsible for making sure the input is not a promise, since we can't\n      // then know if it would resolve to an array later.\n      throw new Error(\"applyMap() can't be called on RpcPromise\");\n    } else if (input instanceof Array) {\n      let payloads: RpcPayload[] = [];\n      try {\n        for (let elem of input) {\n          payloads.push(applyMapToElement(elem, input, owner, captures, instructions));\n        }\n      } catch (err) {\n        for (let payload of payloads) {\n          payload.dispose();\n        }\n        throw err;\n      }\n\n      result = RpcPayload.fromArray(payloads);\n    } else if (input === null || input === undefined) {\n      result = RpcPayload.fromAppReturn(input);\n    } else {\n      result = applyMapToElement(input, parent, owner, captures, instructions);\n    }\n\n    // TODO(perf): We should probably return a hook that allows pipelining but whose pull() doesn't\n    //   resolve until all promises in the payload have been substituted.\n    return new PayloadStubHook(result);\n  } finally {\n    for (let cap of captures) {\n      cap.dispose();\n    }\n  }\n}\n\nexport function forceInitMap() {}\n","// Copyright (c) 2026 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport {\n  StubHook, RpcPayload, PropertyPath, ErrorStubHook, PayloadStubHook, PromiseStubHook, streamImpl\n} from \"./core.js\";\n\n// =======================================================================================\n// WritableStreamStubHook - wraps a local WritableStream for export\n\n// Many WritableStreamStubHooks could point at the same WritableStream. We store a refcount in a\n// separate object that they all share.\ntype BoxedWriterState = {\n  refcount: number;\n  writer: WritableStreamDefaultWriter;\n  closed: boolean;\n};\n\nclass WritableStreamStubHook extends StubHook {\n  private state?: BoxedWriterState;  // undefined when disposed\n\n  // Creates a new WritableStreamStubHook that is not duplicated from an existing hook.\n  static create(stream: WritableStream): WritableStreamStubHook {\n    let writer = stream.getWriter();  // Locks the stream\n    return new WritableStreamStubHook({ refcount: 1, writer, closed: false });\n  }\n\n  private constructor(state: BoxedWriterState, dupFrom?: WritableStreamStubHook) {\n    super();\n    this.state = state;\n    if (dupFrom) {\n      ++state.refcount;\n    }\n  }\n\n  private getState(): BoxedWriterState {\n    if (this.state) {\n      return this.state;\n    } else {\n      throw new Error(\"Attempted to use a WritableStreamStubHook after it was disposed.\");\n    }\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    try {\n      let state = this.getState();\n\n      if (path.length !== 1 || typeof path[0] !== \"string\") {\n        throw new Error(\"WritableStream stub only supports direct method calls\");\n      }\n\n      const method = path[0];\n\n      if (method !== \"write\" && method !== \"close\" && method !== \"abort\") {\n        args.dispose();\n        throw new Error(`Unknown WritableStream method: ${method}`);\n      }\n\n      // Mark as closed if close() or abort() is called.\n      if (method === \"close\" || method === \"abort\") {\n        state.closed = true;\n      }\n\n      // write(chunk) delivers asynchronously: stubs nested in the chunk must outlive\n      // writer.write() returning. See RpcPayload.deliverStreamWrite().\n      let promise = method === \"write\"\n          ? args.deliverStreamWrite(state.writer)\n          : args.deliverCall(state.writer[method] as Function, state.writer);\n      return new PromiseStubHook(promise.then(payload => new PayloadStubHook(payload)));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    // WritableStreams don't support map operations.\n    for (let cap of captures) {\n      cap.dispose();\n    }\n    return new ErrorStubHook(new Error(\"Cannot use map() on a WritableStream\"));\n  }\n\n  get(path: PropertyPath): StubHook {\n    // WritableStreams don't expose properties over RPC.\n    return new ErrorStubHook(new Error(\"Cannot access properties on a WritableStream stub\"));\n  }\n\n  dup(): StubHook {\n    let state = this.getState();\n    return new WritableStreamStubHook(state, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // WritableStreams can't be pulled - they're not promises.\n    return Promise.reject(new Error(\"Cannot pull a WritableStream stub\"));\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    let state = this.state;\n    this.state = undefined;\n    if (state) {\n      if (--state.refcount === 0) {\n        if (!state.closed) {\n          // Abort the stream if not cleanly closed.\n          state.writer.abort(new Error(\"WritableStream RPC stub was disposed without calling close()\"))\n              .catch(() => {});  // Ignore errors from abort.\n        }\n        state.writer.releaseLock();\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // WritableStream stubs don't really have a \"broken\" state in the same way.\n    // The caller would notice when write/close/abort fails.\n  }\n}\n\n// =======================================================================================\n// FlowController - BDP-based dynamic flow control for stream writes\n//\n// Estimates the bandwidth-delay product (BDP) of a stream by observing write sends and acks,\n// and dynamically adjusts the window size to match. The window is set to the estimated BDP\n// multiplied by a growth factor, so that the sender always pushes slightly more than the\n// estimated capacity — naturally probing for increased bandwidth.\n//\n// The algorithm works in two phases:\n// - Startup: The window is allowed to double each RTT (STARTUP_GROWTH_FACTOR = 2), enabling\n//   rapid discovery of available bandwidth. Startup ends when the window stops growing\n//   meaningfully for STARTUP_EXIT_ROUNDS consecutive RTT rounds.\n// - Steady state: The window grows by at most STEADY_GROWTH_FACTOR (1.25) per RTT and\n//   shrinks by at most DECAY_FACTOR (0.90) per RTT, providing stability.\n\n// Flow control constants — tunable.\n//\n// Initial window size in bytes. Used before we have any bandwidth estimate.\nconst INITIAL_WINDOW = 256 * 1024;\n// Maximum window size in bytes.\nconst MAX_WINDOW = 1024 * 1024 * 1024;\n// Minimum window size in bytes.\nconst MIN_WINDOW = 64 * 1024;\n// During startup, we allow the window to grow by up to this factor per RTT.\nconst STARTUP_GROWTH_FACTOR = 2;\n// In steady state, we allow the window to grow by up to this factor per RTT.\nconst STEADY_GROWTH_FACTOR = 1.25;\n// Allowed reduction in window size per RTT.\nconst DECAY_FACTOR = 0.90;\n// Number of consecutive non-increasing ack rounds before exiting startup.\nconst STARTUP_EXIT_ROUNDS = 3;\n\n// Opaque token returned by onSend() that must be passed back to onAck(). Carries the\n// send-time snapshot needed to compute delivery rate and apply the window collar.\nexport type SendToken = {\n  sentTime: number;\n  size: number;\n  deliveredAtSend: number;\n  deliveredTimeAtSend: number;\n  windowAtSend: number;\n  windowFullAtSend: boolean;\n};\n\n// Exported for testing purposes only -- otherwise this is only used internally by\n// createWritableStreamFromHook().\nexport class FlowController {\n  // The current window size in bytes. The sender blocks when bytesInFlight >= window.\n  window = INITIAL_WINDOW;\n\n  // Total bytes currently in flight (sent but not yet acked).\n  bytesInFlight = 0;\n\n  // Whether we're still in the startup phase.\n  inStartupPhase = true;\n\n  // ----- BDP estimation state (private) -----\n\n  // Total bytes acked so far.\n  private delivered = 0;\n  // Time of most recent ack.\n  private deliveredTime = 0;\n  // Time when the very first ack was received.\n  private firstAckTime = 0;\n  private firstAckDelivered = 0;\n  // Global minimum RTT observed (milliseconds).\n  private minRtt = Infinity;\n\n  // For startup exit: count of consecutive RTT rounds where the window didn't meaningfully grow.\n  private roundsWithoutIncrease = 0;\n  // Window size at the start of the current round, for startup exit detection.\n  private lastRoundWindow = 0;\n  // Time when the current round started.\n  private roundStartTime = 0;\n\n  constructor(private now: () => number) {}\n\n  // Called when a write of `size` bytes is about to be sent. Returns a token that must be\n  // passed to onAck() when the ack arrives, and whether the sender should block (window full).\n  onSend(size: number): { token: SendToken, shouldBlock: boolean } {\n    this.bytesInFlight += size;\n\n    let token: SendToken = {\n      sentTime: this.now(),\n      size,\n      deliveredAtSend: this.delivered,\n      deliveredTimeAtSend: this.deliveredTime,\n      windowAtSend: this.window,\n      windowFullAtSend: this.bytesInFlight >= this.window,\n    };\n\n    return { token, shouldBlock: token.windowFullAtSend };\n  }\n\n  // Called when a previously-sent write fails. Restores bytesInFlight without updating\n  // any BDP estimates.\n  onError(token: SendToken): void {\n    this.bytesInFlight -= token.size;\n  }\n\n  // Called when an ack is received for a previously-sent write. Updates BDP estimates and\n  // the window. Returns whether a blocked sender should now unblock.\n  onAck(token: SendToken): boolean {\n    let ackTime = this.now();\n\n    // Update delivery tracking metrics.\n    this.delivered += token.size;\n    this.deliveredTime = ackTime;\n    this.bytesInFlight -= token.size;\n\n    // Update RTT estimate.\n    let rtt = ackTime - token.sentTime;\n    this.minRtt = Math.min(this.minRtt, rtt);\n\n    // Update bandwidth estimate and window.\n    if (this.firstAckTime === 0) {\n      // This is the very first ack. We can't estimate bandwidth yet since we need to look\n      // at the interval between acks.\n      this.firstAckTime = ackTime;\n      this.firstAckDelivered = this.delivered;\n    } else {\n      let baseTime;\n      let baseDelivered;\n\n      if (token.deliveredTimeAtSend === 0) {\n        // This write was sent before any acks had been received, but wasn't the very first\n        // write. We can estimate bandwidth starting from the first ack.\n        baseTime = this.firstAckTime;\n        baseDelivered = this.firstAckDelivered;\n      } else {\n        baseTime = token.deliveredTimeAtSend;\n        baseDelivered = token.deliveredAtSend;\n      }\n\n      let interval = ackTime - baseTime;\n      let bytes = this.delivered - baseDelivered;\n      let bandwidth = bytes / interval;\n\n      // Choose our target growth factor depending on whether we're at startup or steady\n      // state.\n      let growthFactor = this.inStartupPhase ? STARTUP_GROWTH_FACTOR : STEADY_GROWTH_FACTOR;\n\n      // Calculate new window to be our calculated bandwidth-delay product, plus a growth\n      // factor to account for the possibility that bandwidth is constrained only due to\n      // the window having been too small.\n      let newWindow = bandwidth * this.minRtt * growthFactor;\n\n      // Don't allow the window to grow too quickly -- it can only grow by at most\n      // `growthFactor` for each RTT.\n      newWindow = Math.min(newWindow, token.windowAtSend * growthFactor);\n\n      if (token.windowFullAtSend) {\n        // Don't allow the window to shrink too quickly.\n        newWindow = Math.max(newWindow, token.windowAtSend * DECAY_FACTOR);\n      } else {\n        // Don't allow the window to shrink at all if we weren't saturating it -- in this\n        // case the sending app is not fully utilizing the connection, so no backpressure is\n        // needed. We clamp to this.window here, not this.windowAtSend, since we don't want to\n        // undo previous shrinkage, when alternating between sends that saturated and ones that\n        // didn't.\n        newWindow = Math.max(newWindow, this.window);\n      }\n\n      // Clamp to min/max values.\n      this.window = Math.max(Math.min(newWindow, MAX_WINDOW), MIN_WINDOW);\n\n      // Check if the startup phase is done.\n      if (this.inStartupPhase && token.sentTime >= this.roundStartTime) {\n        if (this.window > this.lastRoundWindow * STEADY_GROWTH_FACTOR) {\n          // Saw a significant increase this round, so reset the counter.\n          this.roundsWithoutIncrease = 0;\n        } else {\n          // Window size didn't increase enough this round.\n          if (++this.roundsWithoutIncrease >= STARTUP_EXIT_ROUNDS) {\n            // After three rounds with insufficient increase, exit startup mode.\n            this.inStartupPhase = false;\n          }\n        }\n\n        // Advance to next round.\n        this.roundStartTime = ackTime;\n        this.lastRoundWindow = this.window;\n      }\n    }\n\n    return this.bytesInFlight < this.window;\n  }\n}\n\n// =======================================================================================\n// createWritableStreamFromHook - creates a proxy WritableStream that forwards to a remote hook\n\nfunction createWritableStreamFromHook(hook: StubHook): WritableStream {\n  let pendingError: any = undefined;\n  let hookDisposed = false;\n\n  let fc = new FlowController(() => performance.now());\n\n  // If a previous write blocked waiting for the window to open, this resolver will unblock it.\n  let windowResolve: (() => void) | undefined;\n  let windowReject: ((e: unknown) => void) | undefined;\n\n  const disposeHook = () => {\n    if (!hookDisposed) {\n      hookDisposed = true;\n      hook.dispose();\n    }\n  };\n\n  return new WritableStream({\n    write(chunk, controller) {\n      // If we already have an error, fail immediately.\n      if (pendingError !== undefined) {\n        throw pendingError;\n      }\n\n      const payload = RpcPayload.fromAppParams([chunk]);\n      const { promise, size } = hook.stream([\"write\"], payload);\n\n      if (size === undefined) {\n        // Local call — await the promise directly to serialize writes (no overlapping).\n        // We still need to detect errors to set pendingError.\n        return promise.catch((err) => {\n          if (pendingError === undefined) {\n            pendingError = err;\n          }\n          throw err;\n        });\n      } else {\n        // Remote call — use window-based flow control.\n        let { token, shouldBlock } = fc.onSend(size);\n\n        // When the response comes back, update the window size based on BDP estimates.\n        promise.then(() => {\n          let hasCapacity = fc.onAck(token);\n\n          if (hasCapacity && windowResolve) {\n            windowResolve();\n            windowResolve = undefined;\n            windowReject = undefined;\n          }\n        }, (err) => {\n          fc.onError(token);\n          if (pendingError === undefined) {\n            pendingError = err;\n            controller.error(err);\n            disposeHook();\n          }\n          // Unblock any write waiting on backpressure -- reject it so the\n          // stream finishes erroring instead of hanging forever.\n          if (windowReject) {\n            windowReject(err);\n            windowResolve = undefined;\n            windowReject = undefined;\n          }\n        });\n\n        // If we've filled (or exceeded) the window, block until acks free up space.\n        if (shouldBlock) {\n          return new Promise<void>((resolve, reject) => {\n            windowResolve = resolve;\n            windowReject = reject;\n          });\n        }\n      }\n    },\n\n    async close() {\n      if (pendingError !== undefined) {\n        disposeHook();\n        throw pendingError;\n      }\n\n      // Send close(). Per the RPC protocol, if any previous write failed, close() will also\n      // fail with that error -- so there's no need to await pending writes first.\n      const { promise } = hook.stream([\"close\"], RpcPayload.fromAppParams([]));\n\n      try {\n        await promise;\n      } catch (err) {\n        // If a write error was detected (possibly while we were waiting for close()), prefer\n        // throwing that, since the close error is likely just a consequence (e.g. \"can't close\n        // errored stream\").\n        throw pendingError ?? err;\n      } finally {\n        disposeHook();\n      }\n    },\n\n    abort(reason) {\n      if (pendingError !== undefined) {\n        return;\n      }\n\n      pendingError = reason ?? new Error(\"WritableStream was aborted\");\n      if (windowReject) {\n        windowReject(pendingError);\n        windowResolve = undefined;\n        windowReject = undefined;\n      }\n\n      const { promise } = hook.stream([\"abort\"], RpcPayload.fromAppParams([reason]));\n      promise.then(() => disposeHook(), () => disposeHook());\n    }\n  });\n}\n\n// =======================================================================================\n// ReadableStreamStubHook - wraps a local ReadableStream for disposal tracking\n//\n// This hook exists solely to live in RpcPayload.hooks so that the ReadableStream is properly\n// disposed (canceled) when the payload is disposed. It does not handle any RPC operations --\n// the actual data transfer is handled by pumping the stream into a pipe's WritableStream via\n// pipeTo(). All methods other than dispose(), dup(), and ignoreUnhandledRejections() throw errors.\n\n// Many ReadableStreamStubHooks could point at the same ReadableStream. We store a refcount in a\n// separate object that they all share.\ntype BoxedReadableState = {\n  refcount: number;\n  stream: ReadableStream;\n  canceled: boolean;\n};\n\nclass ReadableStreamStubHook extends StubHook {\n  private state?: BoxedReadableState;  // undefined when disposed\n\n  // Creates a new ReadableStreamStubHook.\n  static create(stream: ReadableStream): ReadableStreamStubHook {\n    return new ReadableStreamStubHook({ refcount: 1, stream, canceled: false });\n  }\n\n  private constructor(state: BoxedReadableState, dupFrom?: ReadableStreamStubHook) {\n    super();\n    this.state = state;\n    if (dupFrom) {\n      ++state.refcount;\n    }\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    args.dispose();\n    return new ErrorStubHook(new Error(\"Cannot call methods on a ReadableStream stub\"));\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    for (let cap of captures) {\n      cap.dispose();\n    }\n    return new ErrorStubHook(new Error(\"Cannot use map() on a ReadableStream\"));\n  }\n\n  get(path: PropertyPath): StubHook {\n    return new ErrorStubHook(new Error(\"Cannot access properties on a ReadableStream stub\"));\n  }\n\n  dup(): StubHook {\n    let state = this.state;\n    if (!state) {\n      throw new Error(\"Attempted to dup a ReadableStreamStubHook after it was disposed.\");\n    }\n    return new ReadableStreamStubHook(state, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    return Promise.reject(new Error(\"Cannot pull a ReadableStream stub\"));\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    let state = this.state;\n    this.state = undefined;\n    if (state) {\n      if (--state.refcount === 0) {\n        if (!state.canceled) {\n          state.canceled = true;\n\n          // Don't try to cancel the stream if it's locked. It won't work anyway -- it'll throw\n          // an exception, which we'd ignore anyway.\n          //\n          // This is a little janky but it makes some sense: If someone has locked the stream, they\n          // have taken responsibility for fully reading it. The only reason we really need to\n          // cancel when this hook is disposed is to handle the case where an application receives\n          // a ReadableStream but completely ignores it -- we want it to be canceled naturally when\n          // the payload is disposed.\n          if (!state.stream.locked) {\n            state.stream.cancel(\n                new Error(\"ReadableStream RPC stub was disposed without being consumed\"))\n                .catch(() => {});  // Ignore errors from cancel.\n          }\n        }\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // ReadableStream stubs don't have a \"broken\" state.\n  }\n}\n\n// =======================================================================================\n// Install the implementations into streamImpl\n\nstreamImpl.createWritableStreamHook = WritableStreamStubHook.create;\nstreamImpl.createWritableStreamFromHook = createWritableStreamFromHook;\nstreamImpl.createReadableStreamHook = ReadableStreamStubHook.create;\n\nexport function forceInitStreams() {}\n","// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcTarget as RpcTargetImpl, RpcStub as RpcStubImpl, RpcPromise as RpcPromiseImpl, type RpcCallInfo } from \"./core.js\";\nimport { serialize, deserialize, EncodingLevel } from \"./serialize.js\";\nimport { RpcTransport, RpcTransportWithCustomEncoding, AnyRpcTransport, RpcSession as RpcSessionImpl, RpcSessionOptions } from \"./rpc.js\";\nimport { RpcLimits, DEFAULT_LIMITS, DEFAULT_MAX_DEPTH } from \"./serialize.js\";\nimport { RpcTargetBranded, RpcCompatible, Stub, Stubify, __RPC_TARGET_BRAND } from \"./types.js\";\nimport { newWebSocketRpcSession as newWebSocketRpcSessionImpl,\n         newWorkersWebSocketRpcResponse, WebSocketTransport } from \"./websocket.js\";\nimport { newHttpBatchRpcSession as newHttpBatchRpcSessionImpl,\n         newHttpBatchRpcResponse, nodeHttpBatchRpcResponse } from \"./batch.js\";\nimport { newMessagePortRpcSession as newMessagePortRpcSessionImpl } from \"./messageport.js\";\nimport { forceInitMap } from \"./map.js\";\nimport { forceInitStreams } from \"./streams.js\";\n\nforceInitMap();\nforceInitStreams();\n\n// Re-export public API types.\nexport { serialize, deserialize, newWorkersWebSocketRpcResponse, newHttpBatchRpcResponse,\n         nodeHttpBatchRpcResponse, WebSocketTransport, DEFAULT_LIMITS, DEFAULT_MAX_DEPTH };\nexport type { RpcCallInfo, RpcTransport, RpcTransportWithCustomEncoding, AnyRpcTransport,\n         RpcSessionOptions, RpcCompatible, EncodingLevel, RpcLimits };\n\n// Hack the type system to make RpcStub's types work nicely!\n/**\n * Represents a reference to a remote object, on which methods may be remotely invoked via RPC.\n *\n * `RpcStub` can represent any interface (when using TypeScript, you pass the specific interface\n * type as `T`, but this isn't known at runtime). The way this works is, `RpcStub` is actually a\n * `Proxy`. It makes itself appear as if every possible method / property name is defined. You can\n * invoke any method name, and the invocation will be sent to the server. If it turns out that no\n * such method exists on the remote object, an exception is thrown back. But the client does not\n * actually know, until that point, what methods exist.\n */\nexport type RpcStub<T extends RpcCompatible<T>> = Stub<T>;\nexport const RpcStub: {\n  new <T extends RpcCompatible<T>>(value: T): RpcStub<T>;\n} = <any>RpcStubImpl;\n\n/**\n * Represents the result of an RPC call.\n *\n * Also used to represent properties. That is, `stub.foo` evaluates to an `RpcPromise` for the\n * value of `foo`.\n *\n * This isn't actually a JavaScript `Promise`. It does, however, have `then()`, `catch()`, and\n * `finally()` methods, like `Promise` does, and because it has a `then()` method, JavaScript will\n * allow you to treat it like a promise, e.g. you can `await` it.\n *\n * An `RpcPromise` is also a proxy, just like `RpcStub`, where calling methods or awaiting\n * properties will make a pipelined network request.\n *\n * Note that and `RpcPromise` is \"lazy\": the actual final result is not requested from the server\n * until you actually `await` the promise (or call `then()`, etc. on it). This is an optimization:\n * if you only intend to use the promise for pipelining and you never await it, then there's no\n * need to transmit the resolution!\n */\nexport type RpcPromise<T extends RpcCompatible<T>> = Stub<T> & Promise<Stubify<T>>;\nexport const RpcPromise: {\n  // Note: Cannot construct directly!\n} = <any>RpcPromiseImpl;\n\n/**\n * Use to construct an `RpcSession` on top of a custom `RpcTransport`.\n *\n * Most people won't use this. You only need it if you've implemented your own `RpcTransport`.\n */\nexport interface RpcSession<T extends RpcCompatible<T> = undefined> {\n  getRemoteMain(): RpcStub<T>;\n  getStats(): {imports: number, exports: number};\n\n  // Waits until the peer is not waiting on any more promise resolutions from us. This is useful\n  // in particular to decide when a batch is complete.\n  drain(): Promise<void>;\n}\nexport const RpcSession: {\n  new <T extends RpcCompatible<T> = undefined>(\n      transport: AnyRpcTransport, localMain?: any, options?: RpcSessionOptions): RpcSession<T>;\n} = <any>RpcSessionImpl;\n\n// RpcTarget needs some hackage too to brand it properly and account for the implementation\n// conditionally being imported from \"cloudflare:workers\".\n/**\n * Classes which are intended to be passed by reference and called over RPC must extend\n * `RpcTarget`. A class which does not extend `RpcTarget` (and which doesn't have built-in support\n * from the RPC system) cannot be passed in an RPC message at all; an exception will be thrown.\n *\n * Note that on Cloudflare Workers, this `RpcTarget` is an alias for the one exported from the\n * \"cloudflare:workers\" module, so they can be used interchangably.\n */\nexport interface RpcTarget extends RpcTargetBranded {};\nexport const RpcTarget: {\n  new(): RpcTarget;\n} = RpcTargetImpl;\n\n/**\n * Empty interface used as default type parameter for sessions where the other side doesn't\n * necessarily export a main interface.\n */\ninterface Empty {}\n\n/**\n * Start a WebSocket session given either an already-open WebSocket or a URL.\n *\n * @param webSocket Either the `wss://` URL to connect to, or an already-open WebSocket object to\n * use.\n * @param localMain The main RPC interface to expose to the peer. Returns a stub for the main\n * interface exposed from the peer.\n */\nexport let newWebSocketRpcSession:<T extends RpcCompatible<T> = Empty>\n    (webSocket: WebSocket | string, localMain?: any, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newWebSocketRpcSessionImpl;\n\n/**\n * Initiate an HTTP batch session from the client side.\n *\n * The parameters to this method have exactly the same signature as `fetch()`, but the return\n * value is an RpcStub. You can customize anything about the request except for the method\n * (it will always be set to POST) and the body (which the RPC system will fill in).\n */\nexport let newHttpBatchRpcSession:<T extends RpcCompatible<T>>\n    (urlOrRequest: string | Request, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newHttpBatchRpcSessionImpl;\n\n/**\n * Initiate an RPC session over a MessagePort, which is particularly useful for communicating\n * between an iframe and its parent frame in a browser context. Each side should call this function\n * on its own end of the MessageChannel.\n */\nexport let newMessagePortRpcSession:<T extends RpcCompatible<T> = Empty>\n    (port: MessagePort, localMain?: any, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newMessagePortRpcSessionImpl;\n\n/**\n * Implements unified handling of HTTP-batch and WebSocket responses for the Cloudflare Workers\n * Runtime.\n *\n * SECURITY WARNING: This function accepts cross-origin requests. If you do not want this, you\n * should validate the `Origin` header before calling this, or use `newHttpBatchRpcSession()` and\n * `newWebSocketRpcSession()` directly with appropriate security measures for each type of request.\n * But if your API uses in-band authorization (i.e. it has an RPC method that takes the user's\n * credentials as parameters and returns the authorized API), then cross-origin requests should\n * be safe.\n */\nexport async function newWorkersRpcResponse(\n    request: Request, localMain: any, options?: RpcSessionOptions) {\n  if (request.method === \"POST\") {\n    let response = await newHttpBatchRpcResponse(request, localMain, options);\n    // Since we're exposing the same API over WebSocket, too, and WebSocket always allows\n    // cross-origin requests, the API necessarily must be safe for cross-origin use (e.g. because\n    // it uses in-band authorization, as recommended in the readme). So, we might as well allow\n    // batch requests to be made cross-origin as well.\n    response.headers.set(\"Access-Control-Allow-Origin\", \"*\");\n    return response;\n  } else if (request.headers.get(\"Upgrade\")?.toLowerCase() === \"websocket\") {\n    return newWorkersWebSocketRpcResponse(request, localMain, options);\n  } else {\n    return new Response(\"This endpoint only accepts POST or WebSocket requests.\", { status: 400 });\n  }\n}\n"],"mappings":"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"}