{
  "version": 3,
  "sources": ["../../../../src/workers/core/dev-registry-proxy.worker.ts", "../../../../src/workers/queues/constants.ts", "../../../../src/workers/core/constants.ts", "../../../../src/workers/core/dev-registry-proxy-shared.worker.ts"],
  "sourcesContent": ["import { WorkerEntrypoint } from \"cloudflare:workers\";\nimport { getQueueServiceName, HEADER_QUEUE_NAME } from \"../queues/constants\";\nimport { CorePaths } from \"./constants\";\nimport {\n\tfindQueueConsumer,\n\tresolveTarget,\n\ttailEventsReplacer,\n\ttailEventsReviver,\n\tworkerNotFoundMessage,\n} from \"./dev-registry-proxy-shared.worker\";\nimport type { WorkerdDebugPortConnector } from \"./dev-registry-proxy-shared.worker\";\n\nexport {\n\tcreateProxyDurableObjectClass,\n\tsetRegistry,\n} from \"./dev-registry-proxy-shared.worker\";\n\nconst HANDLER_RESERVED_KEYS = new Set([\n\t\"alarm\",\n\t\"connect\",\n\t\"self\",\n\t\"tail\",\n\t\"tailStream\",\n\t\"test\",\n\t\"trace\",\n\t\"webSocketClose\",\n\t\"webSocketError\",\n\t\"webSocketMessage\",\n]);\n\ninterface Env {\n\tDEV_REGISTRY_DEBUG_PORT: WorkerdDebugPortConnector;\n}\n\ninterface Props {\n\tservice: string;\n\tentrypoint: string | null;\n\t// User-supplied `props` from the original service binding / tail consumer.\n\t// Forwarded to the remote entrypoint via the debug port so they are\n\t// available as `ctx.props` on the callee.\n\tuserProps?: Record<string, unknown>;\n}\n\nfunction resolve(props: Props, env: Env): Fetcher | null {\n\tconst { service, entrypoint, userProps } = props;\n\tconst target = resolveTarget(service);\n\tif (!target || !target.debugPortAddress) {\n\t\treturn null;\n\t}\n\tconst serviceName =\n\t\tentrypoint === null || entrypoint === \"default\"\n\t\t\t? target.defaultEntrypointService\n\t\t\t: target.userWorkerService;\n\tconst client = env.DEV_REGISTRY_DEBUG_PORT.connect(target.debugPortAddress);\n\treturn client.getEntrypoint(serviceName, entrypoint ?? undefined, userProps);\n}\n\n/**\n * Relays a queue broker's `/message` or `/batch` request to the dev session\n * consuming that queue. The queue name comes from a request header (rather\n * than binding props) because the broker serves every queue in its process\n * through a single binding. Responds with 503 when no running dev session\n * advertises a consumer for the queue, in which case the sending broker drops\n * the message, mirroring the local no-consumer behaviour.\n */\nexport class ExternalQueueProxy extends WorkerEntrypoint<Env> {\n\tfetch(request: Request): Promise<Response> | Response {\n\t\tconst queueName = request.headers.get(HEADER_QUEUE_NAME);\n\t\tif (queueName === null) {\n\t\t\treturn new Response(`Missing \"${HEADER_QUEUE_NAME}\" header`, {\n\t\t\t\tstatus: 400,\n\t\t\t});\n\t\t}\n\n\t\tconst target = findQueueConsumer(queueName);\n\t\tif (target === undefined) {\n\t\t\treturn new Response(\n\t\t\t\t`No Worker consuming queue \"${queueName}\" found in the local dev registry. Make sure the consumer Worker is running locally.`,\n\t\t\t\t{ status: 503 }\n\t\t\t);\n\t\t}\n\n\t\tconst client = this.env.DEV_REGISTRY_DEBUG_PORT.connect(\n\t\t\ttarget.debugPortAddress\n\t\t);\n\t\tconst broker = client.getEntrypoint(getQueueServiceName(queueName));\n\t\tconst headers = new Headers(request.headers);\n\t\theaders.delete(HEADER_QUEUE_NAME);\n\t\treturn broker.fetch(new Request(request, { headers }));\n\t}\n}\n\nexport class ExternalServiceProxy extends WorkerEntrypoint<Env, Props> {\n\t_fetcher: Fetcher | null = null;\n\t_entryFetcher: Fetcher | null = null;\n\n\tconstructor(ctx: ExecutionContext<Props>, env: Env) {\n\t\tsuper(ctx, env);\n\t\tthis._fetcher = resolve(ctx.props, env);\n\n\t\t// Separate connection for scheduled: the debug port's EventDispatcher\n\t\t// doesn't support runScheduled/runAlarm/queue, so we forward via HTTP.\n\t\tconst target = resolveTarget(ctx.props.service);\n\t\tif (target && target.debugPortAddress) {\n\t\t\tconst client = env.DEV_REGISTRY_DEBUG_PORT.connect(\n\t\t\t\ttarget.debugPortAddress\n\t\t\t);\n\t\t\tthis._entryFetcher = client.getEntrypoint(\"core:entry\");\n\t\t}\n\n\t\treturn new Proxy(this, {\n\t\t\tget(target, prop) {\n\t\t\t\tif (Reflect.has(target, prop)) {\n\t\t\t\t\treturn Reflect.get(target, prop);\n\t\t\t\t}\n\t\t\t\tif (typeof prop === \"string\" && HANDLER_RESERVED_KEYS.has(prop)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tif (!target._fetcher) {\n\t\t\t\t\tthrow new Error(workerNotFoundMessage(ctx.props.service));\n\t\t\t\t}\n\t\t\t\treturn Reflect.get(target._fetcher, prop);\n\t\t\t},\n\t\t});\n\t}\n\n\tfetch(request: Request): Promise<Response> | Response {\n\t\tif (!this._fetcher) {\n\t\t\treturn new Response(workerNotFoundMessage(this.ctx.props.service), {\n\t\t\t\tstatus: 503,\n\t\t\t});\n\t\t}\n\t\treturn this._fetcher.fetch(request);\n\t}\n\n\tasync scheduled(controller: ScheduledController) {\n\t\tif (!this._entryFetcher) {\n\t\t\tthrow new Error(workerNotFoundMessage(this.ctx.props.service));\n\t\t}\n\t\tconst params = new URLSearchParams();\n\t\tif (controller.cron) {\n\t\t\tparams.set(\"cron\", controller.cron);\n\t\t}\n\t\tif (controller.scheduledTime) {\n\t\t\tparams.set(\"time\", String(controller.scheduledTime));\n\t\t}\n\t\tconst response = await this._entryFetcher.fetch(\n\t\t\tnew Request(`http://localhost${CorePaths.SCHEDULED}?${params}`, {\n\t\t\t\theaders: { \"MF-Route-Override\": this.ctx.props.service },\n\t\t\t})\n\t\t);\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text();\n\t\t\tthrow new Error(\n\t\t\t\t`Scheduled handler returned HTTP ${response.status}: ${body}`\n\t\t\t);\n\t\t}\n\t}\n\n\t// Forward tail events to the remote worker via RPC.\n\t// Events with rpcMethod===\"tail\" are filtered out to prevent infinite\n\t// recursion (the remote tail() call would itself produce a tail event).\n\ttail(events: TraceItem[]) {\n\t\tif (!this._fetcher) {\n\t\t\treturn;\n\t\t}\n\t\tconst filtered = events.filter(\n\t\t\t(e) => (e.event as { rpcMethod?: string } | null)?.rpcMethod !== \"tail\"\n\t\t);\n\t\tif (filtered.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst serializedEvents = JSON.parse(\n\t\t\t\tJSON.stringify(filtered, tailEventsReplacer),\n\t\t\t\ttailEventsReviver\n\t\t\t);\n\t\t\t// @ts-expect-error .tail is not in the `Fetcher` type but it's a valid RPC call\n\t\t\treturn this._fetcher.tail(serializedEvents);\n\t\t} catch (e) {\n\t\t\tconsole.warn(\n\t\t\t\t`[dev-registry] Failed to forward tail events to \"${\n\t\t\t\t\tthis.ctx.props.service\n\t\t\t\t}\": ${e instanceof Error ? e.message : String(e)}`\n\t\t\t);\n\t\t}\n\t}\n}\n", "export const QueueBindings = {\n\tSERVICE_WORKER_PREFIX: \"MINIFLARE_WORKER_\",\n\tMAYBE_JSON_QUEUE_PRODUCERS: \"MINIFLARE_QUEUE_PRODUCERS\",\n\tMAYBE_JSON_QUEUE_CONSUMERS: \"MINIFLARE_QUEUE_CONSUMERS\",\n\t// Optional service binding to the dev-registry proxy's `ExternalQueueProxy`\n\t// entrypoint, present when the dev registry is enabled for queue brokers.\n\tMAYBE_SERVICE_QUEUE_PROXY: \"MINIFLARE_QUEUE_PROXY\",\n} as const;\n\n// Header carrying the queue name on requests the broker forwards to the\n// dev-registry proxy, which resolves the consumer's process from it.\nexport const HEADER_QUEUE_NAME = \"MF-Queue-Name\";\n\n// Prefix for the workerd service backing a single queue's broker. Note this\n// must match the queues plugin name (\"queues\"), which lives on the Node.js\n// side of the build boundary.\nexport const SERVICE_QUEUE_PREFIX = \"queues:queue\";\n\n// The workerd service name backing a single queue's broker. Producers in other\n// dev sessions resolve a consumer process's broker by this exact name through\n// the dev registry's debug port, so it must be derived in one place rather\n// than reconstructed at each call site.\nexport function getQueueServiceName(queueId: string): string {\n\treturn `${SERVICE_QUEUE_PREFIX}:${queueId}`;\n}\n", "/**\n * Reserved paths for internal Miniflare endpoints.\n *\n * Paths under `/cdn-cgi/local/` are reserved by Cloudflare's network\n * and won't conflict with user routes. Paths under `/__cf_local/` live\n * outside `/cdn-cgi/` so they remain reachable over tunnels.\n */\nexport const CorePaths = {\n\t/** Magic proxy used by getPlatformProxy */\n\tPLATFORM_PROXY: \"/cdn-cgi/local/platform-proxy\",\n\t/** Trigger scheduled event handlers */\n\tSCHEDULED: \"/cdn-cgi/local/scheduled\",\n\t/** Trigger email event handlers */\n\tEMAIL: \"/cdn-cgi/local/email\",\n\t/** Local explorer UI and API */\n\tEXPLORER: \"/cdn-cgi/local/explorer\",\n\t/** Stream video serving endpoint (outside /cdn-cgi/ for tunnel access) */\n\tSTREAM_VIDEO: \"/__cf_local/stream\",\n\t/** Local image delivery endpoint (outside /cdn-cgi/ for tunnel access) */\n\tIMAGE_DELIVERY: \"/__cf_local/imagedelivery\",\n\t/** Public R2 bucket object serving endpoint */\n\tR2_PUBLIC: \"/cdn-cgi/local/r2/public\",\n\t/** S3-compatible API endpoint for local R2 buckets */\n\tR2_S3: \"/cdn-cgi/local/r2/s3\",\n} as const;\n\nexport const CoreHeaders = {\n\tCUSTOM_FETCH_SERVICE: \"MF-Custom-Fetch-Service\",\n\tCUSTOM_NODE_SERVICE: \"MF-Custom-Node-Service\",\n\tORIGINAL_URL: \"MF-Original-URL\",\n\t/**\n\t * Stores the original hostname when using the `upstream` option.\n\t * When requests are proxied to an upstream, the `Host` header is rewritten\n\t * to match the upstream. This header preserves the original hostname\n\t * so Workers can access it if needed.\n\t */\n\tORIGINAL_HOSTNAME: \"MF-Original-Hostname\",\n\tPROXY_SHARED_SECRET: \"MF-Proxy-Shared-Secret\",\n\tDISABLE_PRETTY_ERROR: \"MF-Disable-Pretty-Error\",\n\tERROR_STACK: \"MF-Experimental-Error-Stack\",\n\t/**\n\t * The serialised error, URI-encoded. `workerd` drops response bodies for\n\t * `HEAD` requests, so the body alone cannot carry the error out of the user\n\t * Worker. Producers set this in addition to the body; consumers fall back to\n\t * it whenever the body is unavailable.\n\t */\n\tERROR_STACK_PAYLOAD: \"MF-Experimental-Error-Stack-Payload\",\n\tROUTE_OVERRIDE: \"MF-Route-Override\",\n\tCF_BLOB: \"MF-CF-Blob\",\n\t/** Used by the Vite plugin to pass through the original `sec-fetch-mode` header */\n\tSEC_FETCH_MODE: \"MF-Sec-Fetch-Mode\",\n\n\t// API Proxy\n\tOP_SECRET: \"MF-Op-Secret\",\n\tOP: \"MF-Op\",\n\tOP_TARGET: \"MF-Op-Target\",\n\tOP_KEY: \"MF-Op-Key\",\n\tOP_SYNC: \"MF-Op-Sync\",\n\tOP_STRINGIFIED_SIZE: \"MF-Op-Stringified-Size\",\n\tOP_RESULT_TYPE: \"MF-Op-Result-Type\",\n\tOP_ORIGINAL_URL: \"MF-Op-Original-URL\",\n} as const;\n\nexport const CoreBindings = {\n\tSERVICE_LOOPBACK: \"MINIFLARE_LOOPBACK\",\n\tSERVICE_USER_ROUTE_PREFIX: \"MINIFLARE_USER_ROUTE_\",\n\tSERVICE_USER_FALLBACK: \"MINIFLARE_USER_FALLBACK\",\n\tTEXT_CUSTOM_SERVICE: \"MINIFLARE_CUSTOM_SERVICE\",\n\t// Backs the Images binding (`env.IMAGES`) \u2014 see imagesLocalFetcher.\n\tIMAGES_BINDING_SERVICE: \"MINIFLARE_IMAGES_BINDING_SERVICE\",\n\t// Backs `fetch(url, { cf: { image } })` transforms \u2014 see cfImageLocalFetcher.\n\tIMAGES_FETCH_SERVICE: \"MINIFLARE_IMAGES_FETCH_SERVICE\",\n\tTEXT_UPSTREAM_URL: \"MINIFLARE_UPSTREAM_URL\",\n\tJSON_CF_BLOB: \"CF_BLOB\",\n\tJSON_ROUTES: \"MINIFLARE_ROUTES\",\n\tJSON_LOG_LEVEL: \"MINIFLARE_LOG_LEVEL\",\n\tDURABLE_OBJECT_NAMESPACE_PROXY: \"MINIFLARE_PROXY\",\n\tDATA_PROXY_SECRET: \"MINIFLARE_PROXY_SECRET\",\n\tDATA_PROXY_SHARED_SECRET: \"MINIFLARE_PROXY_SHARED_SECRET\",\n\tTRIGGER_HANDLERS: \"TRIGGER_HANDLERS\",\n\tLOG_REQUESTS: \"LOG_REQUESTS\",\n\tSTRIP_DISABLE_PRETTY_ERROR: \"STRIP_DISABLE_PRETTY_ERROR\",\n\tSERVICE_LOCAL_EXPLORER: \"MINIFLARE_LOCAL_EXPLORER\",\n\tEXPLORER_DISK: \"MINIFLARE_EXPLORER_DISK\",\n\tJSON_LOCAL_EXPLORER_BINDING_MAP: \"LOCAL_EXPLORER_BINDING_MAP\",\n\tJSON_LOCAL_EXPLORER_WORKER_NAMES: \"LOCAL_EXPLORER_WORKER_NAMES\",\n\tJSON_EXPLORER_WORKER_OPTS: \"MINIFLARE_EXPLORER_WORKER_OPTS\",\n\tSERVICE_CACHE: \"MINIFLARE_CACHE\",\n\tSERVICE_DEV_CONTROL: \"MINIFLARE_DEV_CONTROL\",\n\tSERVICE_DEV_REGISTRY_PROXY: \"MINIFLARE_DEV_REGISTRY_PROXY\",\n\tJSON_TELEMETRY_CONFIG: \"MINIFLARE_TELEMETRY_CONFIG\",\n\tDEV_REGISTRY_DEBUG_PORT: \"DEV_REGISTRY_DEBUG_PORT\",\n\tSERVICE_STREAM: \"MINIFLARE_STREAM\",\n\tSERVICE_IMAGES_DELIVERY: \"MINIFLARE_IMAGES_DELIVERY\",\n\tSERVICE_R2_PUBLIC: \"MINIFLARE_R2_PUBLIC\",\n\tSERVICE_R2_S3: \"MINIFLARE_R2_S3\",\n\tSERVICE_OBSERVABILITY_COLLECTOR: \"MINIFLARE_OBSERVABILITY_COLLECTOR\",\n} as const;\n\nexport const ProxyOps = {\n\t// Get the target or a property of the target\n\tGET: \"GET\",\n\t// Get the descriptor for a property of the target\n\tGET_OWN_DESCRIPTOR: \"GET_OWN_DESCRIPTOR\",\n\t// Get the target's own property names\n\tGET_OWN_KEYS: \"GET_OWN_KEYS\",\n\t// Call a method on the target\n\tCALL: \"CALL\",\n\t// Remove the strong reference to the target on the \"heap\", allowing it to be\n\t// garbage collected\n\tFREE: \"FREE\",\n} as const;\nexport const ProxyAddresses = {\n\tGLOBAL: 0, // globalThis\n\tENV: 1, // env\n\tUSER_START: 2,\n} as const;\n\n/**\n * Recovers the serialised error a Worker put in `ERROR_STACK_PAYLOAD`, for the\n * cases where the response body carrying it has been dropped (`HEAD` requests).\n * Returns `null` when the header is absent or malformed, so callers can fall\n * back rather than surfacing a decoding failure as the Worker's error.\n */\nexport function decodeErrorPayload(response: {\n\theaders: { get(name: string): string | null };\n}): string | null {\n\tconst payload = response.headers.get(CoreHeaders.ERROR_STACK_PAYLOAD);\n\tif (payload === null) {\n\t\treturn null;\n\t}\n\ttry {\n\t\treturn decodeURIComponent(payload);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n// ### Proxy Special Cases\n// The proxy supports serialising `Request`/`Response`s for the Cache API. It\n// doesn't support serialising `WebSocket`s though. Rather than attempting this,\n// we call `Fetcher#fetch()` using `dispatchFetch()` directly, using the passed\n// request. This gives us WebSocket support, and is much more efficient, since\n// there's no need to serialise the `Request`/`Response`: we just pass\n// everything to `dispatchFetch()` and return what that gives us.\nexport function isFetcherFetch(targetName: string, key: string) {\n\t// `DurableObject` and `WorkerRpc` are the internal names of `DurableObjectStub`:\n\t// https://github.com/cloudflare/workerd/blob/62b9ceee4c94d2b238692397dc4f604fef84f474/src/workerd/api/actor.h#L86\n\t// https://github.com/cloudflare/workerd/blob/62b9ceee4c94d2b238692397dc4f604fef84f474/src/workerd/api/worker-rpc.h#L30\n\treturn (\n\t\t(targetName === \"Fetcher\" ||\n\t\t\ttargetName === \"DurableObject\" ||\n\t\t\ttargetName === \"WorkerRpc\") &&\n\t\tkey === \"fetch\"\n\t);\n}\n// `R2Object#writeHttpMetadata()` is one of the few functions that mutates its\n// arguments. This would be proxied correctly if the argument were a native\n// target proxy itself, but `Headers` can be constructed in Node. Instead, we\n// respond with the updated headers in the proxy server, then copy them to the\n// original argument on the client.\nexport function isR2ObjectWriteHttpMetadata(targetName: string, key: string) {\n\t// `HeadResult` and `GetResult` are the internal names of `R2Object` and `R2ObjectBody` respectively:\n\t// https://github.com/cloudflare/workerd/blob/ae612f0563d864c82adbfa4c2e5ed78b547aa0a1/src/workerd/api/r2-bucket.h#L210\n\t// https://github.com/cloudflare/workerd/blob/ae612f0563d864c82adbfa4c2e5ed78b547aa0a1/src/workerd/api/r2-bucket.h#L263-L264\n\treturn (\n\t\t(targetName === \"HeadResult\" || targetName === \"GetResult\") &&\n\t\tkey === \"writeHttpMetadata\"\n\t);\n}\n\n/**\n * See #createMediaProxy() comment for why this is special\n */\nexport function isImagesInput(targetName: string, key: string) {\n\treturn targetName === \"ImagesBindingImpl\" && key === \"input\";\n}\n\n// Durable Object stub RPC calls should always be async to avoid blocking the\n// Node.js event loop. The internal names are \"DurableObject\" and \"WorkerRpc\".\n// https://github.com/cloudflare/workerd/blob/62b9ceee/src/workerd/api/actor.h#L86\n// https://github.com/cloudflare/workerd/blob/62b9ceee/src/workerd/api/worker-rpc.h#L30\nexport function isDurableObjectStub(targetName: string) {\n\treturn targetName === \"DurableObject\" || targetName === \"WorkerRpc\";\n}\n", "import { DurableObject } from \"cloudflare:workers\";\n\n/**\n * Represents the workerd debug port's ability to open connections to other\n * workerd instances by address. Mirrors the Cap'n Proto RPC interface exposed\n * by the workerd debug port.\n *\n * @see https://github.com/cloudflare/workerd/blob/main/src/workerd/server/server.c++\n */\nexport interface WorkerdDebugPortConnector {\n\tconnect(address: string): WorkerdDebugPortClient;\n}\n\n/**\n * A connected debug port client that can resolve service entrypoints and\n * Durable Object actors on a remote workerd instance.\n */\nexport interface WorkerdDebugPortClient {\n\tgetEntrypoint(\n\t\tservice: string,\n\t\tentrypoint?: string,\n\t\tprops?: Record<string, unknown>\n\t): Fetcher;\n\tgetActor(service: string, entrypoint: string, actorId: string): Fetcher;\n}\n\n/**\n * A dev registry entry describing how to reach a worker's debug port and\n * which workerd services correspond to its default entrypoint and user code.\n */\nexport interface RegistryEntry {\n\tdebugPortAddress: string;\n\tdefaultEntrypointService: string;\n\tuserWorkerService: string;\n\t/** Queue names consumed by this worker, if any. */\n\tqueueConsumers?: string[];\n}\n\nlet registry = new Map<string, RegistryEntry>();\n\n/**\n * Replace the in-memory registry with the given entries.\n * Called whenever the Node.js side pushes an updated registry snapshot.\n */\nexport function setRegistry(data: Record<string, RegistryEntry>): void {\n\tregistry = new Map(Object.entries(data));\n}\n\n/**\n * Look up a worker's registry entry by service name.\n */\nexport function resolveTarget(service: string): RegistryEntry | undefined {\n\tconst entry = registry.get(service);\n\tif (!entry || !(\"debugPortAddress\" in entry)) {\n\t\treturn undefined;\n\t}\n\treturn entry;\n}\n\n/**\n * Find the registry entry of a worker that consumes the given queue, if any\n * dev session advertises one. Each queue has at most one consumer, so the\n * first match wins.\n */\nexport function findQueueConsumer(\n\tqueueName: string\n): RegistryEntry | undefined {\n\tfor (const entry of registry.values()) {\n\t\tif (\n\t\t\tArray.isArray(entry.queueConsumers) &&\n\t\t\tentry.queueConsumers.includes(queueName) &&\n\t\t\tentry.debugPortAddress\n\t\t) {\n\t\t\treturn entry;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Check whether a registry entry exists for the given service, even if it's\n * from an incompatible wrangler version.\n */\nexport function hasRegistryEntry(service: string): boolean {\n\treturn registry.has(service);\n}\n\n/**\n * Return an appropriate error message for a worker that can't be resolved.\n */\nexport function workerNotFoundMessage(service: string): string {\n\tif (hasRegistryEntry(service)) {\n\t\treturn `Worker \"${service}\" is not compatible with this version of the dev server. Please update all Worker instances to the same version.`;\n\t}\n\treturn `Worker \"${service}\" not found. Make sure it is running locally.`;\n}\n\n/**\n * Connect to a Durable Object actor on a remote workerd instance via the\n * debug port, returning a {@link Fetcher} that proxies requests to it.\n */\nexport function connectToActor(\n\tdebugPort: WorkerdDebugPortConnector,\n\tscriptName: string,\n\tclassName: string,\n\tactorId: string\n): Fetcher | null {\n\tconst target = resolveTarget(scriptName);\n\tif (!target || !target.debugPortAddress) {\n\t\treturn null;\n\t}\n\tconst client = debugPort.connect(target.debugPortAddress);\n\treturn client.getActor(target.userWorkerService, className, actorId);\n}\n\n/**\n * Create a {@link DurableObject} subclass that proxies all method calls\n * and fetch requests to a Durable Object running in a separate workerd\n * instance via the debug port RPC. Uses a {@link Proxy} to forward\n * arbitrary RPC method calls to the remote actor's {@link Fetcher}.\n */\nexport function createProxyDurableObjectClass({\n\tscriptName,\n\tclassName,\n}: {\n\tscriptName: string;\n\tclassName: string;\n}): typeof DurableObject {\n\treturn class extends DurableObject<{\n\t\tDEV_REGISTRY_DEBUG_PORT: WorkerdDebugPortConnector;\n\t}> {\n\t\t_cachedFetcher: Fetcher | undefined;\n\t\t_cachedDebugPortAddress: string | undefined;\n\n\t\t// Lazily resolve and cache. Invalidates when debugPortAddress changes.\n\t\t_resolve(): Fetcher | null {\n\t\t\tconst target = resolveTarget(scriptName);\n\t\t\tif (\n\t\t\t\tthis._cachedFetcher &&\n\t\t\t\ttarget?.debugPortAddress === this._cachedDebugPortAddress\n\t\t\t) {\n\t\t\t\treturn this._cachedFetcher;\n\t\t\t}\n\t\t\tthis._cachedFetcher = undefined;\n\t\t\tthis._cachedDebugPortAddress = undefined;\n\n\t\t\tconst fetcher = connectToActor(\n\t\t\t\tthis.env.DEV_REGISTRY_DEBUG_PORT,\n\t\t\t\tscriptName,\n\t\t\t\tclassName,\n\t\t\t\tthis.ctx.id.toString()\n\t\t\t);\n\t\t\tif (fetcher && target) {\n\t\t\t\tthis._cachedFetcher = fetcher;\n\t\t\t\tthis._cachedDebugPortAddress = target.debugPortAddress;\n\t\t\t}\n\t\t\treturn fetcher;\n\t\t}\n\n\t\tconstructor(\n\t\t\tctx: DurableObjectState,\n\t\t\tenv: { DEV_REGISTRY_DEBUG_PORT: WorkerdDebugPortConnector }\n\t\t) {\n\t\t\tsuper(ctx, env);\n\n\t\t\treturn new Proxy(this, {\n\t\t\t\tget(target, prop) {\n\t\t\t\t\tif (Reflect.has(target, prop)) {\n\t\t\t\t\t\treturn Reflect.get(target, prop);\n\t\t\t\t\t}\n\t\t\t\t\tconst fetcher = target._resolve();\n\t\t\t\t\tif (!fetcher) {\n\t\t\t\t\t\t// Return a function-that-throws rather than throwing immediately:\n\t\t\t\t\t\t// workerd probes DO properties (fetch, alarm, etc.) via the get\n\t\t\t\t\t\t// trap, and throwing here would crash those internal checks.\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tthrow new Error(workerNotFoundMessage(scriptName));\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn Reflect.get(fetcher, prop);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tfetch(request: Request): Promise<Response> {\n\t\t\tconst fetcher = this._resolve();\n\t\t\tif (!fetcher) {\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tnew Response(workerNotFoundMessage(scriptName), { status: 503 })\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn fetcher.fetch(request);\n\t\t}\n\t} as unknown as typeof DurableObject;\n}\n\nconst SERIALIZED_DATE = \"___serialized_date___\";\nconst SERIALIZED_BIGINT = \"___serialized_bigint___\";\n\n/**\n * JSON replacer that serializes `Date` and `bigint` values into tagged\n * objects so they survive a JSON round-trip in tail event forwarding.\n */\nexport function tailEventsReplacer(_: string, value: any) {\n\tif (value instanceof Date) {\n\t\treturn { [SERIALIZED_DATE]: value.toISOString() };\n\t} else if (typeof value === \"bigint\") {\n\t\treturn { [SERIALIZED_BIGINT]: value.toString() };\n\t}\n\treturn value;\n}\n\n/**\n * JSON reviver that restores `Date` and `bigint` values from the tagged\n * objects produced by {@link tailEventsReplacer}.\n */\nexport function tailEventsReviver(_: string, value: any) {\n\tif (value && typeof value === \"object\") {\n\t\tif (SERIALIZED_DATE in value) {\n\t\t\treturn new Date(value[SERIALIZED_DATE]);\n\t\t} else if (SERIALIZED_BIGINT in value) {\n\t\t\treturn BigInt(value[SERIALIZED_BIGINT]);\n\t\t}\n\t}\n\treturn value;\n}\n"],
  "mappings": "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",
  "names": ["target"]
}
