@rivetkit/cloudflare-workers 2.0.24-rc.1 → 2.0.25-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mod.cjs +669 -303
- package/dist/mod.cjs.map +1 -1
- package/dist/mod.d.cts +67 -27
- package/dist/mod.d.ts +67 -27
- package/dist/mod.js +675 -309
- package/dist/mod.js.map +1 -1
- package/package.json +2 -2
- package/src/actor-driver.ts +211 -47
- package/src/actor-handler-do.ts +306 -71
- package/src/actor-id.ts +38 -0
- package/src/actor-kv.ts +71 -0
- package/src/global-kv.ts +6 -0
- package/src/handler.ts +48 -9
- package/src/manager-driver.ts +143 -116
- package/src/mod.ts +8 -1
package/dist/mod.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/cloudflare-workers/dist/mod.cjs","../src/handler.ts","../src/actor-handler-do.ts","../src/actor-driver.ts","../src/log.ts","../src/config.ts","../src/manager-driver.ts","../src/util.ts","../src/websocket.ts"],"names":["promiseWithResolvers","invariant","env","_a","ActorHandler"],"mappings":"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","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/cloudflare-workers/dist/mod.cjs","sourcesContent":[null,"import { env } from \"cloudflare:workers\";\nimport type { Registry, RunConfig } from \"rivetkit\";\nimport {\n\ttype ActorHandlerInterface,\n\tcreateActorDurableObject,\n\ttype DurableObjectConstructor,\n} from \"./actor-handler-do\";\nimport { ConfigSchema, type InputConfig } from \"./config\";\nimport { CloudflareActorsManagerDriver } from \"./manager-driver\";\nimport { upgradeWebSocket } from \"./websocket\";\n\n/** Cloudflare Workers env */\nexport interface Bindings {\n\tACTOR_KV: KVNamespace;\n\tACTOR_DO: DurableObjectNamespace<ActorHandlerInterface>;\n}\n\n/**\n * Stores the env for the current request. Required since some contexts like the inline client driver does not have access to the Hono context.\n *\n * Use getCloudflareAmbientEnv unless using CF_AMBIENT_ENV.run.\n */\nexport function getCloudflareAmbientEnv(): Bindings {\n\treturn env as unknown as Bindings;\n}\n\ninterface Handler {\n\thandler: ExportedHandler<Bindings>;\n\tActorHandler: DurableObjectConstructor;\n}\n\nexport function createHandler<R extends Registry<any>>(\n\tregistry: R,\n\tinputConfig?: InputConfig,\n): Handler {\n\t// HACK: Cloudflare does not support using `crypto.randomUUID()` before start, so we pass a default value\n\t//\n\t// Runner key is not used on Cloudflare\n\tinputConfig = { ...inputConfig, runnerKey: \"\" };\n\n\t// Parse config\n\tconst config = ConfigSchema.parse(inputConfig);\n\n\t// Create config\n\tconst runConfig = {\n\t\t...config,\n\t\tdriver: {\n\t\t\tname: \"cloudflare-workers\",\n\t\t\tmanager: () => new CloudflareActorsManagerDriver(),\n\t\t\t// HACK: We can't build the actor driver until we're inside the Durable Object\n\t\t\tactor: undefined as any,\n\t\t},\n\t\tgetUpgradeWebSocket: () => upgradeWebSocket,\n\t} satisfies RunConfig;\n\n\t// Create Durable Object\n\tconst ActorHandler = createActorDurableObject(registry, runConfig);\n\n\t// Create server\n\tconst serverOutput = registry.start(runConfig);\n\n\t// Create Cloudflare handler\n\tconst handler = {\n\t\tfetch: (request, cfEnv, ctx) => {\n\t\t\tconst url = new URL(request.url);\n\n\t\t\t// Inject Rivet env\n\t\t\tconst env = Object.assign({ RIVET: serverOutput.client }, cfEnv);\n\n\t\t\t// Mount Rivet manager API\n\t\t\tif (url.pathname.startsWith(config.managerPath)) {\n\t\t\t\tconst strippedPath = url.pathname.substring(\n\t\t\t\t\tconfig.managerPath.length,\n\t\t\t\t);\n\t\t\t\turl.pathname = strippedPath;\n\t\t\t\tconst modifiedRequest = new Request(url.toString(), request);\n\t\t\t\treturn serverOutput.fetch(modifiedRequest, env, ctx);\n\t\t\t}\n\n\t\t\tif (config.fetch) {\n\t\t\t\treturn config.fetch(request, env, ctx);\n\t\t\t} else {\n\t\t\t\treturn new Response(\n\t\t\t\t\t\"This is a RivetKit server.\\n\\nLearn more at https://rivetkit.org\\n\",\n\t\t\t\t\t{ status: 200 },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t} satisfies ExportedHandler<Bindings>;\n\n\treturn { handler, ActorHandler };\n}\n","import { DurableObject, env } from \"cloudflare:workers\";\nimport type { ExecutionContext } from \"hono\";\nimport invariant from \"invariant\";\nimport type { ActorKey, ActorRouter, Registry, RunConfig } from \"rivetkit\";\nimport { createActorRouter, createClientWithDriver } from \"rivetkit\";\nimport type { ActorDriver } from \"rivetkit/driver-helpers\";\nimport {\n\ttype ManagerDriver,\n\tserializeEmptyPersistData,\n} from \"rivetkit/driver-helpers\";\nimport { promiseWithResolvers } from \"rivetkit/utils\";\nimport {\n\tCloudflareDurableObjectGlobalState,\n\tcreateCloudflareActorsActorDriverBuilder,\n} from \"./actor-driver\";\nimport type { Bindings } from \"./handler\";\nimport { logger } from \"./log\";\n\nexport const KEYS = {\n\tNAME: \"rivetkit:name\",\n\tKEY: \"rivetkit:key\",\n\tPERSIST_DATA: \"rivetkit:data\",\n};\n\nexport interface ActorHandlerInterface extends DurableObject {\n\tinitialize(req: ActorInitRequest): Promise<void>;\n}\n\nexport interface ActorInitRequest {\n\tname: string;\n\tkey: ActorKey;\n\tinput?: unknown;\n}\n\ninterface InitializedData {\n\tname: string;\n\tkey: ActorKey;\n}\n\nexport type DurableObjectConstructor = new (\n\t...args: ConstructorParameters<typeof DurableObject<Bindings>>\n) => DurableObject<Bindings>;\n\ninterface LoadedActor {\n\tactorRouter: ActorRouter;\n\tactorDriver: ActorDriver;\n}\n\nexport function createActorDurableObject(\n\tregistry: Registry<any>,\n\trootRunConfig: RunConfig,\n): DurableObjectConstructor {\n\tconst globalState = new CloudflareDurableObjectGlobalState();\n\n\t// Configure to use the runner role instead of server role\n\tconst runConfig = Object.assign({}, rootRunConfig, { role: \"runner\" });\n\n\t/**\n\t * Startup steps:\n\t * 1. If not already created call `initialize`, otherwise check KV to ensure it's initialized\n\t * 2. Load actor\n\t * 3. Start service requests\n\t */\n\treturn class ActorHandler\n\t\textends DurableObject<Bindings>\n\t\timplements ActorHandlerInterface\n\t{\n\t\t#initialized?: InitializedData;\n\t\t#initializedPromise?: ReturnType<typeof promiseWithResolvers<void>>;\n\n\t\t#actor?: LoadedActor;\n\n\t\tasync #loadActor(): Promise<LoadedActor> {\n\t\t\t// Wait for init\n\t\t\tif (!this.#initialized) {\n\t\t\t\t// Wait for init\n\t\t\t\tif (this.#initializedPromise) {\n\t\t\t\t\tawait this.#initializedPromise.promise;\n\t\t\t\t} else {\n\t\t\t\t\tthis.#initializedPromise = promiseWithResolvers();\n\t\t\t\t\tconst res = await this.ctx.storage.get([\n\t\t\t\t\t\tKEYS.NAME,\n\t\t\t\t\t\tKEYS.KEY,\n\t\t\t\t\t\tKEYS.PERSIST_DATA,\n\t\t\t\t\t]);\n\t\t\t\t\tif (res.get(KEYS.PERSIST_DATA)) {\n\t\t\t\t\t\tconst name = res.get(KEYS.NAME) as string;\n\t\t\t\t\t\tif (!name) throw new Error(\"missing actor name\");\n\t\t\t\t\t\tconst key = res.get(KEYS.KEY) as ActorKey;\n\t\t\t\t\t\tif (!key) throw new Error(\"missing actor key\");\n\n\t\t\t\t\t\tlogger().debug({\n\t\t\t\t\t\t\tmsg: \"already initialized\",\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis.#initialized = { name, key };\n\t\t\t\t\t\tthis.#initializedPromise.resolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger().debug(\"waiting to initialize\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if already loaded\n\t\t\tif (this.#actor) {\n\t\t\t\treturn this.#actor;\n\t\t\t}\n\n\t\t\tif (!this.#initialized) throw new Error(\"Not initialized\");\n\n\t\t\t// Register DO with global state first\n\t\t\t// HACK: This leaks the DO context, but DO does not provide a native way\n\t\t\t// of knowing when the DO shuts down. We're making a broad assumption\n\t\t\t// that DO will boot a new isolate frequenlty enough that this is not an issue.\n\t\t\tconst actorId = this.ctx.id.toString();\n\t\t\tglobalState.setDOState(actorId, { ctx: this.ctx, env: env });\n\n\t\t\t// Configure actor driver\n\t\t\tinvariant(runConfig.driver, \"runConfig.driver\");\n\t\t\trunConfig.driver.actor =\n\t\t\t\tcreateCloudflareActorsActorDriverBuilder(globalState);\n\n\t\t\t// Create manager driver (we need this for the actor router)\n\t\t\tconst managerDriver = runConfig.driver.manager(\n\t\t\t\tregistry.config,\n\t\t\t\trunConfig,\n\t\t\t);\n\n\t\t\t// Create inline client\n\t\t\tconst inlineClient = createClientWithDriver(\n\t\t\t\tmanagerDriver,\n\t\t\t\trunConfig,\n\t\t\t);\n\n\t\t\t// Create actor driver\n\t\t\tconst actorDriver = runConfig.driver.actor(\n\t\t\t\tregistry.config,\n\t\t\t\trunConfig,\n\t\t\t\tmanagerDriver,\n\t\t\t\tinlineClient,\n\t\t\t);\n\n\t\t\t// Create actor router\n\t\t\tconst actorRouter = createActorRouter(\n\t\t\t\trunConfig,\n\t\t\t\tactorDriver,\n\t\t\t\tfalse,\n\t\t\t);\n\n\t\t\t// Save actor\n\t\t\tthis.#actor = {\n\t\t\t\tactorRouter,\n\t\t\t\tactorDriver,\n\t\t\t};\n\n\t\t\t// Initialize the actor instance with proper metadata\n\t\t\t// This ensures the actor driver knows about this actor\n\t\t\tawait actorDriver.loadActor(actorId);\n\n\t\t\treturn this.#actor;\n\t\t}\n\n\t\t/** RPC called by the service that creates the DO to initialize it. */\n\t\tasync initialize(req: ActorInitRequest) {\n\t\t\t// TODO: Need to add this to a core promise that needs to be resolved before start\n\n\t\t\tawait this.ctx.storage.put({\n\t\t\t\t[KEYS.NAME]: req.name,\n\t\t\t\t[KEYS.KEY]: req.key,\n\t\t\t\t[KEYS.PERSIST_DATA]: serializeEmptyPersistData(req.input),\n\t\t\t});\n\t\t\tthis.#initialized = {\n\t\t\t\tname: req.name,\n\t\t\t\tkey: req.key,\n\t\t\t};\n\n\t\t\tlogger().debug({ msg: \"initialized actor\", key: req.key });\n\n\t\t\t// Preemptively actor so the lifecycle hooks are called\n\t\t\tawait this.#loadActor();\n\t\t}\n\n\t\tasync fetch(request: Request): Promise<Response> {\n\t\t\tconst { actorRouter } = await this.#loadActor();\n\n\t\t\tconst actorId = this.ctx.id.toString();\n\t\t\treturn await actorRouter.fetch(request, {\n\t\t\t\tactorId,\n\t\t\t});\n\t\t}\n\n\t\tasync alarm(): Promise<void> {\n\t\t\tconst { actorDriver } = await this.#loadActor();\n\t\t\tconst actorId = this.ctx.id.toString();\n\n\t\t\t// Load the actor instance and trigger alarm\n\t\t\tconst actor = await actorDriver.loadActor(actorId);\n\t\t\tawait actor._onAlarm();\n\t\t}\n\t};\n}\n","import invariant from \"invariant\";\nimport type {\n\tAnyActorInstance as CoreAnyActorInstance,\n\tRegistryConfig,\n\tRunConfig,\n} from \"rivetkit\";\nimport { lookupInRegistry } from \"rivetkit\";\nimport type { Client } from \"rivetkit/client\";\nimport type {\n\tActorDriver,\n\tAnyActorInstance,\n\tManagerDriver,\n} from \"rivetkit/driver-helpers\";\nimport { promiseWithResolvers } from \"rivetkit/utils\";\nimport { KEYS } from \"./actor-handler-do\";\n\ninterface DurableObjectGlobalState {\n\tctx: DurableObjectState;\n\tenv: unknown;\n}\n\n/**\n * Cloudflare DO can have multiple DO running within the same global scope.\n *\n * This allows for storing the actor context globally and looking it up by ID in `CloudflareActorsActorDriver`.\n */\nexport class CloudflareDurableObjectGlobalState {\n\t// Single map for all actor state\n\t#dos: Map<string, DurableObjectGlobalState> = new Map();\n\n\tgetDOState(actorId: string): DurableObjectGlobalState {\n\t\tconst state = this.#dos.get(actorId);\n\t\tinvariant(\n\t\t\tstate !== undefined,\n\t\t\t\"durable object state not in global state\",\n\t\t);\n\t\treturn state;\n\t}\n\n\tsetDOState(actorId: string, state: DurableObjectGlobalState) {\n\t\tthis.#dos.set(actorId, state);\n\t}\n}\n\nexport interface DriverContext {\n\tstate: DurableObjectState;\n}\n\n// Actor handler to track running instances\nclass ActorHandler {\n\tactor?: AnyActorInstance;\n\tactorPromise?: ReturnType<typeof promiseWithResolvers<void>> =\n\t\tpromiseWithResolvers();\n}\n\nexport class CloudflareActorsActorDriver implements ActorDriver {\n\t#registryConfig: RegistryConfig;\n\t#runConfig: RunConfig;\n\t#managerDriver: ManagerDriver;\n\t#inlineClient: Client<any>;\n\t#globalState: CloudflareDurableObjectGlobalState;\n\t#actors: Map<string, ActorHandler> = new Map();\n\n\tconstructor(\n\t\tregistryConfig: RegistryConfig,\n\t\trunConfig: RunConfig,\n\t\tmanagerDriver: ManagerDriver,\n\t\tinlineClient: Client<any>,\n\t\tglobalState: CloudflareDurableObjectGlobalState,\n\t) {\n\t\tthis.#registryConfig = registryConfig;\n\t\tthis.#runConfig = runConfig;\n\t\tthis.#managerDriver = managerDriver;\n\t\tthis.#inlineClient = inlineClient;\n\t\tthis.#globalState = globalState;\n\t}\n\n\t#getDOCtx(actorId: string) {\n\t\treturn this.#globalState.getDOState(actorId).ctx;\n\t}\n\n\tasync loadActor(actorId: string): Promise<AnyActorInstance> {\n\t\t// Check if actor is already loaded\n\t\tlet handler = this.#actors.get(actorId);\n\t\tif (handler) {\n\t\t\tif (handler.actorPromise) await handler.actorPromise.promise;\n\t\t\tif (!handler.actor) throw new Error(\"Actor should be loaded\");\n\t\t\treturn handler.actor;\n\t\t}\n\n\t\t// Create new actor handler\n\t\thandler = new ActorHandler();\n\t\tthis.#actors.set(actorId, handler);\n\n\t\t// Get the actor metadata from Durable Object storage\n\t\tconst doState = this.#globalState.getDOState(actorId);\n\t\tconst storage = doState.ctx.storage;\n\n\t\t// Load actor metadata\n\t\tconst [name, key] = await Promise.all([\n\t\t\tstorage.get<string>(KEYS.NAME),\n\t\t\tstorage.get<string[]>(KEYS.KEY),\n\t\t]);\n\n\t\tif (!name) {\n\t\t\tthrow new Error(\n\t\t\t\t`Actor ${actorId} is not initialized - missing name`,\n\t\t\t);\n\t\t}\n\t\tif (!key) {\n\t\t\tthrow new Error(\n\t\t\t\t`Actor ${actorId} is not initialized - missing key`,\n\t\t\t);\n\t\t}\n\n\t\t// Create actor instance\n\t\tconst definition = lookupInRegistry(this.#registryConfig, name);\n\t\thandler.actor = definition.instantiate();\n\n\t\t// Start actor\n\t\tawait handler.actor.start(\n\t\t\tthis,\n\t\t\tthis.#inlineClient,\n\t\t\tactorId,\n\t\t\tname,\n\t\t\tkey,\n\t\t\t\"unknown\", // TODO: Support regions in Cloudflare\n\t\t);\n\n\t\t// Finish\n\t\thandler.actorPromise?.resolve();\n\t\thandler.actorPromise = undefined;\n\n\t\treturn handler.actor;\n\t}\n\n\tgetContext(actorId: string): DriverContext {\n\t\tconst state = this.#globalState.getDOState(actorId);\n\t\treturn { state: state.ctx };\n\t}\n\n\tasync readPersistedData(actorId: string): Promise<Uint8Array | undefined> {\n\t\treturn await this.#getDOCtx(actorId).storage.get(KEYS.PERSIST_DATA);\n\t}\n\n\tasync writePersistedData(actorId: string, data: Uint8Array): Promise<void> {\n\t\tawait this.#getDOCtx(actorId).storage.put(KEYS.PERSIST_DATA, data);\n\t}\n\n\tasync setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> {\n\t\tawait this.#getDOCtx(actor.id).storage.setAlarm(timestamp);\n\t}\n\n\tasync getDatabase(actorId: string): Promise<unknown | undefined> {\n\t\treturn this.#getDOCtx(actorId).storage.sql;\n\t}\n}\n\nexport function createCloudflareActorsActorDriverBuilder(\n\tglobalState: CloudflareDurableObjectGlobalState,\n) {\n\treturn (\n\t\tregistryConfig: RegistryConfig,\n\t\trunConfig: RunConfig,\n\t\tmanagerDriver: ManagerDriver,\n\t\tinlineClient: Client<any>,\n\t) => {\n\t\treturn new CloudflareActorsActorDriver(\n\t\t\tregistryConfig,\n\t\t\trunConfig,\n\t\t\tmanagerDriver,\n\t\t\tinlineClient,\n\t\t\tglobalState,\n\t\t);\n\t};\n}\n","import { getLogger } from \"rivetkit/log\";\n\nexport function logger() {\n\treturn getLogger(\"driver-cloudflare-workers\");\n}\n","import type { Client } from \"rivetkit\";\nimport { RunConfigSchema } from \"rivetkit/driver-helpers\";\nimport { z } from \"zod\";\n\nexport const ConfigSchema = RunConfigSchema.removeDefault()\n\t.omit({ driver: true, getUpgradeWebSocket: true })\n\t.extend({\n\t\t/** Path that the Rivet manager API will be mounted. */\n\t\tmanagerPath: z.string().optional().default(\"/rivet\"),\n\n\t\tfetch: z\n\t\t\t.custom<\n\t\t\t\tExportedHandlerFetchHandler<{ RIVET: Client<any> }, unknown>\n\t\t\t>()\n\t\t\t.optional(),\n\t})\n\t.default({});\nexport type InputConfig = z.input<typeof ConfigSchema>;\nexport type Config = z.infer<typeof ConfigSchema>;\n","import type { Context as HonoContext } from \"hono\";\nimport type { Encoding, UniversalWebSocket } from \"rivetkit\";\nimport {\n\ttype ActorOutput,\n\ttype CreateInput,\n\ttype GetForIdInput,\n\ttype GetOrCreateWithKeyInput,\n\ttype GetWithKeyInput,\n\tgenerateRandomString,\n\ttype ManagerDisplayInformation,\n\ttype ManagerDriver,\n\tWS_PROTOCOL_ACTOR,\n\tWS_PROTOCOL_CONN_ID,\n\tWS_PROTOCOL_CONN_PARAMS,\n\tWS_PROTOCOL_CONN_TOKEN,\n\tWS_PROTOCOL_ENCODING,\n\tWS_PROTOCOL_STANDARD,\n\tWS_PROTOCOL_TARGET,\n} from \"rivetkit/driver-helpers\";\nimport { ActorAlreadyExists, InternalError } from \"rivetkit/errors\";\nimport { getCloudflareAmbientEnv } from \"./handler\";\nimport { logger } from \"./log\";\nimport type { Bindings } from \"./mod\";\nimport { serializeKey, serializeNameAndKey } from \"./util\";\n\n// Actor metadata structure\ninterface ActorData {\n\tname: string;\n\tkey: string[];\n}\n\nconst KEYS = {\n\tACTOR: {\n\t\t// Combined key for actor metadata (name and key)\n\t\tmetadata: (actorId: string) => `actor:${actorId}:metadata`,\n\n\t\t// Key index function for actor lookup\n\t\tkeyIndex: (name: string, key: string[] = []) => {\n\t\t\t// Use serializeKey for consistent handling of all keys\n\t\t\treturn `actor_key:${serializeKey(key)}`;\n\t\t},\n\t},\n};\n\nconst STANDARD_WEBSOCKET_HEADERS = [\n\t\"connection\",\n\t\"upgrade\",\n\t\"sec-websocket-key\",\n\t\"sec-websocket-version\",\n\t\"sec-websocket-protocol\",\n\t\"sec-websocket-extensions\",\n];\n\nexport class CloudflareActorsManagerDriver implements ManagerDriver {\n\tasync sendRequest(\n\t\tactorId: string,\n\t\tactorRequest: Request,\n\t): Promise<Response> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\tlogger().debug({\n\t\t\tmsg: \"sending request to durable object\",\n\t\t\tactorId,\n\t\t\tmethod: actorRequest.method,\n\t\t\turl: actorRequest.url,\n\t\t});\n\n\t\tconst id = env.ACTOR_DO.idFromString(actorId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync openWebSocket(\n\t\tpath: string,\n\t\tactorId: string,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t\tconnId?: string,\n\t\tconnToken?: string,\n\t): Promise<UniversalWebSocket> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\tlogger().debug({\n\t\t\tmsg: \"opening websocket to durable object\",\n\t\t\tactorId,\n\t\t\tpath,\n\t\t});\n\n\t\t// Make a fetch request to the Durable Object with WebSocket upgrade\n\t\tconst id = env.ACTOR_DO.idFromString(actorId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\tconst protocols: string[] = [];\n\t\tprotocols.push(WS_PROTOCOL_STANDARD);\n\t\tprotocols.push(`${WS_PROTOCOL_TARGET}actor`);\n\t\tprotocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);\n\t\tprotocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);\n\t\tif (params) {\n\t\t\tprotocols.push(\n\t\t\t\t`${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`,\n\t\t\t);\n\t\t}\n\t\tif (connId) {\n\t\t\tprotocols.push(`${WS_PROTOCOL_CONN_ID}${connId}`);\n\t\t}\n\t\tif (connToken) {\n\t\t\tprotocols.push(`${WS_PROTOCOL_CONN_TOKEN}${connToken}`);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\tUpgrade: \"websocket\",\n\t\t\tConnection: \"Upgrade\",\n\t\t\t\"sec-websocket-protocol\": protocols.join(\", \"),\n\t\t};\n\n\t\t// Use the path parameter to determine the URL\n\t\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\t\tconst url = `http://actor${normalizedPath}`;\n\n\t\tlogger().debug({ msg: \"rewriting websocket url\", from: path, to: url });\n\n\t\tconst response = await stub.fetch(url, {\n\t\t\theaders,\n\t\t});\n\t\tconst webSocket = response.webSocket;\n\n\t\tif (!webSocket) {\n\t\t\tthrow new InternalError(\n\t\t\t\t`missing websocket connection in response from DO\\n\\nStatus: ${response.status}\\nResponse: ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tlogger().debug({\n\t\t\tmsg: \"durable object websocket connection open\",\n\t\t\tactorId,\n\t\t});\n\n\t\twebSocket.accept();\n\n\t\t// TODO: Is this still needed?\n\t\t// HACK: Cloudflare does not call onopen automatically, so we need\n\t\t// to call this on the next tick\n\t\tsetTimeout(() => {\n\t\t\tconst event = new Event(\"open\");\n\t\t\t(webSocket as any).onopen?.(event);\n\t\t\t(webSocket as any).dispatchEvent(event);\n\t\t}, 0);\n\n\t\treturn webSocket as unknown as UniversalWebSocket;\n\t}\n\n\tasync proxyRequest(\n\t\tc: HonoContext<{ Bindings: Bindings }>,\n\t\tactorRequest: Request,\n\t\tactorId: string,\n\t): Promise<Response> {\n\t\tlogger().debug({\n\t\t\tmsg: \"forwarding request to durable object\",\n\t\t\tactorId,\n\t\t\tmethod: actorRequest.method,\n\t\t\turl: actorRequest.url,\n\t\t});\n\n\t\tconst id = c.env.ACTOR_DO.idFromString(actorId);\n\t\tconst stub = c.env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync proxyWebSocket(\n\t\tc: HonoContext<{ Bindings: Bindings }>,\n\t\tpath: string,\n\t\tactorId: string,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t): Promise<Response> {\n\t\tlogger().debug({\n\t\t\tmsg: \"forwarding websocket to durable object\",\n\t\t\tactorId,\n\t\t\tpath,\n\t\t});\n\n\t\t// Validate upgrade\n\t\tconst upgradeHeader = c.req.header(\"Upgrade\");\n\t\tif (!upgradeHeader || upgradeHeader !== \"websocket\") {\n\t\t\treturn new Response(\"Expected Upgrade: websocket\", {\n\t\t\t\tstatus: 426,\n\t\t\t});\n\t\t}\n\n\t\tconst newUrl = new URL(`http://actor${path}`);\n\t\tconst actorRequest = new Request(newUrl, c.req.raw);\n\n\t\tlogger().debug({\n\t\t\tmsg: \"rewriting websocket url\",\n\t\t\tfrom: c.req.url,\n\t\t\tto: actorRequest.url,\n\t\t});\n\n\t\t// Always build fresh request to prevent forwarding unwanted headers\n\t\t// HACK: Since we can't build a new request, we need to remove\n\t\t// non-standard headers manually\n\t\tconst headerKeys: string[] = [];\n\t\tactorRequest.headers.forEach((v, k) => {\n\t\t\theaderKeys.push(k);\n\t\t});\n\t\tfor (const k of headerKeys) {\n\t\t\tif (!STANDARD_WEBSOCKET_HEADERS.includes(k)) {\n\t\t\t\tactorRequest.headers.delete(k);\n\t\t\t}\n\t\t}\n\n\t\t// Build protocols for WebSocket connection\n\t\tconst protocols: string[] = [];\n\t\tprotocols.push(WS_PROTOCOL_STANDARD);\n\t\tprotocols.push(`${WS_PROTOCOL_TARGET}actor`);\n\t\tprotocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);\n\t\tprotocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);\n\t\tif (params) {\n\t\t\tprotocols.push(\n\t\t\t\t`${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`,\n\t\t\t);\n\t\t}\n\t\tactorRequest.headers.set(\n\t\t\t\"sec-websocket-protocol\",\n\t\t\tprotocols.join(\", \"),\n\t\t);\n\n\t\tconst id = c.env.ACTOR_DO.idFromString(actorId);\n\t\tconst stub = c.env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync getForId({\n\t\tc,\n\t\tactorId,\n\t}: GetForIdInput<{ Bindings: Bindings }>): Promise<\n\t\tActorOutput | undefined\n\t> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Get actor metadata from KV (combined name and key)\n\t\tconst actorData = (await env.ACTOR_KV.get(\n\t\t\tKEYS.ACTOR.metadata(actorId),\n\t\t\t{\n\t\t\t\ttype: \"json\",\n\t\t\t},\n\t\t)) as ActorData | null;\n\n\t\t// If the actor doesn't exist, return undefined\n\t\tif (!actorData) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tactorId,\n\t\t\tname: actorData.name,\n\t\t\tkey: actorData.key,\n\t\t};\n\t}\n\n\tasync getWithKey({\n\t\tc,\n\t\tname,\n\t\tkey,\n\t}: GetWithKeyInput<{ Bindings: Bindings }>): Promise<\n\t\tActorOutput | undefined\n\t> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\tlogger().debug({ msg: \"getWithKey: searching for actor\", name, key });\n\n\t\t// Generate deterministic ID from the name and key\n\t\t// This is aligned with how createActor generates IDs\n\t\tconst nameKeyString = serializeNameAndKey(name, key);\n\t\tconst actorId = env.ACTOR_DO.idFromName(nameKeyString).toString();\n\n\t\t// Check if the actor metadata exists\n\t\tconst actorData = await env.ACTOR_KV.get(KEYS.ACTOR.metadata(actorId), {\n\t\t\ttype: \"json\",\n\t\t});\n\n\t\tif (!actorData) {\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getWithKey: no actor found with matching name and key\",\n\t\t\t\tname,\n\t\t\t\tkey,\n\t\t\t\tactorId,\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\tlogger().debug({\n\t\t\tmsg: \"getWithKey: found actor with matching name and key\",\n\t\t\tactorId,\n\t\t\tname,\n\t\t\tkey,\n\t\t});\n\t\treturn this.#buildActorOutput(c, actorId);\n\t}\n\n\tasync getOrCreateWithKey(\n\t\tinput: GetOrCreateWithKeyInput,\n\t): Promise<ActorOutput> {\n\t\t// TODO: Prevent race condition here\n\t\tconst getOutput = await this.getWithKey(input);\n\t\tif (getOutput) {\n\t\t\treturn getOutput;\n\t\t} else {\n\t\t\treturn await this.createActor(input);\n\t\t}\n\t}\n\n\tasync createActor({\n\t\tc,\n\t\tname,\n\t\tkey,\n\t\tinput,\n\t}: CreateInput<{ Bindings: Bindings }>): Promise<ActorOutput> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Check if actor with the same name and key already exists\n\t\tconst existingActor = await this.getWithKey({ c, name, key });\n\t\tif (existingActor) {\n\t\t\tthrow new ActorAlreadyExists(name, key);\n\t\t}\n\n\t\t// Create a deterministic ID from the actor name and key\n\t\t// This ensures that actors with the same name and key will have the same ID\n\t\tconst nameKeyString = serializeNameAndKey(name, key);\n\t\tconst doId = env.ACTOR_DO.idFromName(nameKeyString);\n\t\tconst actorId = doId.toString();\n\n\t\t// Init actor\n\t\tconst actor = env.ACTOR_DO.get(doId);\n\t\tawait actor.initialize({\n\t\t\tname,\n\t\t\tkey,\n\t\t\tinput,\n\t\t});\n\n\t\t// Store combined actor metadata (name and key)\n\t\tconst actorData: ActorData = { name, key };\n\t\tawait env.ACTOR_KV.put(\n\t\t\tKEYS.ACTOR.metadata(actorId),\n\t\t\tJSON.stringify(actorData),\n\t\t);\n\n\t\t// Add to key index for lookups by name and key\n\t\tawait env.ACTOR_KV.put(KEYS.ACTOR.keyIndex(name, key), actorId);\n\n\t\treturn {\n\t\t\tactorId,\n\t\t\tname,\n\t\t\tkey,\n\t\t};\n\t}\n\n\t// Helper method to build actor output from an ID\n\tasync #buildActorOutput(\n\t\tc: any,\n\t\tactorId: string,\n\t): Promise<ActorOutput | undefined> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\tconst actorData = (await env.ACTOR_KV.get(\n\t\t\tKEYS.ACTOR.metadata(actorId),\n\t\t\t{\n\t\t\t\ttype: \"json\",\n\t\t\t},\n\t\t)) as ActorData | null;\n\n\t\tif (!actorData) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tactorId,\n\t\t\tname: actorData.name,\n\t\t\tkey: actorData.key,\n\t\t};\n\t}\n\n\tdisplayInformation(): ManagerDisplayInformation {\n\t\treturn {\n\t\t\tname: \"Cloudflare Workers\",\n\t\t\tproperties: {},\n\t\t};\n\t}\n\n\tgetOrCreateInspectorAccessToken() {\n\t\treturn generateRandomString();\n\t}\n}\n","// Constants for key handling\nexport const EMPTY_KEY = \"(none)\";\nexport const KEY_SEPARATOR = \",\";\n\n/**\n * Serializes an array of key strings into a single string for use with idFromName\n *\n * @param name The actor name\n * @param key Array of key strings to serialize\n * @returns A single string containing the serialized name and key\n */\nexport function serializeNameAndKey(name: string, key: string[]): string {\n\t// Escape colons in the name\n\tconst escapedName = name.replace(/:/g, \"\\\\:\");\n\n\t// For empty keys, just return the name and a marker\n\tif (key.length === 0) {\n\t\treturn `${escapedName}:${EMPTY_KEY}`;\n\t}\n\n\t// Serialize the key array\n\tconst serializedKey = serializeKey(key);\n\n\t// Combine name and serialized key\n\treturn `${escapedName}:${serializedKey}`;\n}\n\n/**\n * Serializes an array of key strings into a single string\n *\n * @param key Array of key strings to serialize\n * @returns A single string containing the serialized key\n */\nexport function serializeKey(key: string[]): string {\n\t// Use a special marker for empty key arrays\n\tif (key.length === 0) {\n\t\treturn EMPTY_KEY;\n\t}\n\n\t// Escape each key part to handle the separator and the empty key marker\n\tconst escapedParts = key.map((part) => {\n\t\t// First check if it matches our empty key marker\n\t\tif (part === EMPTY_KEY) {\n\t\t\treturn `\\\\${EMPTY_KEY}`;\n\t\t}\n\n\t\t// Escape backslashes first, then commas\n\t\tlet escaped = part.replace(/\\\\/g, \"\\\\\\\\\");\n\t\tescaped = escaped.replace(/,/g, \"\\\\,\");\n\t\treturn escaped;\n\t});\n\n\treturn escapedParts.join(KEY_SEPARATOR);\n}\n\n/**\n * Deserializes a key string back into an array of key strings\n *\n * @param keyString The serialized key string\n * @returns Array of key strings\n */\nexport function deserializeKey(keyString: string): string[] {\n\t// Handle empty values\n\tif (!keyString) {\n\t\treturn [];\n\t}\n\n\t// Check for special empty key marker\n\tif (keyString === EMPTY_KEY) {\n\t\treturn [];\n\t}\n\n\t// Split by unescaped commas and unescape the escaped characters\n\tconst parts: string[] = [];\n\tlet currentPart = \"\";\n\tlet escaping = false;\n\n\tfor (let i = 0; i < keyString.length; i++) {\n\t\tconst char = keyString[i];\n\n\t\tif (escaping) {\n\t\t\t// This is an escaped character, add it directly\n\t\t\tcurrentPart += char;\n\t\t\tescaping = false;\n\t\t} else if (char === \"\\\\\") {\n\t\t\t// Start of an escape sequence\n\t\t\tescaping = true;\n\t\t} else if (char === KEY_SEPARATOR) {\n\t\t\t// This is a separator\n\t\t\tparts.push(currentPart);\n\t\t\tcurrentPart = \"\";\n\t\t} else {\n\t\t\t// Regular character\n\t\t\tcurrentPart += char;\n\t\t}\n\t}\n\n\t// Add the last part if it exists\n\tif (currentPart || parts.length > 0) {\n\t\tparts.push(currentPart);\n\t}\n\n\treturn parts;\n}\n","// Modified from https://github.com/honojs/hono/blob/40ea0eee58e39b31053a0246c595434f1094ad31/src/adapter/cloudflare-workers/websocket.ts#L17\n//\n// This version calls the open event by default\n\nimport type { UpgradeWebSocket, WSEvents, WSReadyState } from \"hono/ws\";\nimport { defineWebSocketHelper, WSContext } from \"hono/ws\";\nimport { WS_PROTOCOL_STANDARD } from \"rivetkit/driver-helpers\";\n\n// Based on https://github.com/honojs/hono/issues/1153#issuecomment-1767321332\nexport const upgradeWebSocket: UpgradeWebSocket<\n\tWebSocket,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tany,\n\tWSEvents<WebSocket>\n> = defineWebSocketHelper(async (c, events) => {\n\tconst upgradeHeader = c.req.header(\"Upgrade\");\n\tif (upgradeHeader !== \"websocket\") {\n\t\treturn;\n\t}\n\n\tconst webSocketPair = new WebSocketPair();\n\tconst client: WebSocket = webSocketPair[0];\n\tconst server: WebSocket = webSocketPair[1];\n\n\tconst wsContext = new WSContext<WebSocket>({\n\t\tclose: (code, reason) => server.close(code, reason),\n\t\tget protocol() {\n\t\t\treturn server.protocol;\n\t\t},\n\t\traw: server,\n\t\tget readyState() {\n\t\t\treturn server.readyState as WSReadyState;\n\t\t},\n\t\turl: server.url ? new URL(server.url) : null,\n\t\tsend: (source) => server.send(source),\n\t});\n\n\tif (events.onClose) {\n\t\tserver.addEventListener(\"close\", (evt: CloseEvent) =>\n\t\t\tevents.onClose?.(evt, wsContext),\n\t\t);\n\t}\n\tif (events.onMessage) {\n\t\tserver.addEventListener(\"message\", (evt: MessageEvent) =>\n\t\t\tevents.onMessage?.(evt, wsContext),\n\t\t);\n\t}\n\tif (events.onError) {\n\t\tserver.addEventListener(\"error\", (evt: Event) =>\n\t\t\tevents.onError?.(evt, wsContext),\n\t\t);\n\t}\n\n\tserver.accept?.();\n\n\t// note: cloudflare actors doesn't support 'open' event, so we call it immediately with a fake event\n\t//\n\t// we have to do this after `server.accept() is called`\n\tevents.onOpen?.(new Event(\"open\"), wsContext);\n\n\t// Build response headers\n\tconst headers: Record<string, string> = {};\n\n\t// Set Sec-WebSocket-Protocol if does not exist\n\tconst protocols = c.req.header(\"Sec-WebSocket-Protocol\");\n\tif (\n\t\ttypeof protocols === \"string\" &&\n\t\tprotocols\n\t\t\t.split(\",\")\n\t\t\t.map((x) => x.trim())\n\t\t\t.includes(WS_PROTOCOL_STANDARD)\n\t) {\n\t\theaders[\"Sec-WebSocket-Protocol\"] = WS_PROTOCOL_STANDARD;\n\t}\n\n\treturn new Response(null, {\n\t\tstatus: 101,\n\t\theaders,\n\t\twebSocket: client,\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/cloudflare-workers/dist/mod.cjs","../src/actor-handler-do.ts","../src/actor-driver.ts","../src/actor-id.ts","../src/actor-kv.ts","../src/global-kv.ts","../src/handler.ts","../src/config.ts","../src/manager-driver.ts","../src/log.ts","../src/util.ts","../src/websocket.ts"],"names":["env","invariant"],"mappings":"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","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/cloudflare-workers/dist/mod.cjs","sourcesContent":[null,"import { DurableObject, env } from \"cloudflare:workers\";\nimport type { ExecutionContext } from \"hono\";\nimport invariant from \"invariant\";\nimport type { ActorKey, ActorRouter, Registry, RunConfig } from \"rivetkit\";\nimport { createActorRouter, createClientWithDriver } from \"rivetkit\";\nimport type { ActorDriver, ManagerDriver } from \"rivetkit/driver-helpers\";\nimport { getInitialActorKvState } from \"rivetkit/driver-helpers\";\nimport { stringifyError } from \"rivetkit/utils\";\nimport {\n\tActorGlobalState,\n\tCloudflareDurableObjectGlobalState,\n\tcreateCloudflareActorsActorDriverBuilder,\n} from \"./actor-driver\";\nimport { buildActorId, parseActorId } from \"./actor-id\";\nimport { kvPut } from \"./actor-kv\";\nimport { GLOBAL_KV_KEYS } from \"./global-kv\";\nimport type { Bindings } from \"./handler\";\nimport { getCloudflareAmbientEnv } from \"./handler\";\nimport { logger } from \"./log\";\n\nexport interface ActorHandlerInterface extends DurableObject {\n\tcreate(req: ActorInitRequest): Promise<ActorInitResponse>;\n\tgetMetadata(): Promise<\n\t\t| {\n\t\t\t\tactorId: string;\n\t\t\t\tname: string;\n\t\t\t\tkey: ActorKey;\n\t\t\t\tdestroying: boolean;\n\t\t }\n\t\t| undefined\n\t>;\n}\n\nexport interface ActorInitRequest {\n\tname: string;\n\tkey: ActorKey;\n\tinput?: unknown;\n\tallowExisting: boolean;\n}\nexport type ActorInitResponse =\n\t| { success: { actorId: string; created: boolean } }\n\t| { error: { actorAlreadyExists: true } };\n\nexport type DurableObjectConstructor = new (\n\t...args: ConstructorParameters<typeof DurableObject<Bindings>>\n) => DurableObject<Bindings>;\n\nexport function createActorDurableObject(\n\tregistry: Registry<any>,\n\trootRunConfig: RunConfig,\n): DurableObjectConstructor {\n\tconst globalState = new CloudflareDurableObjectGlobalState();\n\n\t// Configure to use the runner role instead of server role\n\tconst runConfig = Object.assign({}, rootRunConfig, { role: \"runner\" });\n\n\t/**\n\t * Startup steps:\n\t * 1. If not already created call `initialize`, otherwise check KV to ensure it's initialized\n\t * 2. Load actor\n\t * 3. Start service requests\n\t */\n\treturn class ActorHandler\n\t\textends DurableObject<Bindings>\n\t\timplements ActorHandlerInterface\n\t{\n\t\t/**\n\t\t * This holds a strong reference to ActorGlobalState.\n\t\t * CloudflareDurableObjectGlobalState holds a weak reference so we can\n\t\t * access it elsewhere.\n\t\t **/\n\t\t#state: ActorGlobalState;\n\n\t\tconstructor(\n\t\t\t...args: ConstructorParameters<typeof DurableObject<Bindings>>\n\t\t) {\n\t\t\tsuper(...args);\n\n\t\t\t// Initialize SQL table for key-value storage\n\t\t\t//\n\t\t\t// We do this instead of using the native KV storage so we can store blob keys. The native CF KV API only supports string keys.\n\t\t\tthis.ctx.storage.sql.exec(`\n\t\t\t\tCREATE TABLE IF NOT EXISTS _rivetkit_kv_storage(\n\t\t\t\t\tkey BLOB PRIMARY KEY,\n\t\t\t\t\tvalue BLOB\n\t\t\t\t);\n\t\t\t`);\n\n\t\t\t// Initialize SQL table for actor metadata\n\t\t\t//\n\t\t\t// id always equals 1 in order to ensure that there's always exactly 1 row in this table\n\t\t\tthis.ctx.storage.sql.exec(`\n\t\t\t\tCREATE TABLE IF NOT EXISTS _rivetkit_metadata(\n\t\t\t\t\tid INTEGER PRIMARY KEY CHECK (id = 1),\n\t\t\t\t\tname TEXT NOT NULL,\n\t\t\t\t\tkey TEXT NOT NULL,\n\t\t\t\t\tdestroyed INTEGER DEFAULT 0,\n\t\t\t\t\tgeneration INTEGER DEFAULT 0\n\t\t\t\t);\n\t\t\t`);\n\n\t\t\t// Get or create the actor state from the global WeakMap\n\t\t\tconst state = globalState.getActorState(this.ctx);\n\t\t\tif (state) {\n\t\t\t\tthis.#state = state;\n\t\t\t} else {\n\t\t\t\tthis.#state = new ActorGlobalState();\n\t\t\t\tglobalState.setActorState(this.ctx, this.#state);\n\t\t\t}\n\t\t}\n\n\t\tasync #loadActor() {\n\t\t\tinvariant(this.#state, \"State should be initialized\");\n\n\t\t\t// Check if initialized\n\t\t\tif (!this.#state.initialized) {\n\t\t\t\t// Query SQL for initialization data\n\t\t\t\tconst cursor = this.ctx.storage.sql.exec(\n\t\t\t\t\t\"SELECT name, key, destroyed, generation FROM _rivetkit_metadata WHERE id = 1\",\n\t\t\t\t);\n\t\t\t\tconst result = cursor.raw().next();\n\n\t\t\t\tif (!result.done && result.value) {\n\t\t\t\t\tconst name = result.value[0] as string;\n\t\t\t\t\tconst key = JSON.parse(\n\t\t\t\t\t\tresult.value[1] as string,\n\t\t\t\t\t) as ActorKey;\n\t\t\t\t\tconst destroyed = result.value[2] as number;\n\t\t\t\t\tconst generation = result.value[3] as number;\n\n\t\t\t\t\t// Only initialize if not destroyed\n\t\t\t\t\tif (!destroyed) {\n\t\t\t\t\t\tlogger().debug({\n\t\t\t\t\t\t\tmsg: \"already initialized\",\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tgeneration,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis.#state.initialized = { name, key, generation };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger().debug(\"actor is destroyed, cannot load\");\n\t\t\t\t\t\tthrow new Error(\"Actor is destroyed\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlogger().debug(\"not initialized\");\n\t\t\t\t\tthrow new Error(\"Actor is not initialized\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if already loaded\n\t\t\tif (this.#state.actor) {\n\t\t\t\t// Assert that the cached actor has the correct generation\n\t\t\t\t// This will catch any cases where #state.actor has a stale generation\n\t\t\t\tinvariant(\n\t\t\t\t\t!this.#state.initialized ||\n\t\t\t\t\t\tthis.#state.actor.generation ===\n\t\t\t\t\t\t\tthis.#state.initialized.generation,\n\t\t\t\t\t`Stale actor cached: actor generation ${this.#state.actor.generation} != initialized generation ${this.#state.initialized?.generation}. This should not happen.`,\n\t\t\t\t);\n\t\t\t\treturn this.#state.actor;\n\t\t\t}\n\n\t\t\tif (!this.#state.initialized) throw new Error(\"Not initialized\");\n\n\t\t\t// Register DO with global state first\n\t\t\t// HACK: This leaks the DO context, but DO does not provide a native way\n\t\t\t// of knowing when the DO shuts down. We're making a broad assumption\n\t\t\t// that DO will boot a new isolate frequenlty enough that this is not an issue.\n\t\t\tconst actorId = this.ctx.id.toString();\n\t\t\tglobalState.setDOState(actorId, { ctx: this.ctx, env: env });\n\n\t\t\t// Configure actor driver\n\t\t\tinvariant(runConfig.driver, \"runConfig.driver\");\n\t\t\trunConfig.driver.actor =\n\t\t\t\tcreateCloudflareActorsActorDriverBuilder(globalState);\n\n\t\t\t// Create manager driver (we need this for the actor router)\n\t\t\tconst managerDriver = runConfig.driver.manager(\n\t\t\t\tregistry.config,\n\t\t\t\trunConfig,\n\t\t\t);\n\n\t\t\t// Create inline client\n\t\t\tconst inlineClient = createClientWithDriver(\n\t\t\t\tmanagerDriver,\n\t\t\t\trunConfig,\n\t\t\t);\n\n\t\t\t// Create actor driver\n\t\t\tconst actorDriver = runConfig.driver.actor(\n\t\t\t\tregistry.config,\n\t\t\t\trunConfig,\n\t\t\t\tmanagerDriver,\n\t\t\t\tinlineClient,\n\t\t\t);\n\n\t\t\t// Create actor router\n\t\t\tconst actorRouter = createActorRouter(\n\t\t\t\trunConfig,\n\t\t\t\tactorDriver,\n\t\t\t\tfalse,\n\t\t\t);\n\n\t\t\t// Save actor with generation\n\t\t\tthis.#state.actor = {\n\t\t\t\tactorRouter,\n\t\t\t\tactorDriver,\n\t\t\t\tgeneration: this.#state.initialized.generation,\n\t\t\t};\n\n\t\t\t// Build actor ID with generation for loading\n\t\t\tconst actorIdWithGen = buildActorId(\n\t\t\t\tactorId,\n\t\t\t\tthis.#state.initialized.generation,\n\t\t\t);\n\n\t\t\t// Initialize the actor instance with proper metadata\n\t\t\t// This ensures the actor driver knows about this actor\n\t\t\tawait actorDriver.loadActor(actorIdWithGen);\n\n\t\t\treturn this.#state.actor;\n\t\t}\n\n\t\t/** RPC called to get actor metadata without creating it */\n\t\tasync getMetadata(): Promise<\n\t\t\t| {\n\t\t\t\t\tactorId: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\tkey: ActorKey;\n\t\t\t\t\tdestroying: boolean;\n\t\t\t }\n\t\t\t| undefined\n\t\t> {\n\t\t\t// Query the metadata\n\t\t\tconst cursor = this.ctx.storage.sql.exec(\n\t\t\t\t\"SELECT name, key, destroyed, generation FROM _rivetkit_metadata WHERE id = 1\",\n\t\t\t);\n\t\t\tconst result = cursor.raw().next();\n\n\t\t\tif (!result.done && result.value) {\n\t\t\t\tconst name = result.value[0] as string;\n\t\t\t\tconst key = JSON.parse(result.value[1] as string) as ActorKey;\n\t\t\t\tconst destroyed = result.value[2] as number;\n\t\t\t\tconst generation = result.value[3] as number;\n\n\t\t\t\t// Check if destroyed\n\t\t\t\tif (destroyed) {\n\t\t\t\t\tlogger().debug({\n\t\t\t\t\t\tmsg: \"getMetadata: actor is destroyed\",\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tgeneration,\n\t\t\t\t\t});\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\t// Build actor ID with generation\n\t\t\t\tconst doId = this.ctx.id.toString();\n\t\t\t\tconst actorId = buildActorId(doId, generation);\n\t\t\t\tconst destroying =\n\t\t\t\t\tglobalState.getActorState(this.ctx)?.destroying ?? false;\n\n\t\t\t\tlogger().debug({\n\t\t\t\t\tmsg: \"getMetadata: found actor metadata\",\n\t\t\t\t\tactorId,\n\t\t\t\t\tname,\n\t\t\t\t\tkey,\n\t\t\t\t\tgeneration,\n\t\t\t\t\tdestroying,\n\t\t\t\t});\n\n\t\t\t\treturn { actorId, name, key, destroying };\n\t\t\t}\n\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getMetadata: no metadata found\",\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\t/** RPC called by the manager to create a DO. Can optionally allow existing actors. */\n\t\tasync create(req: ActorInitRequest): Promise<ActorInitResponse> {\n\t\t\t// Check if actor exists\n\t\t\tconst checkCursor = this.ctx.storage.sql.exec(\n\t\t\t\t\"SELECT destroyed, generation FROM _rivetkit_metadata WHERE id = 1\",\n\t\t\t);\n\t\t\tconst checkResult = checkCursor.raw().next();\n\n\t\t\tlet created = false;\n\t\t\tlet generation = 0;\n\n\t\t\tif (!checkResult.done && checkResult.value) {\n\t\t\t\tconst destroyed = checkResult.value[0] as number;\n\t\t\t\tgeneration = checkResult.value[1] as number;\n\n\t\t\t\tif (!destroyed) {\n\t\t\t\t\t// Actor exists and is not destroyed\n\t\t\t\t\tif (!req.allowExisting) {\n\t\t\t\t\t\t// Fail if not allowing existing actors\n\t\t\t\t\t\tlogger().debug({\n\t\t\t\t\t\t\tmsg: \"create failed: actor already exists\",\n\t\t\t\t\t\t\tname: req.name,\n\t\t\t\t\t\t\tkey: req.key,\n\t\t\t\t\t\t\tgeneration,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn { error: { actorAlreadyExists: true } };\n\t\t\t\t\t}\n\n\t\t\t\t\t// Return existing actor\n\t\t\t\t\tlogger().debug({\n\t\t\t\t\t\tmsg: \"actor already exists\",\n\t\t\t\t\t\tkey: req.key,\n\t\t\t\t\t\tgeneration,\n\t\t\t\t\t});\n\t\t\t\t\tconst doId = this.ctx.id.toString();\n\t\t\t\t\tconst actorId = buildActorId(doId, generation);\n\t\t\t\t\treturn { success: { actorId, created: false } };\n\t\t\t\t}\n\n\t\t\t\t// Actor exists but is destroyed - resurrect with incremented generation\n\t\t\t\tgeneration = generation + 1;\n\t\t\t\tcreated = true;\n\n\t\t\t\t// Clear stale actor from previous generation\n\t\t\t\t// This is necessary because the DO instance may still be in memory\n\t\t\t\t// with the old #state.actor field from before the destroy\n\t\t\t\tif (this.#state) {\n\t\t\t\t\tthis.#state.actor = undefined;\n\t\t\t\t}\n\n\t\t\t\tlogger().debug({\n\t\t\t\t\tmsg: \"resurrecting destroyed actor\",\n\t\t\t\t\tkey: req.key,\n\t\t\t\t\toldGeneration: generation - 1,\n\t\t\t\t\tnewGeneration: generation,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// No actor exists - will create with generation 0\n\t\t\t\tgeneration = 0;\n\t\t\t\tcreated = true;\n\t\t\t\tlogger().debug({\n\t\t\t\t\tmsg: \"creating new actor\",\n\t\t\t\t\tkey: req.key,\n\t\t\t\t\tgeneration,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Perform upsert - either inserts new or updates destroyed actor\n\t\t\tthis.ctx.storage.sql.exec(\n\t\t\t\t`INSERT INTO _rivetkit_metadata (id, name, key, destroyed, generation)\n\t\t\t\tVALUES (1, ?, ?, 0, ?)\n\t\t\t\tON CONFLICT(id) DO UPDATE SET\n\t\t\t\t\tname = excluded.name,\n\t\t\t\t\tkey = excluded.key,\n\t\t\t\t\tdestroyed = 0,\n\t\t\t\t\tgeneration = excluded.generation`,\n\t\t\t\treq.name,\n\t\t\t\tJSON.stringify(req.key),\n\t\t\t\tgeneration,\n\t\t\t);\n\n\t\t\tthis.#state.initialized = {\n\t\t\t\tname: req.name,\n\t\t\t\tkey: req.key,\n\t\t\t\tgeneration,\n\t\t\t};\n\n\t\t\t// Build actor ID with generation\n\t\t\tconst doId = this.ctx.id.toString();\n\t\t\tconst actorId = buildActorId(doId, generation);\n\n\t\t\t// Initialize storage and update KV when created or resurrected\n\t\t\tif (created) {\n\t\t\t\t// Initialize persist data in KV storage\n\t\t\t\tinitializeActorKvStorage(this.ctx.storage.sql, req.input);\n\n\t\t\t\t// Update metadata in the background\n\t\t\t\tconst env = getCloudflareAmbientEnv();\n\t\t\t\tconst actorData = { name: req.name, key: req.key, generation };\n\t\t\t\tthis.ctx.waitUntil(\n\t\t\t\t\tenv.ACTOR_KV.put(\n\t\t\t\t\t\tGLOBAL_KV_KEYS.actorMetadata(actorId),\n\t\t\t\t\t\tJSON.stringify(actorData),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Preemptively load actor so the lifecycle hooks are called\n\t\t\tawait this.#loadActor();\n\n\t\t\tlogger().debug({\n\t\t\t\tmsg: created\n\t\t\t\t\t? \"actor created/resurrected\"\n\t\t\t\t\t: \"returning existing actor\",\n\t\t\t\tactorId,\n\t\t\t\tcreated,\n\t\t\t\tgeneration,\n\t\t\t});\n\n\t\t\treturn { success: { actorId, created } };\n\t\t}\n\n\t\tasync fetch(request: Request): Promise<Response> {\n\t\t\tconst { actorRouter, generation } = await this.#loadActor();\n\n\t\t\t// Build actor ID with generation\n\t\t\tconst doId = this.ctx.id.toString();\n\t\t\tconst actorId = buildActorId(doId, generation);\n\n\t\t\treturn await actorRouter.fetch(request, {\n\t\t\t\tactorId,\n\t\t\t});\n\t\t}\n\n\t\tasync alarm(): Promise<void> {\n\t\t\tconst { actorDriver, generation } = await this.#loadActor();\n\n\t\t\t// Build actor ID with generation\n\t\t\tconst doId = this.ctx.id.toString();\n\t\t\tconst actorId = buildActorId(doId, generation);\n\n\t\t\t// Load the actor instance and trigger alarm\n\t\t\tconst actor = await actorDriver.loadActor(actorId);\n\t\t\tawait actor.onAlarm();\n\t\t}\n\t};\n}\n\nfunction initializeActorKvStorage(\n\tsql: SqlStorage,\n\tinput: unknown | undefined,\n): void {\n\tconst initialKvState = getInitialActorKvState(input);\n\tfor (const [key, value] of initialKvState) {\n\t\tkvPut(sql, key, value);\n\t}\n}\n","import invariant from \"invariant\";\nimport type {\n\tActorKey,\n\tActorRouter,\n\tAnyActorInstance as CoreAnyActorInstance,\n\tRegistryConfig,\n\tRunConfig,\n} from \"rivetkit\";\nimport { lookupInRegistry } from \"rivetkit\";\nimport type { Client } from \"rivetkit/client\";\nimport type {\n\tActorDriver,\n\tAnyActorInstance,\n\tManagerDriver,\n} from \"rivetkit/driver-helpers\";\nimport { promiseWithResolvers } from \"rivetkit/utils\";\nimport { parseActorId } from \"./actor-id\";\nimport { kvDelete, kvGet, kvListPrefix, kvPut } from \"./actor-kv\";\nimport { GLOBAL_KV_KEYS } from \"./global-kv\";\nimport { getCloudflareAmbientEnv } from \"./handler\";\n\ninterface DurableObjectGlobalState {\n\tctx: DurableObjectState;\n\tenv: unknown;\n}\n\n/**\n * Cloudflare DO can have multiple DO running within the same global scope.\n *\n * This allows for storing the actor context globally and looking it up by ID in `CloudflareActorsActorDriver`.\n */\nexport class CloudflareDurableObjectGlobalState {\n\t// Map of actor ID -> DO state\n\t#dos: Map<string, DurableObjectGlobalState> = new Map();\n\n\t// WeakMap of DO state -> ActorGlobalState for proper GC\n\t#actors: WeakMap<DurableObjectState, ActorGlobalState> = new WeakMap();\n\n\tgetDOState(doId: string): DurableObjectGlobalState {\n\t\tconst state = this.#dos.get(doId);\n\t\tinvariant(\n\t\t\tstate !== undefined,\n\t\t\t\"durable object state not in global state\",\n\t\t);\n\t\treturn state;\n\t}\n\n\tsetDOState(doId: string, state: DurableObjectGlobalState) {\n\t\tthis.#dos.set(doId, state);\n\t}\n\n\tgetActorState(ctx: DurableObjectState): ActorGlobalState | undefined {\n\t\treturn this.#actors.get(ctx);\n\t}\n\n\tsetActorState(ctx: DurableObjectState, actorState: ActorGlobalState): void {\n\t\tthis.#actors.set(ctx, actorState);\n\t}\n}\n\nexport interface DriverContext {\n\tstate: DurableObjectState;\n}\n\ninterface InitializedData {\n\tname: string;\n\tkey: ActorKey;\n\tgeneration: number;\n}\n\ninterface LoadedActor {\n\tactorRouter: ActorRouter;\n\tactorDriver: ActorDriver;\n\tgeneration: number;\n}\n\n// Actor global state to track running instances\nexport class ActorGlobalState {\n\t// Initialization state\n\tinitialized?: InitializedData;\n\n\t// Loaded actor state\n\tactor?: LoadedActor;\n\tactorInstance?: AnyActorInstance;\n\tactorPromise?: ReturnType<typeof promiseWithResolvers<void>>;\n\n\t/**\n\t * Indicates if `startDestroy` has been called.\n\t *\n\t * This is stored in memory instead of SQLite since the destroy may be cancelled.\n\t *\n\t * See the corresponding `destroyed` property in SQLite metadata.\n\t */\n\tdestroying: boolean = false;\n\n\treset() {\n\t\tthis.initialized = undefined;\n\t\tthis.actor = undefined;\n\t\tthis.actorInstance = undefined;\n\t\tthis.actorPromise = undefined;\n\t\tthis.destroying = false;\n\t}\n}\n\nexport class CloudflareActorsActorDriver implements ActorDriver {\n\t#registryConfig: RegistryConfig;\n\t#runConfig: RunConfig;\n\t#managerDriver: ManagerDriver;\n\t#inlineClient: Client<any>;\n\t#globalState: CloudflareDurableObjectGlobalState;\n\n\tconstructor(\n\t\tregistryConfig: RegistryConfig,\n\t\trunConfig: RunConfig,\n\t\tmanagerDriver: ManagerDriver,\n\t\tinlineClient: Client<any>,\n\t\tglobalState: CloudflareDurableObjectGlobalState,\n\t) {\n\t\tthis.#registryConfig = registryConfig;\n\t\tthis.#runConfig = runConfig;\n\t\tthis.#managerDriver = managerDriver;\n\t\tthis.#inlineClient = inlineClient;\n\t\tthis.#globalState = globalState;\n\t}\n\n\t#getDOCtx(actorId: string) {\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\t\treturn this.#globalState.getDOState(doId).ctx;\n\t}\n\n\tasync loadActor(actorId: string): Promise<AnyActorInstance> {\n\t\t// Parse actor ID to get DO ID and generation\n\t\tconst [doId, expectedGeneration] = parseActorId(actorId);\n\n\t\t// Get the DO state\n\t\tconst doState = this.#globalState.getDOState(doId);\n\n\t\t// Check if actor is already loaded\n\t\tlet actorState = this.#globalState.getActorState(doState.ctx);\n\t\tif (actorState?.actorInstance) {\n\t\t\t// Actor is already loaded, return it\n\t\t\treturn actorState.actorInstance;\n\t\t}\n\n\t\t// Create new actor state if it doesn't exist\n\t\tif (!actorState) {\n\t\t\tactorState = new ActorGlobalState();\n\t\t\tactorState.actorPromise = promiseWithResolvers();\n\t\t\tthis.#globalState.setActorState(doState.ctx, actorState);\n\t\t} else if (actorState.actorPromise) {\n\t\t\t// Another request is already loading this actor, wait for it\n\t\t\tawait actorState.actorPromise.promise;\n\t\t\tif (!actorState.actorInstance) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Actor ${actorId} failed to load in concurrent request`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn actorState.actorInstance;\n\t\t}\n\n\t\t// Load actor metadata\n\t\tconst sql = doState.ctx.storage.sql;\n\t\tconst cursor = sql.exec(\n\t\t\t\"SELECT name, key, destroyed, generation FROM _rivetkit_metadata LIMIT 1\",\n\t\t);\n\t\tconst result = cursor.raw().next();\n\n\t\tif (result.done || !result.value) {\n\t\t\tthrow new Error(\n\t\t\t\t`Actor ${actorId} is not initialized - missing metadata`,\n\t\t\t);\n\t\t}\n\n\t\tconst name = result.value[0] as string;\n\t\tconst key = JSON.parse(result.value[1] as string) as string[];\n\t\tconst destroyed = result.value[2] as number;\n\t\tconst generation = result.value[3] as number;\n\n\t\t// Check if actor is destroyed\n\t\tif (destroyed) {\n\t\t\tthrow new Error(`Actor ${actorId} is destroyed`);\n\t\t}\n\n\t\t// Check if generation matches\n\t\tif (generation !== expectedGeneration) {\n\t\t\tthrow new Error(\n\t\t\t\t`Actor ${actorId} generation mismatch - expected ${expectedGeneration}, got ${generation}`,\n\t\t\t);\n\t\t}\n\n\t\t// Create actor instance\n\t\tconst definition = lookupInRegistry(this.#registryConfig, name);\n\t\tactorState.actorInstance = definition.instantiate();\n\n\t\t// Start actor\n\t\tawait actorState.actorInstance.start(\n\t\t\tthis,\n\t\t\tthis.#inlineClient,\n\t\t\tactorId,\n\t\t\tname,\n\t\t\tkey,\n\t\t\t\"unknown\", // TODO: Support regions in Cloudflare\n\t\t);\n\n\t\t// Finish\n\t\tactorState.actorPromise?.resolve();\n\t\tactorState.actorPromise = undefined;\n\n\t\treturn actorState.actorInstance;\n\t}\n\n\tgetContext(actorId: string): DriverContext {\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\t\tconst state = this.#globalState.getDOState(doId);\n\t\treturn { state: state.ctx };\n\t}\n\n\tasync setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> {\n\t\tawait this.#getDOCtx(actor.id).storage.setAlarm(timestamp);\n\t}\n\n\tasync getDatabase(actorId: string): Promise<unknown | undefined> {\n\t\treturn this.#getDOCtx(actorId).storage.sql;\n\t}\n\n\t// Batch KV operations\n\tasync kvBatchPut(\n\t\tactorId: string,\n\t\tentries: [Uint8Array, Uint8Array][],\n\t): Promise<void> {\n\t\tconst sql = this.#getDOCtx(actorId).storage.sql;\n\n\t\tfor (const [key, value] of entries) {\n\t\t\tkvPut(sql, key, value);\n\t\t}\n\t}\n\n\tasync kvBatchGet(\n\t\tactorId: string,\n\t\tkeys: Uint8Array[],\n\t): Promise<(Uint8Array | null)[]> {\n\t\tconst sql = this.#getDOCtx(actorId).storage.sql;\n\n\t\tconst results: (Uint8Array | null)[] = [];\n\t\tfor (const key of keys) {\n\t\t\tresults.push(kvGet(sql, key));\n\t\t}\n\n\t\treturn results;\n\t}\n\n\tasync kvBatchDelete(actorId: string, keys: Uint8Array[]): Promise<void> {\n\t\tconst sql = this.#getDOCtx(actorId).storage.sql;\n\n\t\tfor (const key of keys) {\n\t\t\tkvDelete(sql, key);\n\t\t}\n\t}\n\n\tasync kvListPrefix(\n\t\tactorId: string,\n\t\tprefix: Uint8Array,\n\t): Promise<[Uint8Array, Uint8Array][]> {\n\t\tconst sql = this.#getDOCtx(actorId).storage.sql;\n\n\t\treturn kvListPrefix(sql, prefix);\n\t}\n\n\tstartDestroy(actorId: string): void {\n\t\t// Parse actor ID to get DO ID and generation\n\t\tconst [doId, generation] = parseActorId(actorId);\n\n\t\t// Get the DO state\n\t\tconst doState = this.#globalState.getDOState(doId);\n\t\tconst actorState = this.#globalState.getActorState(doState.ctx);\n\n\t\t// Actor not loaded, nothing to destroy\n\t\tif (!actorState?.actorInstance) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if already destroying\n\t\tif (actorState.destroying) {\n\t\t\treturn;\n\t\t}\n\t\tactorState.destroying = true;\n\n\t\t// Spawn onStop in background\n\t\tthis.#callOnStopAsync(actorId, doId, actorState.actorInstance);\n\t}\n\n\tasync #callOnStopAsync(\n\t\tactorId: string,\n\t\tdoId: string,\n\t\tactor: CoreAnyActorInstance,\n\t) {\n\t\t// Stop\n\t\tawait actor.onStop(\"destroy\");\n\n\t\t// Remove state\n\t\tconst doState = this.#globalState.getDOState(doId);\n\t\tconst sql = doState.ctx.storage.sql;\n\t\tsql.exec(\"UPDATE _rivetkit_metadata SET destroyed = 1 WHERE 1=1\");\n\t\tsql.exec(\"DELETE FROM _rivetkit_kv_storage\");\n\n\t\t// Clear any scheduled alarms\n\t\tawait doState.ctx.storage.deleteAlarm();\n\n\t\t// Delete from ACTOR_KV in the background - use full actorId including generation\n\t\tconst env = getCloudflareAmbientEnv();\n\t\tdoState.ctx.waitUntil(\n\t\t\tenv.ACTOR_KV.delete(GLOBAL_KV_KEYS.actorMetadata(actorId)),\n\t\t);\n\n\t\t// Reset global state using the DO context\n\t\tconst actorHandle = this.#globalState.getActorState(doState.ctx);\n\t\tactorHandle?.reset();\n\t}\n}\n\nexport function createCloudflareActorsActorDriverBuilder(\n\tglobalState: CloudflareDurableObjectGlobalState,\n) {\n\treturn (\n\t\tregistryConfig: RegistryConfig,\n\t\trunConfig: RunConfig,\n\t\tmanagerDriver: ManagerDriver,\n\t\tinlineClient: Client<any>,\n\t) => {\n\t\treturn new CloudflareActorsActorDriver(\n\t\t\tregistryConfig,\n\t\t\trunConfig,\n\t\t\tmanagerDriver,\n\t\t\tinlineClient,\n\t\t\tglobalState,\n\t\t);\n\t};\n}\n","/**\n * Actor ID utilities for managing actor IDs with generation tracking.\n *\n * Actor IDs are formatted as: `{doId}:{generation}`\n * This allows tracking actor resurrection and preventing stale references.\n */\n\n/**\n * Build an actor ID from a Durable Object ID and generation number.\n * @param doId The Durable Object ID\n * @param generation The generation number (increments on resurrection)\n * @returns The formatted actor ID\n */\nexport function buildActorId(doId: string, generation: number): string {\n\treturn `${doId}:${generation}`;\n}\n\n/**\n * Parse an actor ID into its components.\n * @param actorId The actor ID to parse\n * @returns A tuple of [doId, generation]\n * @throws Error if the actor ID format is invalid\n */\nexport function parseActorId(actorId: string): [string, number] {\n\tconst parts = actorId.split(\":\");\n\tif (parts.length !== 2) {\n\t\tthrow new Error(`Invalid actor ID format: ${actorId}`);\n\t}\n\n\tconst [doId, generationStr] = parts;\n\tconst generation = parseInt(generationStr, 10);\n\n\tif (Number.isNaN(generation)) {\n\t\tthrow new Error(`Invalid generation number in actor ID: ${actorId}`);\n\t}\n\n\treturn [doId, generation];\n}\n","export function kvGet(sql: SqlStorage, key: Uint8Array): Uint8Array | null {\n\tconst cursor = sql.exec(\n\t\t\"SELECT value FROM _rivetkit_kv_storage WHERE key = ?\",\n\t\tkey,\n\t);\n\tconst result = cursor.raw().next();\n\n\tif (!result.done && result.value) {\n\t\treturn toUint8Array(result.value[0]);\n\t}\n\treturn null;\n}\n\nexport function kvPut(\n\tsql: SqlStorage,\n\tkey: Uint8Array,\n\tvalue: Uint8Array,\n): void {\n\tsql.exec(\n\t\t\"INSERT OR REPLACE INTO _rivetkit_kv_storage (key, value) VALUES (?, ?)\",\n\t\tkey,\n\t\tvalue,\n\t);\n}\n\nexport function kvDelete(sql: SqlStorage, key: Uint8Array): void {\n\tsql.exec(\"DELETE FROM _rivetkit_kv_storage WHERE key = ?\", key);\n}\n\nexport function kvListPrefix(\n\tsql: SqlStorage,\n\tprefix: Uint8Array,\n): [Uint8Array, Uint8Array][] {\n\tconst cursor = sql.exec(\"SELECT key, value FROM _rivetkit_kv_storage\");\n\tconst entries: [Uint8Array, Uint8Array][] = [];\n\n\tfor (const row of cursor.raw()) {\n\t\tconst key = toUint8Array(row[0]);\n\t\tconst value = toUint8Array(row[1]);\n\n\t\t// Check if key starts with prefix\n\t\tif (hasPrefix(key, prefix)) {\n\t\t\tentries.push([key, value]);\n\t\t}\n\t}\n\n\treturn entries;\n}\n\n// Helper function to convert SqlStorageValue to Uint8Array\nfunction toUint8Array(\n\tvalue: string | number | ArrayBuffer | Uint8Array | null,\n): Uint8Array {\n\tif (value instanceof Uint8Array) {\n\t\treturn value;\n\t}\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value);\n\t}\n\tthrow new Error(\n\t\t`Unexpected SQL value type: ${typeof value} (${value?.constructor?.name})`,\n\t);\n}\n\nfunction hasPrefix(arr: Uint8Array, prefix: Uint8Array): boolean {\n\tif (prefix.length > arr.length) return false;\n\tfor (let i = 0; i < prefix.length; i++) {\n\t\tif (arr[i] !== prefix[i]) return false;\n\t}\n\treturn true;\n}\n","/** KV keys for using Workers KV to store actor metadata globally. */\nexport const GLOBAL_KV_KEYS = {\n\tactorMetadata: (actorId: string): string => {\n\t\treturn `actor:${actorId}:metadata`;\n\t},\n};\n","import { env } from \"cloudflare:workers\";\nimport type { Client, Registry, RunConfig } from \"rivetkit\";\nimport {\n\ttype ActorHandlerInterface,\n\tcreateActorDurableObject,\n\ttype DurableObjectConstructor,\n} from \"./actor-handler-do\";\nimport { type Config, ConfigSchema, type InputConfig } from \"./config\";\nimport { CloudflareActorsManagerDriver } from \"./manager-driver\";\nimport { upgradeWebSocket } from \"./websocket\";\n\n/** Cloudflare Workers env */\nexport interface Bindings {\n\tACTOR_KV: KVNamespace;\n\tACTOR_DO: DurableObjectNamespace<ActorHandlerInterface>;\n}\n\n/**\n * Stores the env for the current request. Required since some contexts like the inline client driver does not have access to the Hono context.\n *\n * Use getCloudflareAmbientEnv unless using CF_AMBIENT_ENV.run.\n */\nexport function getCloudflareAmbientEnv(): Bindings {\n\treturn env as unknown as Bindings;\n}\n\nexport interface InlineOutput<A extends Registry<any>> {\n\t/** Client to communicate with the actors. */\n\tclient: Client<A>;\n\n\t/** Fetch handler to manually route requests to the Rivet manager API. */\n\tfetch: (request: Request, ...args: any) => Response | Promise<Response>;\n\n\tconfig: Config;\n\n\tActorHandler: DurableObjectConstructor;\n}\n\nexport interface HandlerOutput {\n\thandler: ExportedHandler<Bindings>;\n\tActorHandler: DurableObjectConstructor;\n}\n\n/**\n * Creates an inline client for accessing Rivet Actors privately without a public manager API.\n *\n * If you want to expose a public manager API, either:\n *\n * - Use `createHandler` to expose the Rivet API on `/rivet`\n * - Forward Rivet API requests to `InlineOutput::fetch`\n */\nexport function createInlineClient<R extends Registry<any>>(\n\tregistry: R,\n\tinputConfig?: InputConfig,\n): InlineOutput<R> {\n\t// HACK: Cloudflare does not support using `crypto.randomUUID()` before start, so we pass a default value\n\t//\n\t// Runner key is not used on Cloudflare\n\tinputConfig = { ...inputConfig, runnerKey: \"\" };\n\n\t// Parse config\n\tconst config = ConfigSchema.parse(inputConfig);\n\n\t// Create config\n\tconst runConfig = {\n\t\t...config,\n\t\tdriver: {\n\t\t\tname: \"cloudflare-workers\",\n\t\t\tmanager: () => new CloudflareActorsManagerDriver(),\n\t\t\t// HACK: We can't build the actor driver until we're inside the Durable Object\n\t\t\tactor: undefined as any,\n\t\t},\n\t\tgetUpgradeWebSocket: () => upgradeWebSocket,\n\t} satisfies RunConfig;\n\n\t// Create Durable Object\n\tconst ActorHandler = createActorDurableObject(registry, runConfig);\n\n\t// Create server\n\tconst { client, fetch } = registry.start(runConfig);\n\n\treturn { client, fetch, config, ActorHandler };\n}\n\n/**\n * Creates a handler to be exported from a Cloudflare Worker.\n *\n * This will automatically expose the Rivet manager API on `/rivet`.\n *\n * This includes a `fetch` handler and `ActorHandler` Durable Object.\n */\nexport function createHandler<R extends Registry<any>>(\n\tregistry: R,\n\tinputConfig?: InputConfig,\n): HandlerOutput {\n\tconst { client, fetch, config, ActorHandler } = createInlineClient(\n\t\tregistry,\n\t\tinputConfig,\n\t);\n\n\t// Create Cloudflare handler\n\tconst handler = {\n\t\tfetch: async (request, cfEnv, ctx) => {\n\t\t\tconst url = new URL(request.url);\n\n\t\t\t// Inject Rivet env\n\t\t\tconst env = Object.assign({ RIVET: client }, cfEnv);\n\n\t\t\t// Mount Rivet manager API\n\t\t\tif (url.pathname.startsWith(config.managerPath)) {\n\t\t\t\tconst strippedPath = url.pathname.substring(\n\t\t\t\t\tconfig.managerPath.length,\n\t\t\t\t);\n\t\t\t\turl.pathname = strippedPath;\n\t\t\t\tconst modifiedRequest = new Request(url.toString(), request);\n\t\t\t\treturn fetch(modifiedRequest, env, ctx);\n\t\t\t}\n\n\t\t\tif (config.fetch) {\n\t\t\t\treturn config.fetch(request, env, ctx);\n\t\t\t} else {\n\t\t\t\treturn new Response(\n\t\t\t\t\t\"This is a RivetKit server.\\n\\nLearn more at https://rivetkit.org\\n\",\n\t\t\t\t\t{ status: 200 },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t} satisfies ExportedHandler<Bindings>;\n\n\treturn { handler, ActorHandler };\n}\n","import type { Client } from \"rivetkit\";\nimport { RunConfigSchema } from \"rivetkit/driver-helpers\";\nimport { z } from \"zod\";\n\nexport const ConfigSchema = RunConfigSchema.removeDefault()\n\t.omit({ driver: true, getUpgradeWebSocket: true })\n\t.extend({\n\t\t/** Path that the Rivet manager API will be mounted. */\n\t\tmanagerPath: z.string().optional().default(\"/rivet\"),\n\n\t\tfetch: z\n\t\t\t.custom<\n\t\t\t\tExportedHandlerFetchHandler<{ RIVET: Client<any> }, unknown>\n\t\t\t>()\n\t\t\t.optional(),\n\t})\n\t.default({});\nexport type InputConfig = z.input<typeof ConfigSchema>;\nexport type Config = z.infer<typeof ConfigSchema>;\n","import type { Context as HonoContext } from \"hono\";\nimport type { Encoding, UniversalWebSocket } from \"rivetkit\";\nimport {\n\ttype ActorOutput,\n\ttype CreateInput,\n\ttype GetForIdInput,\n\ttype GetOrCreateWithKeyInput,\n\ttype GetWithKeyInput,\n\tgenerateRandomString,\n\ttype ListActorsInput,\n\ttype ManagerDisplayInformation,\n\ttype ManagerDriver,\n\tWS_PROTOCOL_ACTOR,\n\tWS_PROTOCOL_CONN_PARAMS,\n\tWS_PROTOCOL_ENCODING,\n\tWS_PROTOCOL_STANDARD,\n\tWS_PROTOCOL_TARGET,\n} from \"rivetkit/driver-helpers\";\nimport {\n\tActorDuplicateKey,\n\tActorNotFound,\n\tInternalError,\n} from \"rivetkit/errors\";\nimport { assertUnreachable } from \"rivetkit/utils\";\nimport { parseActorId } from \"./actor-id\";\nimport { getCloudflareAmbientEnv } from \"./handler\";\nimport { logger } from \"./log\";\nimport type { Bindings } from \"./mod\";\nimport { serializeNameAndKey } from \"./util\";\n\nconst STANDARD_WEBSOCKET_HEADERS = [\n\t\"connection\",\n\t\"upgrade\",\n\t\"sec-websocket-key\",\n\t\"sec-websocket-version\",\n\t\"sec-websocket-protocol\",\n\t\"sec-websocket-extensions\",\n];\n\nexport class CloudflareActorsManagerDriver implements ManagerDriver {\n\tasync sendRequest(\n\t\tactorId: string,\n\t\tactorRequest: Request,\n\t): Promise<Response> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\n\t\tlogger().debug({\n\t\t\tmsg: \"sending request to durable object\",\n\t\t\tactorId,\n\t\t\tdoId,\n\t\t\tmethod: actorRequest.method,\n\t\t\turl: actorRequest.url,\n\t\t});\n\n\t\tconst id = env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync openWebSocket(\n\t\tpath: string,\n\t\tactorId: string,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t): Promise<UniversalWebSocket> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\n\t\tlogger().debug({\n\t\t\tmsg: \"opening websocket to durable object\",\n\t\t\tactorId,\n\t\t\tdoId,\n\t\t\tpath,\n\t\t});\n\n\t\t// Make a fetch request to the Durable Object with WebSocket upgrade\n\t\tconst id = env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\tconst protocols: string[] = [];\n\t\tprotocols.push(WS_PROTOCOL_STANDARD);\n\t\tprotocols.push(`${WS_PROTOCOL_TARGET}actor`);\n\t\tprotocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);\n\t\tprotocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);\n\t\tif (params) {\n\t\t\tprotocols.push(\n\t\t\t\t`${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`,\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\tUpgrade: \"websocket\",\n\t\t\tConnection: \"Upgrade\",\n\t\t\t\"sec-websocket-protocol\": protocols.join(\", \"),\n\t\t};\n\n\t\t// Use the path parameter to determine the URL\n\t\tconst normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n\t\tconst url = `http://actor${normalizedPath}`;\n\n\t\tlogger().debug({ msg: \"rewriting websocket url\", from: path, to: url });\n\n\t\tconst response = await stub.fetch(url, {\n\t\t\theaders,\n\t\t});\n\t\tconst webSocket = response.webSocket;\n\n\t\tif (!webSocket) {\n\t\t\tthrow new InternalError(\n\t\t\t\t`missing websocket connection in response from DO\\n\\nStatus: ${response.status}\\nResponse: ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tlogger().debug({\n\t\t\tmsg: \"durable object websocket connection open\",\n\t\t\tactorId,\n\t\t});\n\n\t\twebSocket.accept();\n\n\t\t// TODO: Is this still needed?\n\t\t// HACK: Cloudflare does not call onopen automatically, so we need\n\t\t// to call this on the next tick\n\t\tsetTimeout(() => {\n\t\t\tconst event = new Event(\"open\");\n\t\t\t(webSocket as any).onopen?.(event);\n\t\t\t(webSocket as any).dispatchEvent(event);\n\t\t}, 0);\n\n\t\treturn webSocket as unknown as UniversalWebSocket;\n\t}\n\n\tasync proxyRequest(\n\t\tc: HonoContext<{ Bindings: Bindings }>,\n\t\tactorRequest: Request,\n\t\tactorId: string,\n\t): Promise<Response> {\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\n\t\tlogger().debug({\n\t\t\tmsg: \"forwarding request to durable object\",\n\t\t\tactorId,\n\t\t\tdoId,\n\t\t\tmethod: actorRequest.method,\n\t\t\turl: actorRequest.url,\n\t\t});\n\n\t\tconst id = c.env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = c.env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync proxyWebSocket(\n\t\tc: HonoContext<{ Bindings: Bindings }>,\n\t\tpath: string,\n\t\tactorId: string,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t): Promise<Response> {\n\t\tlogger().debug({\n\t\t\tmsg: \"forwarding websocket to durable object\",\n\t\t\tactorId,\n\t\t\tpath,\n\t\t});\n\n\t\t// Validate upgrade\n\t\tconst upgradeHeader = c.req.header(\"Upgrade\");\n\t\tif (!upgradeHeader || upgradeHeader !== \"websocket\") {\n\t\t\treturn new Response(\"Expected Upgrade: websocket\", {\n\t\t\t\tstatus: 426,\n\t\t\t});\n\t\t}\n\n\t\tconst newUrl = new URL(`http://actor${path}`);\n\t\tconst actorRequest = new Request(newUrl, c.req.raw);\n\n\t\tlogger().debug({\n\t\t\tmsg: \"rewriting websocket url\",\n\t\t\tfrom: c.req.url,\n\t\t\tto: actorRequest.url,\n\t\t});\n\n\t\t// Always build fresh request to prevent forwarding unwanted headers\n\t\t// HACK: Since we can't build a new request, we need to remove\n\t\t// non-standard headers manually\n\t\tconst headerKeys: string[] = [];\n\t\tactorRequest.headers.forEach((v, k) => {\n\t\t\theaderKeys.push(k);\n\t\t});\n\t\tfor (const k of headerKeys) {\n\t\t\tif (!STANDARD_WEBSOCKET_HEADERS.includes(k)) {\n\t\t\t\tactorRequest.headers.delete(k);\n\t\t\t}\n\t\t}\n\n\t\t// Build protocols for WebSocket connection\n\t\tconst protocols: string[] = [];\n\t\tprotocols.push(WS_PROTOCOL_STANDARD);\n\t\tprotocols.push(`${WS_PROTOCOL_TARGET}actor`);\n\t\tprotocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);\n\t\tprotocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);\n\t\tif (params) {\n\t\t\tprotocols.push(\n\t\t\t\t`${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`,\n\t\t\t);\n\t\t}\n\t\tactorRequest.headers.set(\n\t\t\t\"sec-websocket-protocol\",\n\t\t\tprotocols.join(\", \"),\n\t\t);\n\n\t\t// Parse actor ID to get DO ID\n\t\tconst [doId] = parseActorId(actorId);\n\t\tconst id = c.env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = c.env.ACTOR_DO.get(id);\n\n\t\treturn await stub.fetch(actorRequest);\n\t}\n\n\tasync getForId({\n\t\tc,\n\t\tactorId,\n\t}: GetForIdInput<{ Bindings: Bindings }>): Promise<\n\t\tActorOutput | undefined\n\t> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Parse actor ID to get DO ID and expected generation\n\t\tconst [doId, expectedGeneration] = parseActorId(actorId);\n\n\t\t// Get the Durable Object stub\n\t\tconst id = env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\t// Call the DO's getMetadata method\n\t\tconst result = await stub.getMetadata();\n\n\t\tif (!result) {\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getForId: actor not found\",\n\t\t\t\tactorId,\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Check if the actor IDs match in order to check if the generation matches\n\t\tif (result.actorId !== actorId) {\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getForId: generation mismatch\",\n\t\t\t\trequestedActorId: actorId,\n\t\t\t\tactualActorId: result.actorId,\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (result.destroying) {\n\t\t\tthrow new ActorNotFound(actorId);\n\t\t}\n\n\t\treturn {\n\t\t\tactorId: result.actorId,\n\t\t\tname: result.name,\n\t\t\tkey: result.key,\n\t\t};\n\t}\n\n\tasync getWithKey({\n\t\tc,\n\t\tname,\n\t\tkey,\n\t}: GetWithKeyInput<{ Bindings: Bindings }>): Promise<\n\t\tActorOutput | undefined\n\t> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\tlogger().debug({ msg: \"getWithKey: searching for actor\", name, key });\n\n\t\t// Generate deterministic ID from the name and key\n\t\tconst nameKeyString = serializeNameAndKey(name, key);\n\t\tconst doId = env.ACTOR_DO.idFromName(nameKeyString).toString();\n\n\t\t// Try to get the Durable Object to see if it exists\n\t\tconst id = env.ACTOR_DO.idFromString(doId);\n\t\tconst stub = env.ACTOR_DO.get(id);\n\n\t\t// Check if actor exists without creating it\n\t\tconst result = await stub.getMetadata();\n\n\t\tif (result) {\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getWithKey: found actor with matching name and key\",\n\t\t\t\tactorId: result.actorId,\n\t\t\t\tname: result.name,\n\t\t\t\tkey: result.key,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tactorId: result.actorId,\n\t\t\t\tname: result.name,\n\t\t\t\tkey: result.key,\n\t\t\t};\n\t\t} else {\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getWithKey: no actor found with matching name and key\",\n\t\t\t\tname,\n\t\t\t\tkey,\n\t\t\t\tdoId,\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync getOrCreateWithKey({\n\t\tc,\n\t\tname,\n\t\tkey,\n\t\tinput,\n\t}: GetOrCreateWithKeyInput<{ Bindings: Bindings }>): Promise<ActorOutput> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Create a deterministic ID from the actor name and key\n\t\t// This ensures that actors with the same name and key will have the same ID\n\t\tconst nameKeyString = serializeNameAndKey(name, key);\n\t\tconst doId = env.ACTOR_DO.idFromName(nameKeyString);\n\n\t\t// Get or create actor using the Durable Object's method\n\t\tconst actor = env.ACTOR_DO.get(doId);\n\t\tconst result = await actor.create({\n\t\t\tname,\n\t\t\tkey,\n\t\t\tinput,\n\t\t\tallowExisting: true,\n\t\t});\n\t\tif (\"success\" in result) {\n\t\t\tconst { actorId, created } = result.success;\n\t\t\tlogger().debug({\n\t\t\t\tmsg: \"getOrCreateWithKey result\",\n\t\t\t\tactorId,\n\t\t\t\tname,\n\t\t\t\tkey,\n\t\t\t\tcreated,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tactorId,\n\t\t\t\tname,\n\t\t\t\tkey,\n\t\t\t};\n\t\t} else if (\"error\" in result) {\n\t\t\tthrow new Error(`Error: ${JSON.stringify(result.error)}`);\n\t\t} else {\n\t\t\tassertUnreachable(result);\n\t\t}\n\t}\n\n\tasync createActor({\n\t\tc,\n\t\tname,\n\t\tkey,\n\t\tinput,\n\t}: CreateInput<{ Bindings: Bindings }>): Promise<ActorOutput> {\n\t\tconst env = getCloudflareAmbientEnv();\n\n\t\t// Create a deterministic ID from the actor name and key\n\t\t// This ensures that actors with the same name and key will have the same ID\n\t\tconst nameKeyString = serializeNameAndKey(name, key);\n\t\tconst doId = env.ACTOR_DO.idFromName(nameKeyString);\n\n\t\t// Create actor - this will fail if it already exists\n\t\tconst actor = env.ACTOR_DO.get(doId);\n\t\tconst result = await actor.create({\n\t\t\tname,\n\t\t\tkey,\n\t\t\tinput,\n\t\t\tallowExisting: false,\n\t\t});\n\n\t\tif (\"success\" in result) {\n\t\t\tconst { actorId } = result.success;\n\t\t\treturn {\n\t\t\t\tactorId,\n\t\t\t\tname,\n\t\t\t\tkey,\n\t\t\t};\n\t\t} else if (\"error\" in result) {\n\t\t\tif (result.error.actorAlreadyExists) {\n\t\t\t\tthrow new ActorDuplicateKey(name, key);\n\t\t\t}\n\n\t\t\tthrow new InternalError(\n\t\t\t\t`Unknown error creating actor: ${JSON.stringify(result.error)}`,\n\t\t\t);\n\t\t} else {\n\t\t\tassertUnreachable(result);\n\t\t}\n\t}\n\n\tasync listActors({ c, name }: ListActorsInput): Promise<ActorOutput[]> {\n\t\tlogger().warn({\n\t\t\tmsg: \"listActors not fully implemented for Cloudflare Workers\",\n\t\t\tname,\n\t\t});\n\t\treturn [];\n\t}\n\n\tdisplayInformation(): ManagerDisplayInformation {\n\t\treturn {\n\t\t\tname: \"Cloudflare Workers\",\n\t\t\tproperties: {},\n\t\t};\n\t}\n\n\tgetOrCreateInspectorAccessToken() {\n\t\treturn generateRandomString();\n\t}\n}\n","import { getLogger } from \"rivetkit/log\";\n\nexport function logger() {\n\treturn getLogger(\"driver-cloudflare-workers\");\n}\n","// Constants for key handling\nexport const EMPTY_KEY = \"(none)\";\nexport const KEY_SEPARATOR = \",\";\n\n/**\n * Serializes an array of key strings into a single string for use with idFromName\n *\n * @param name The actor name\n * @param key Array of key strings to serialize\n * @returns A single string containing the serialized name and key\n */\nexport function serializeNameAndKey(name: string, key: string[]): string {\n\t// Escape colons in the name\n\tconst escapedName = name.replace(/:/g, \"\\\\:\");\n\n\t// For empty keys, just return the name and a marker\n\tif (key.length === 0) {\n\t\treturn `${escapedName}:${EMPTY_KEY}`;\n\t}\n\n\t// Serialize the key array\n\tconst serializedKey = serializeKey(key);\n\n\t// Combine name and serialized key\n\treturn `${escapedName}:${serializedKey}`;\n}\n\n/**\n * Serializes an array of key strings into a single string\n *\n * @param key Array of key strings to serialize\n * @returns A single string containing the serialized key\n */\nexport function serializeKey(key: string[]): string {\n\t// Use a special marker for empty key arrays\n\tif (key.length === 0) {\n\t\treturn EMPTY_KEY;\n\t}\n\n\t// Escape each key part to handle the separator and the empty key marker\n\tconst escapedParts = key.map((part) => {\n\t\t// First check if it matches our empty key marker\n\t\tif (part === EMPTY_KEY) {\n\t\t\treturn `\\\\${EMPTY_KEY}`;\n\t\t}\n\n\t\t// Escape backslashes first, then commas\n\t\tlet escaped = part.replace(/\\\\/g, \"\\\\\\\\\");\n\t\tescaped = escaped.replace(/,/g, \"\\\\,\");\n\t\treturn escaped;\n\t});\n\n\treturn escapedParts.join(KEY_SEPARATOR);\n}\n\n/**\n * Deserializes a key string back into an array of key strings\n *\n * @param keyString The serialized key string\n * @returns Array of key strings\n */\nexport function deserializeKey(keyString: string): string[] {\n\t// Handle empty values\n\tif (!keyString) {\n\t\treturn [];\n\t}\n\n\t// Check for special empty key marker\n\tif (keyString === EMPTY_KEY) {\n\t\treturn [];\n\t}\n\n\t// Split by unescaped commas and unescape the escaped characters\n\tconst parts: string[] = [];\n\tlet currentPart = \"\";\n\tlet escaping = false;\n\n\tfor (let i = 0; i < keyString.length; i++) {\n\t\tconst char = keyString[i];\n\n\t\tif (escaping) {\n\t\t\t// This is an escaped character, add it directly\n\t\t\tcurrentPart += char;\n\t\t\tescaping = false;\n\t\t} else if (char === \"\\\\\") {\n\t\t\t// Start of an escape sequence\n\t\t\tescaping = true;\n\t\t} else if (char === KEY_SEPARATOR) {\n\t\t\t// This is a separator\n\t\t\tparts.push(currentPart);\n\t\t\tcurrentPart = \"\";\n\t\t} else {\n\t\t\t// Regular character\n\t\t\tcurrentPart += char;\n\t\t}\n\t}\n\n\t// Add the last part if it exists\n\tif (currentPart || parts.length > 0) {\n\t\tparts.push(currentPart);\n\t}\n\n\treturn parts;\n}\n","// Modified from https://github.com/honojs/hono/blob/40ea0eee58e39b31053a0246c595434f1094ad31/src/adapter/cloudflare-workers/websocket.ts#L17\n//\n// This version calls the open event by default\n\nimport type { UpgradeWebSocket, WSEvents, WSReadyState } from \"hono/ws\";\nimport { defineWebSocketHelper, WSContext } from \"hono/ws\";\nimport { WS_PROTOCOL_STANDARD } from \"rivetkit/driver-helpers\";\n\n// Based on https://github.com/honojs/hono/issues/1153#issuecomment-1767321332\nexport const upgradeWebSocket: UpgradeWebSocket<\n\tWebSocket,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tany,\n\tWSEvents<WebSocket>\n> = defineWebSocketHelper(async (c, events) => {\n\tconst upgradeHeader = c.req.header(\"Upgrade\");\n\tif (upgradeHeader !== \"websocket\") {\n\t\treturn;\n\t}\n\n\tconst webSocketPair = new WebSocketPair();\n\tconst client: WebSocket = webSocketPair[0];\n\tconst server: WebSocket = webSocketPair[1];\n\n\tconst wsContext = new WSContext<WebSocket>({\n\t\tclose: (code, reason) => server.close(code, reason),\n\t\tget protocol() {\n\t\t\treturn server.protocol;\n\t\t},\n\t\traw: server,\n\t\tget readyState() {\n\t\t\treturn server.readyState as WSReadyState;\n\t\t},\n\t\turl: server.url ? new URL(server.url) : null,\n\t\tsend: (source) => server.send(source),\n\t});\n\n\tif (events.onClose) {\n\t\tserver.addEventListener(\"close\", (evt: CloseEvent) =>\n\t\t\tevents.onClose?.(evt, wsContext),\n\t\t);\n\t}\n\tif (events.onMessage) {\n\t\tserver.addEventListener(\"message\", (evt: MessageEvent) =>\n\t\t\tevents.onMessage?.(evt, wsContext),\n\t\t);\n\t}\n\tif (events.onError) {\n\t\tserver.addEventListener(\"error\", (evt: Event) =>\n\t\t\tevents.onError?.(evt, wsContext),\n\t\t);\n\t}\n\n\tserver.accept?.();\n\n\t// note: cloudflare actors doesn't support 'open' event, so we call it immediately with a fake event\n\t//\n\t// we have to do this after `server.accept() is called`\n\tevents.onOpen?.(new Event(\"open\"), wsContext);\n\n\t// Build response headers\n\tconst headers: Record<string, string> = {};\n\n\t// Set Sec-WebSocket-Protocol if does not exist\n\tconst protocols = c.req.header(\"Sec-WebSocket-Protocol\");\n\tif (\n\t\ttypeof protocols === \"string\" &&\n\t\tprotocols\n\t\t\t.split(\",\")\n\t\t\t.map((x) => x.trim())\n\t\t\t.includes(WS_PROTOCOL_STANDARD)\n\t) {\n\t\theaders[\"Sec-WebSocket-Protocol\"] = WS_PROTOCOL_STANDARD;\n\t}\n\n\treturn new Response(null, {\n\t\tstatus: 101,\n\t\theaders,\n\t\twebSocket: client,\n\t});\n});\n"]}
|
package/dist/mod.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as rivetkit from 'rivetkit';
|
|
2
|
-
import { Client,
|
|
2
|
+
import { Client, Registry, RunConfig, ActorKey } from 'rivetkit';
|
|
3
3
|
export { Client } from 'rivetkit';
|
|
4
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
4
5
|
import * as rivetkit_utils from 'rivetkit/utils';
|
|
5
6
|
import * as rivetkit_log from 'rivetkit/log';
|
|
6
7
|
import * as rivetkit_driver_helpers from 'rivetkit/driver-helpers';
|
|
7
8
|
import { z } from 'zod';
|
|
8
|
-
import { DurableObject } from 'cloudflare:workers';
|
|
9
9
|
|
|
10
10
|
interface DriverContext {
|
|
11
11
|
state: DurableObjectState;
|
|
@@ -17,12 +17,12 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
17
17
|
manager: z.ZodType<(registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver, z.ZodTypeDef, (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver>;
|
|
18
18
|
actor: z.ZodType<(registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver, z.ZodTypeDef, (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver>;
|
|
19
19
|
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
21
20
|
name: string;
|
|
21
|
+
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
22
22
|
manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
|
|
23
23
|
}, {
|
|
24
|
-
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
25
24
|
name: string;
|
|
25
|
+
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
26
26
|
manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
|
|
27
27
|
}>>;
|
|
28
28
|
maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -109,10 +109,9 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
109
109
|
namespace: z.ZodDefault<z.ZodString>;
|
|
110
110
|
runnerName: z.ZodDefault<z.ZodString>;
|
|
111
111
|
encoding: z.ZodDefault<z.ZodEnum<["json", "cbor", "bare"]>>;
|
|
112
|
-
transport: z.ZodDefault<z.ZodEnum<["websocket", "sse"]>>;
|
|
113
112
|
headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
114
113
|
getUpgradeWebSocket: z.ZodOptional<z.ZodType<rivetkit_utils.GetUpgradeWebSocket, z.ZodTypeDef, rivetkit_utils.GetUpgradeWebSocket>>;
|
|
115
|
-
|
|
114
|
+
disableMetadataLookup: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
116
115
|
}, "driver" | "getUpgradeWebSocket"> & {
|
|
117
116
|
/** Path that the Rivet manager API will be mounted. */
|
|
118
117
|
managerPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -147,10 +146,12 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
147
146
|
namespace: string;
|
|
148
147
|
runnerName: string;
|
|
149
148
|
encoding: "json" | "cbor" | "bare";
|
|
150
|
-
transport: "websocket" | "sse";
|
|
151
149
|
headers: Record<string, string>;
|
|
152
|
-
|
|
150
|
+
disableMetadataLookup: boolean;
|
|
153
151
|
managerPath: string;
|
|
152
|
+
fetch?: ExportedHandlerFetchHandler<{
|
|
153
|
+
RIVET: Client<any>;
|
|
154
|
+
}, unknown> | undefined;
|
|
154
155
|
overrideServerAddress?: string | undefined;
|
|
155
156
|
autoConfigureServerless?: boolean | {
|
|
156
157
|
metadata?: Record<string, unknown> | undefined;
|
|
@@ -165,10 +166,10 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
165
166
|
runnerKey?: string | undefined;
|
|
166
167
|
endpoint?: string | undefined;
|
|
167
168
|
token?: string | undefined;
|
|
169
|
+
}, {
|
|
168
170
|
fetch?: ExportedHandlerFetchHandler<{
|
|
169
171
|
RIVET: Client<any>;
|
|
170
172
|
}, unknown> | undefined;
|
|
171
|
-
}, {
|
|
172
173
|
maxIncomingMessageSize?: number | undefined;
|
|
173
174
|
inspector?: {
|
|
174
175
|
enabled?: boolean | {
|
|
@@ -208,35 +209,74 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
208
209
|
namespace?: string | undefined;
|
|
209
210
|
runnerName?: string | undefined;
|
|
210
211
|
encoding?: "json" | "cbor" | "bare" | undefined;
|
|
211
|
-
transport?: "websocket" | "sse" | undefined;
|
|
212
212
|
headers?: Record<string, string> | undefined;
|
|
213
|
-
|
|
213
|
+
disableMetadataLookup?: boolean | undefined;
|
|
214
214
|
managerPath?: string | undefined;
|
|
215
|
-
fetch?: ExportedHandlerFetchHandler<{
|
|
216
|
-
RIVET: Client<any>;
|
|
217
|
-
}, unknown> | undefined;
|
|
218
215
|
}>>;
|
|
219
216
|
type InputConfig = z.input<typeof ConfigSchema>;
|
|
220
|
-
|
|
221
|
-
interface ActorHandlerInterface extends DurableObject {
|
|
222
|
-
initialize(req: ActorInitRequest): Promise<void>;
|
|
223
|
-
}
|
|
224
|
-
interface ActorInitRequest {
|
|
225
|
-
name: string;
|
|
226
|
-
key: ActorKey;
|
|
227
|
-
input?: unknown;
|
|
228
|
-
}
|
|
229
|
-
type DurableObjectConstructor = new (...args: ConstructorParameters<typeof DurableObject<Bindings>>) => DurableObject<Bindings>;
|
|
217
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
230
218
|
|
|
231
219
|
/** Cloudflare Workers env */
|
|
232
220
|
interface Bindings {
|
|
233
221
|
ACTOR_KV: KVNamespace;
|
|
234
222
|
ACTOR_DO: DurableObjectNamespace<ActorHandlerInterface>;
|
|
235
223
|
}
|
|
236
|
-
interface
|
|
224
|
+
interface InlineOutput<A extends Registry<any>> {
|
|
225
|
+
/** Client to communicate with the actors. */
|
|
226
|
+
client: Client<A>;
|
|
227
|
+
/** Fetch handler to manually route requests to the Rivet manager API. */
|
|
228
|
+
fetch: (request: Request, ...args: any) => Response | Promise<Response>;
|
|
229
|
+
config: Config;
|
|
230
|
+
ActorHandler: DurableObjectConstructor;
|
|
231
|
+
}
|
|
232
|
+
interface HandlerOutput {
|
|
237
233
|
handler: ExportedHandler<Bindings>;
|
|
238
234
|
ActorHandler: DurableObjectConstructor;
|
|
239
235
|
}
|
|
240
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Creates an inline client for accessing Rivet Actors privately without a public manager API.
|
|
238
|
+
*
|
|
239
|
+
* If you want to expose a public manager API, either:
|
|
240
|
+
*
|
|
241
|
+
* - Use `createHandler` to expose the Rivet API on `/rivet`
|
|
242
|
+
* - Forward Rivet API requests to `InlineOutput::fetch`
|
|
243
|
+
*/
|
|
244
|
+
declare function createInlineClient<R extends Registry<any>>(registry: R, inputConfig?: InputConfig): InlineOutput<R>;
|
|
245
|
+
/**
|
|
246
|
+
* Creates a handler to be exported from a Cloudflare Worker.
|
|
247
|
+
*
|
|
248
|
+
* This will automatically expose the Rivet manager API on `/rivet`.
|
|
249
|
+
*
|
|
250
|
+
* This includes a `fetch` handler and `ActorHandler` Durable Object.
|
|
251
|
+
*/
|
|
252
|
+
declare function createHandler<R extends Registry<any>>(registry: R, inputConfig?: InputConfig): HandlerOutput;
|
|
253
|
+
|
|
254
|
+
interface ActorHandlerInterface extends DurableObject {
|
|
255
|
+
create(req: ActorInitRequest): Promise<ActorInitResponse>;
|
|
256
|
+
getMetadata(): Promise<{
|
|
257
|
+
actorId: string;
|
|
258
|
+
name: string;
|
|
259
|
+
key: ActorKey;
|
|
260
|
+
destroying: boolean;
|
|
261
|
+
} | undefined>;
|
|
262
|
+
}
|
|
263
|
+
interface ActorInitRequest {
|
|
264
|
+
name: string;
|
|
265
|
+
key: ActorKey;
|
|
266
|
+
input?: unknown;
|
|
267
|
+
allowExisting: boolean;
|
|
268
|
+
}
|
|
269
|
+
type ActorInitResponse = {
|
|
270
|
+
success: {
|
|
271
|
+
actorId: string;
|
|
272
|
+
created: boolean;
|
|
273
|
+
};
|
|
274
|
+
} | {
|
|
275
|
+
error: {
|
|
276
|
+
actorAlreadyExists: true;
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
type DurableObjectConstructor = new (...args: ConstructorParameters<typeof DurableObject<Bindings>>) => DurableObject<Bindings>;
|
|
280
|
+
declare function createActorDurableObject(registry: Registry<any>, rootRunConfig: RunConfig): DurableObjectConstructor;
|
|
241
281
|
|
|
242
|
-
export { type Bindings, type InputConfig as Config, type DriverContext, createHandler };
|
|
282
|
+
export { type Bindings, type InputConfig as Config, type DriverContext, type HandlerOutput, type InlineOutput, createActorDurableObject, createHandler, createInlineClient };
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as rivetkit from 'rivetkit';
|
|
2
|
-
import { Client,
|
|
2
|
+
import { Client, Registry, RunConfig, ActorKey } from 'rivetkit';
|
|
3
3
|
export { Client } from 'rivetkit';
|
|
4
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
4
5
|
import * as rivetkit_utils from 'rivetkit/utils';
|
|
5
6
|
import * as rivetkit_log from 'rivetkit/log';
|
|
6
7
|
import * as rivetkit_driver_helpers from 'rivetkit/driver-helpers';
|
|
7
8
|
import { z } from 'zod';
|
|
8
|
-
import { DurableObject } from 'cloudflare:workers';
|
|
9
9
|
|
|
10
10
|
interface DriverContext {
|
|
11
11
|
state: DurableObjectState;
|
|
@@ -17,12 +17,12 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
17
17
|
manager: z.ZodType<(registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver, z.ZodTypeDef, (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver>;
|
|
18
18
|
actor: z.ZodType<(registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver, z.ZodTypeDef, (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver>;
|
|
19
19
|
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
21
20
|
name: string;
|
|
21
|
+
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
22
22
|
manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
|
|
23
23
|
}, {
|
|
24
|
-
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
25
24
|
name: string;
|
|
25
|
+
actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
|
|
26
26
|
manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
|
|
27
27
|
}>>;
|
|
28
28
|
maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -109,10 +109,9 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
109
109
|
namespace: z.ZodDefault<z.ZodString>;
|
|
110
110
|
runnerName: z.ZodDefault<z.ZodString>;
|
|
111
111
|
encoding: z.ZodDefault<z.ZodEnum<["json", "cbor", "bare"]>>;
|
|
112
|
-
transport: z.ZodDefault<z.ZodEnum<["websocket", "sse"]>>;
|
|
113
112
|
headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
114
113
|
getUpgradeWebSocket: z.ZodOptional<z.ZodType<rivetkit_utils.GetUpgradeWebSocket, z.ZodTypeDef, rivetkit_utils.GetUpgradeWebSocket>>;
|
|
115
|
-
|
|
114
|
+
disableMetadataLookup: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
116
115
|
}, "driver" | "getUpgradeWebSocket"> & {
|
|
117
116
|
/** Path that the Rivet manager API will be mounted. */
|
|
118
117
|
managerPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -147,10 +146,12 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
147
146
|
namespace: string;
|
|
148
147
|
runnerName: string;
|
|
149
148
|
encoding: "json" | "cbor" | "bare";
|
|
150
|
-
transport: "websocket" | "sse";
|
|
151
149
|
headers: Record<string, string>;
|
|
152
|
-
|
|
150
|
+
disableMetadataLookup: boolean;
|
|
153
151
|
managerPath: string;
|
|
152
|
+
fetch?: ExportedHandlerFetchHandler<{
|
|
153
|
+
RIVET: Client<any>;
|
|
154
|
+
}, unknown> | undefined;
|
|
154
155
|
overrideServerAddress?: string | undefined;
|
|
155
156
|
autoConfigureServerless?: boolean | {
|
|
156
157
|
metadata?: Record<string, unknown> | undefined;
|
|
@@ -165,10 +166,10 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
165
166
|
runnerKey?: string | undefined;
|
|
166
167
|
endpoint?: string | undefined;
|
|
167
168
|
token?: string | undefined;
|
|
169
|
+
}, {
|
|
168
170
|
fetch?: ExportedHandlerFetchHandler<{
|
|
169
171
|
RIVET: Client<any>;
|
|
170
172
|
}, unknown> | undefined;
|
|
171
|
-
}, {
|
|
172
173
|
maxIncomingMessageSize?: number | undefined;
|
|
173
174
|
inspector?: {
|
|
174
175
|
enabled?: boolean | {
|
|
@@ -208,35 +209,74 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
|
|
|
208
209
|
namespace?: string | undefined;
|
|
209
210
|
runnerName?: string | undefined;
|
|
210
211
|
encoding?: "json" | "cbor" | "bare" | undefined;
|
|
211
|
-
transport?: "websocket" | "sse" | undefined;
|
|
212
212
|
headers?: Record<string, string> | undefined;
|
|
213
|
-
|
|
213
|
+
disableMetadataLookup?: boolean | undefined;
|
|
214
214
|
managerPath?: string | undefined;
|
|
215
|
-
fetch?: ExportedHandlerFetchHandler<{
|
|
216
|
-
RIVET: Client<any>;
|
|
217
|
-
}, unknown> | undefined;
|
|
218
215
|
}>>;
|
|
219
216
|
type InputConfig = z.input<typeof ConfigSchema>;
|
|
220
|
-
|
|
221
|
-
interface ActorHandlerInterface extends DurableObject {
|
|
222
|
-
initialize(req: ActorInitRequest): Promise<void>;
|
|
223
|
-
}
|
|
224
|
-
interface ActorInitRequest {
|
|
225
|
-
name: string;
|
|
226
|
-
key: ActorKey;
|
|
227
|
-
input?: unknown;
|
|
228
|
-
}
|
|
229
|
-
type DurableObjectConstructor = new (...args: ConstructorParameters<typeof DurableObject<Bindings>>) => DurableObject<Bindings>;
|
|
217
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
230
218
|
|
|
231
219
|
/** Cloudflare Workers env */
|
|
232
220
|
interface Bindings {
|
|
233
221
|
ACTOR_KV: KVNamespace;
|
|
234
222
|
ACTOR_DO: DurableObjectNamespace<ActorHandlerInterface>;
|
|
235
223
|
}
|
|
236
|
-
interface
|
|
224
|
+
interface InlineOutput<A extends Registry<any>> {
|
|
225
|
+
/** Client to communicate with the actors. */
|
|
226
|
+
client: Client<A>;
|
|
227
|
+
/** Fetch handler to manually route requests to the Rivet manager API. */
|
|
228
|
+
fetch: (request: Request, ...args: any) => Response | Promise<Response>;
|
|
229
|
+
config: Config;
|
|
230
|
+
ActorHandler: DurableObjectConstructor;
|
|
231
|
+
}
|
|
232
|
+
interface HandlerOutput {
|
|
237
233
|
handler: ExportedHandler<Bindings>;
|
|
238
234
|
ActorHandler: DurableObjectConstructor;
|
|
239
235
|
}
|
|
240
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Creates an inline client for accessing Rivet Actors privately without a public manager API.
|
|
238
|
+
*
|
|
239
|
+
* If you want to expose a public manager API, either:
|
|
240
|
+
*
|
|
241
|
+
* - Use `createHandler` to expose the Rivet API on `/rivet`
|
|
242
|
+
* - Forward Rivet API requests to `InlineOutput::fetch`
|
|
243
|
+
*/
|
|
244
|
+
declare function createInlineClient<R extends Registry<any>>(registry: R, inputConfig?: InputConfig): InlineOutput<R>;
|
|
245
|
+
/**
|
|
246
|
+
* Creates a handler to be exported from a Cloudflare Worker.
|
|
247
|
+
*
|
|
248
|
+
* This will automatically expose the Rivet manager API on `/rivet`.
|
|
249
|
+
*
|
|
250
|
+
* This includes a `fetch` handler and `ActorHandler` Durable Object.
|
|
251
|
+
*/
|
|
252
|
+
declare function createHandler<R extends Registry<any>>(registry: R, inputConfig?: InputConfig): HandlerOutput;
|
|
253
|
+
|
|
254
|
+
interface ActorHandlerInterface extends DurableObject {
|
|
255
|
+
create(req: ActorInitRequest): Promise<ActorInitResponse>;
|
|
256
|
+
getMetadata(): Promise<{
|
|
257
|
+
actorId: string;
|
|
258
|
+
name: string;
|
|
259
|
+
key: ActorKey;
|
|
260
|
+
destroying: boolean;
|
|
261
|
+
} | undefined>;
|
|
262
|
+
}
|
|
263
|
+
interface ActorInitRequest {
|
|
264
|
+
name: string;
|
|
265
|
+
key: ActorKey;
|
|
266
|
+
input?: unknown;
|
|
267
|
+
allowExisting: boolean;
|
|
268
|
+
}
|
|
269
|
+
type ActorInitResponse = {
|
|
270
|
+
success: {
|
|
271
|
+
actorId: string;
|
|
272
|
+
created: boolean;
|
|
273
|
+
};
|
|
274
|
+
} | {
|
|
275
|
+
error: {
|
|
276
|
+
actorAlreadyExists: true;
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
type DurableObjectConstructor = new (...args: ConstructorParameters<typeof DurableObject<Bindings>>) => DurableObject<Bindings>;
|
|
280
|
+
declare function createActorDurableObject(registry: Registry<any>, rootRunConfig: RunConfig): DurableObjectConstructor;
|
|
241
281
|
|
|
242
|
-
export { type Bindings, type InputConfig as Config, type DriverContext, createHandler };
|
|
282
|
+
export { type Bindings, type InputConfig as Config, type DriverContext, type HandlerOutput, type InlineOutput, createActorDurableObject, createHandler, createInlineClient };
|