@rivetkit/cloudflare-workers 2.0.26 → 2.0.27

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 CHANGED
@@ -93,14 +93,11 @@ var GLOBAL_KV_KEYS = {
93
93
  // src/config.ts
94
94
 
95
95
  var _zod = require('zod');
96
- var ConfigSchemaBase = _driverhelpers.RunConfigSchema.removeDefault().omit({ driver: true, getUpgradeWebSocket: true }).extend({
96
+ var ConfigSchema = _driverhelpers.RunConfigSchema.removeDefault().omit({ driver: true, getUpgradeWebSocket: true }).extend({
97
97
  /** Path that the Rivet manager API will be mounted. */
98
98
  managerPath: _zod.z.string().optional().default("/rivet"),
99
99
  fetch: _zod.z.custom().optional()
100
- });
101
- var ConfigSchema = ConfigSchemaBase.default(
102
- () => ConfigSchemaBase.parse({})
103
- );
100
+ }).default({});
104
101
 
105
102
  // src/manager-driver.ts
106
103
 
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/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\nconst ConfigSchemaBase = 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});\nexport const ConfigSchema = ConfigSchemaBase.default(() =>\n\tConfigSchemaBase.parse({}),\n);\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"]}
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,48 +1,79 @@
1
+ import * as rivetkit from 'rivetkit';
1
2
  import { Client, Registry, RunConfig, ActorKey } from 'rivetkit';
2
3
  export { Client } from 'rivetkit';
3
4
  import { DurableObject } from 'cloudflare:workers';
5
+ import * as rivetkit_utils from 'rivetkit/utils';
4
6
  import * as rivetkit_log from 'rivetkit/log';
7
+ import * as rivetkit_driver_helpers from 'rivetkit/driver-helpers';
5
8
  import { z } from 'zod';
6
9
 
7
10
  interface DriverContext {
8
11
  state: DurableObjectState;
9
12
  }
10
13
 
11
- declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
14
+ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
15
+ driver: z.ZodOptional<z.ZodObject<{
16
+ name: z.ZodString;
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
+ 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
+ }, "strip", z.ZodTypeAny, {
20
+ name: string;
21
+ actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
22
+ manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
23
+ }, {
24
+ name: string;
25
+ actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
26
+ manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
27
+ }>>;
12
28
  maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
13
29
  inspector: z.ZodDefault<z.ZodOptional<z.ZodObject<{
14
30
  enabled: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
15
31
  actor: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
16
32
  manager: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
17
- }, z.core.$strip>]>>>;
18
- token: z.ZodDefault<z.ZodOptional<z.ZodCustom<() => string, () => string>>>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ actor: boolean;
35
+ manager: boolean;
36
+ }, {
37
+ actor?: boolean | undefined;
38
+ manager?: boolean | undefined;
39
+ }>]>>>;
40
+ token: z.ZodDefault<z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>>>;
19
41
  defaultEndpoint: z.ZodOptional<z.ZodString>;
20
- }, z.core.$strip>>>;
42
+ }, "strip", z.ZodTypeAny, {
43
+ enabled: boolean | {
44
+ actor: boolean;
45
+ manager: boolean;
46
+ };
47
+ token: (...args: unknown[]) => string;
48
+ defaultEndpoint?: string | undefined;
49
+ }, {
50
+ enabled?: boolean | {
51
+ actor?: boolean | undefined;
52
+ manager?: boolean | undefined;
53
+ } | undefined;
54
+ token?: ((...args: unknown[]) => string) | undefined;
55
+ defaultEndpoint?: string | undefined;
56
+ }>>>;
21
57
  disableDefaultServer: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
22
58
  defaultServerPort: z.ZodDefault<z.ZodNumber>;
23
59
  runEngine: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
24
60
  runEngineVersion: z.ZodDefault<z.ZodOptional<z.ZodString>>;
25
61
  overrideServerAddress: z.ZodOptional<z.ZodString>;
26
62
  disableActorDriver: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
27
- runnerKind: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
28
- serverless: "serverless";
29
- normal: "normal";
30
- }>>>;
63
+ runnerKind: z.ZodDefault<z.ZodOptional<z.ZodEnum<["serverless", "normal"]>>>;
31
64
  basePath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
32
65
  noWelcome: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
33
66
  logging: z.ZodDefault<z.ZodOptional<z.ZodObject<{
34
- baseLogger: z.ZodOptional<z.ZodCustom<rivetkit_log.Logger, rivetkit_log.Logger>>;
35
- level: z.ZodOptional<z.ZodEnum<{
36
- error: "error";
37
- trace: "trace";
38
- fatal: "fatal";
39
- warn: "warn";
40
- info: "info";
41
- debug: "debug";
42
- silent: "silent";
43
- }>>;
44
- }, z.core.$strip>>>;
45
- autoConfigureServerless: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
67
+ baseLogger: z.ZodOptional<z.ZodType<rivetkit_log.Logger, z.ZodTypeDef, rivetkit_log.Logger>>;
68
+ level: z.ZodOptional<z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal", "silent"]>>;
69
+ }, "strip", z.ZodTypeAny, {
70
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
71
+ baseLogger?: rivetkit_log.Logger | undefined;
72
+ }, {
73
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
74
+ baseLogger?: rivetkit_log.Logger | undefined;
75
+ }>>>;
76
+ autoConfigureServerless: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
46
77
  url: z.ZodOptional<z.ZodString>;
47
78
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
48
79
  maxRunners: z.ZodOptional<z.ZodNumber>;
@@ -51,27 +82,137 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
51
82
  runnersMargin: z.ZodOptional<z.ZodNumber>;
52
83
  slotsPerRunner: z.ZodOptional<z.ZodNumber>;
53
84
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
- }, z.core.$strip>]>>;
55
- runnerKey: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
85
+ }, "strip", z.ZodTypeAny, {
86
+ metadata?: Record<string, unknown> | undefined;
87
+ headers?: Record<string, string> | undefined;
88
+ url?: string | undefined;
89
+ maxRunners?: number | undefined;
90
+ minRunners?: number | undefined;
91
+ requestLifespan?: number | undefined;
92
+ runnersMargin?: number | undefined;
93
+ slotsPerRunner?: number | undefined;
94
+ }, {
95
+ metadata?: Record<string, unknown> | undefined;
96
+ headers?: Record<string, string> | undefined;
97
+ url?: string | undefined;
98
+ maxRunners?: number | undefined;
99
+ minRunners?: number | undefined;
100
+ requestLifespan?: number | undefined;
101
+ runnersMargin?: number | undefined;
102
+ slotsPerRunner?: number | undefined;
103
+ }>]>>;
104
+ } & {
105
+ runnerKey: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
56
106
  totalSlots: z.ZodDefault<z.ZodNumber>;
57
- endpoint: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
58
- token: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
107
+ endpoint: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
108
+ token: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
59
109
  namespace: z.ZodDefault<z.ZodString>;
60
110
  runnerName: z.ZodDefault<z.ZodString>;
61
- encoding: z.ZodDefault<z.ZodEnum<{
62
- json: "json";
63
- cbor: "cbor";
64
- bare: "bare";
65
- }>>;
111
+ encoding: z.ZodDefault<z.ZodEnum<["json", "cbor", "bare"]>>;
66
112
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
113
+ getUpgradeWebSocket: z.ZodOptional<z.ZodType<rivetkit_utils.GetUpgradeWebSocket, z.ZodTypeDef, rivetkit_utils.GetUpgradeWebSocket>>;
67
114
  disableMetadataLookup: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
115
+ }, "driver" | "getUpgradeWebSocket"> & {
116
+ /** Path that the Rivet manager API will be mounted. */
68
117
  managerPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
69
- fetch: z.ZodOptional<z.ZodCustom<ExportedHandlerFetchHandler<{
118
+ fetch: z.ZodOptional<z.ZodType<ExportedHandlerFetchHandler<{
70
119
  RIVET: Client<any>;
71
- }, unknown>, ExportedHandlerFetchHandler<{
120
+ }, unknown>, z.ZodTypeDef, ExportedHandlerFetchHandler<{
72
121
  RIVET: Client<any>;
73
122
  }, unknown>>>;
74
- }, z.core.$strip>>;
123
+ }, "strip", z.ZodTypeAny, {
124
+ maxIncomingMessageSize: number;
125
+ inspector: {
126
+ enabled: boolean | {
127
+ actor: boolean;
128
+ manager: boolean;
129
+ };
130
+ token: (...args: unknown[]) => string;
131
+ defaultEndpoint?: string | undefined;
132
+ };
133
+ disableDefaultServer: boolean;
134
+ defaultServerPort: number;
135
+ runEngine: boolean;
136
+ runEngineVersion: string;
137
+ disableActorDriver: boolean;
138
+ runnerKind: "serverless" | "normal";
139
+ basePath: string;
140
+ noWelcome: boolean;
141
+ logging: {
142
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
143
+ baseLogger?: rivetkit_log.Logger | undefined;
144
+ };
145
+ totalSlots: number;
146
+ namespace: string;
147
+ runnerName: string;
148
+ encoding: "json" | "cbor" | "bare";
149
+ headers: Record<string, string>;
150
+ disableMetadataLookup: boolean;
151
+ managerPath: string;
152
+ fetch?: ExportedHandlerFetchHandler<{
153
+ RIVET: Client<any>;
154
+ }, unknown> | undefined;
155
+ overrideServerAddress?: string | undefined;
156
+ autoConfigureServerless?: boolean | {
157
+ metadata?: Record<string, unknown> | undefined;
158
+ headers?: Record<string, string> | undefined;
159
+ url?: string | undefined;
160
+ maxRunners?: number | undefined;
161
+ minRunners?: number | undefined;
162
+ requestLifespan?: number | undefined;
163
+ runnersMargin?: number | undefined;
164
+ slotsPerRunner?: number | undefined;
165
+ } | undefined;
166
+ runnerKey?: string | undefined;
167
+ endpoint?: string | undefined;
168
+ token?: string | undefined;
169
+ }, {
170
+ fetch?: ExportedHandlerFetchHandler<{
171
+ RIVET: Client<any>;
172
+ }, unknown> | undefined;
173
+ maxIncomingMessageSize?: number | undefined;
174
+ inspector?: {
175
+ enabled?: boolean | {
176
+ actor?: boolean | undefined;
177
+ manager?: boolean | undefined;
178
+ } | undefined;
179
+ token?: ((...args: unknown[]) => string) | undefined;
180
+ defaultEndpoint?: string | undefined;
181
+ } | undefined;
182
+ disableDefaultServer?: boolean | undefined;
183
+ defaultServerPort?: number | undefined;
184
+ runEngine?: boolean | undefined;
185
+ runEngineVersion?: string | undefined;
186
+ overrideServerAddress?: string | undefined;
187
+ disableActorDriver?: boolean | undefined;
188
+ runnerKind?: "serverless" | "normal" | undefined;
189
+ basePath?: string | undefined;
190
+ noWelcome?: boolean | undefined;
191
+ logging?: {
192
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
193
+ baseLogger?: rivetkit_log.Logger | undefined;
194
+ } | undefined;
195
+ autoConfigureServerless?: boolean | {
196
+ metadata?: Record<string, unknown> | undefined;
197
+ headers?: Record<string, string> | undefined;
198
+ url?: string | undefined;
199
+ maxRunners?: number | undefined;
200
+ minRunners?: number | undefined;
201
+ requestLifespan?: number | undefined;
202
+ runnersMargin?: number | undefined;
203
+ slotsPerRunner?: number | undefined;
204
+ } | undefined;
205
+ runnerKey?: string | undefined;
206
+ totalSlots?: number | undefined;
207
+ endpoint?: string | undefined;
208
+ token?: string | undefined;
209
+ namespace?: string | undefined;
210
+ runnerName?: string | undefined;
211
+ encoding?: "json" | "cbor" | "bare" | undefined;
212
+ headers?: Record<string, string> | undefined;
213
+ disableMetadataLookup?: boolean | undefined;
214
+ managerPath?: string | undefined;
215
+ }>>;
75
216
  type InputConfig = z.input<typeof ConfigSchema>;
76
217
  type Config = z.infer<typeof ConfigSchema>;
77
218
 
package/dist/mod.d.ts CHANGED
@@ -1,48 +1,79 @@
1
+ import * as rivetkit from 'rivetkit';
1
2
  import { Client, Registry, RunConfig, ActorKey } from 'rivetkit';
2
3
  export { Client } from 'rivetkit';
3
4
  import { DurableObject } from 'cloudflare:workers';
5
+ import * as rivetkit_utils from 'rivetkit/utils';
4
6
  import * as rivetkit_log from 'rivetkit/log';
7
+ import * as rivetkit_driver_helpers from 'rivetkit/driver-helpers';
5
8
  import { z } from 'zod';
6
9
 
7
10
  interface DriverContext {
8
11
  state: DurableObjectState;
9
12
  }
10
13
 
11
- declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
14
+ declare const ConfigSchema: z.ZodDefault<z.ZodObject<Omit<{
15
+ driver: z.ZodOptional<z.ZodObject<{
16
+ name: z.ZodString;
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
+ 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
+ }, "strip", z.ZodTypeAny, {
20
+ name: string;
21
+ actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
22
+ manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
23
+ }, {
24
+ name: string;
25
+ actor: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig, managerDriver: rivetkit_driver_helpers.ManagerDriver, inlineClient: rivetkit.AnyClient) => rivetkit_driver_helpers.ActorDriver;
26
+ manager: (registryConfig: rivetkit.RegistryConfig, runConfig: rivetkit.RunConfig) => rivetkit_driver_helpers.ManagerDriver;
27
+ }>>;
12
28
  maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
13
29
  inspector: z.ZodDefault<z.ZodOptional<z.ZodObject<{
14
30
  enabled: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
15
31
  actor: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
16
32
  manager: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
17
- }, z.core.$strip>]>>>;
18
- token: z.ZodDefault<z.ZodOptional<z.ZodCustom<() => string, () => string>>>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ actor: boolean;
35
+ manager: boolean;
36
+ }, {
37
+ actor?: boolean | undefined;
38
+ manager?: boolean | undefined;
39
+ }>]>>>;
40
+ token: z.ZodDefault<z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>>>;
19
41
  defaultEndpoint: z.ZodOptional<z.ZodString>;
20
- }, z.core.$strip>>>;
42
+ }, "strip", z.ZodTypeAny, {
43
+ enabled: boolean | {
44
+ actor: boolean;
45
+ manager: boolean;
46
+ };
47
+ token: (...args: unknown[]) => string;
48
+ defaultEndpoint?: string | undefined;
49
+ }, {
50
+ enabled?: boolean | {
51
+ actor?: boolean | undefined;
52
+ manager?: boolean | undefined;
53
+ } | undefined;
54
+ token?: ((...args: unknown[]) => string) | undefined;
55
+ defaultEndpoint?: string | undefined;
56
+ }>>>;
21
57
  disableDefaultServer: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
22
58
  defaultServerPort: z.ZodDefault<z.ZodNumber>;
23
59
  runEngine: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
24
60
  runEngineVersion: z.ZodDefault<z.ZodOptional<z.ZodString>>;
25
61
  overrideServerAddress: z.ZodOptional<z.ZodString>;
26
62
  disableActorDriver: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
27
- runnerKind: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
28
- serverless: "serverless";
29
- normal: "normal";
30
- }>>>;
63
+ runnerKind: z.ZodDefault<z.ZodOptional<z.ZodEnum<["serverless", "normal"]>>>;
31
64
  basePath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
32
65
  noWelcome: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
33
66
  logging: z.ZodDefault<z.ZodOptional<z.ZodObject<{
34
- baseLogger: z.ZodOptional<z.ZodCustom<rivetkit_log.Logger, rivetkit_log.Logger>>;
35
- level: z.ZodOptional<z.ZodEnum<{
36
- error: "error";
37
- trace: "trace";
38
- fatal: "fatal";
39
- warn: "warn";
40
- info: "info";
41
- debug: "debug";
42
- silent: "silent";
43
- }>>;
44
- }, z.core.$strip>>>;
45
- autoConfigureServerless: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
67
+ baseLogger: z.ZodOptional<z.ZodType<rivetkit_log.Logger, z.ZodTypeDef, rivetkit_log.Logger>>;
68
+ level: z.ZodOptional<z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal", "silent"]>>;
69
+ }, "strip", z.ZodTypeAny, {
70
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
71
+ baseLogger?: rivetkit_log.Logger | undefined;
72
+ }, {
73
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
74
+ baseLogger?: rivetkit_log.Logger | undefined;
75
+ }>>>;
76
+ autoConfigureServerless: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
46
77
  url: z.ZodOptional<z.ZodString>;
47
78
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
48
79
  maxRunners: z.ZodOptional<z.ZodNumber>;
@@ -51,27 +82,137 @@ declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
51
82
  runnersMargin: z.ZodOptional<z.ZodNumber>;
52
83
  slotsPerRunner: z.ZodOptional<z.ZodNumber>;
53
84
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
- }, z.core.$strip>]>>;
55
- runnerKey: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
85
+ }, "strip", z.ZodTypeAny, {
86
+ metadata?: Record<string, unknown> | undefined;
87
+ headers?: Record<string, string> | undefined;
88
+ url?: string | undefined;
89
+ maxRunners?: number | undefined;
90
+ minRunners?: number | undefined;
91
+ requestLifespan?: number | undefined;
92
+ runnersMargin?: number | undefined;
93
+ slotsPerRunner?: number | undefined;
94
+ }, {
95
+ metadata?: Record<string, unknown> | undefined;
96
+ headers?: Record<string, string> | undefined;
97
+ url?: string | undefined;
98
+ maxRunners?: number | undefined;
99
+ minRunners?: number | undefined;
100
+ requestLifespan?: number | undefined;
101
+ runnersMargin?: number | undefined;
102
+ slotsPerRunner?: number | undefined;
103
+ }>]>>;
104
+ } & {
105
+ runnerKey: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
56
106
  totalSlots: z.ZodDefault<z.ZodNumber>;
57
- endpoint: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
58
- token: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
107
+ endpoint: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
108
+ token: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
59
109
  namespace: z.ZodDefault<z.ZodString>;
60
110
  runnerName: z.ZodDefault<z.ZodString>;
61
- encoding: z.ZodDefault<z.ZodEnum<{
62
- json: "json";
63
- cbor: "cbor";
64
- bare: "bare";
65
- }>>;
111
+ encoding: z.ZodDefault<z.ZodEnum<["json", "cbor", "bare"]>>;
66
112
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
113
+ getUpgradeWebSocket: z.ZodOptional<z.ZodType<rivetkit_utils.GetUpgradeWebSocket, z.ZodTypeDef, rivetkit_utils.GetUpgradeWebSocket>>;
67
114
  disableMetadataLookup: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
115
+ }, "driver" | "getUpgradeWebSocket"> & {
116
+ /** Path that the Rivet manager API will be mounted. */
68
117
  managerPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
69
- fetch: z.ZodOptional<z.ZodCustom<ExportedHandlerFetchHandler<{
118
+ fetch: z.ZodOptional<z.ZodType<ExportedHandlerFetchHandler<{
70
119
  RIVET: Client<any>;
71
- }, unknown>, ExportedHandlerFetchHandler<{
120
+ }, unknown>, z.ZodTypeDef, ExportedHandlerFetchHandler<{
72
121
  RIVET: Client<any>;
73
122
  }, unknown>>>;
74
- }, z.core.$strip>>;
123
+ }, "strip", z.ZodTypeAny, {
124
+ maxIncomingMessageSize: number;
125
+ inspector: {
126
+ enabled: boolean | {
127
+ actor: boolean;
128
+ manager: boolean;
129
+ };
130
+ token: (...args: unknown[]) => string;
131
+ defaultEndpoint?: string | undefined;
132
+ };
133
+ disableDefaultServer: boolean;
134
+ defaultServerPort: number;
135
+ runEngine: boolean;
136
+ runEngineVersion: string;
137
+ disableActorDriver: boolean;
138
+ runnerKind: "serverless" | "normal";
139
+ basePath: string;
140
+ noWelcome: boolean;
141
+ logging: {
142
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
143
+ baseLogger?: rivetkit_log.Logger | undefined;
144
+ };
145
+ totalSlots: number;
146
+ namespace: string;
147
+ runnerName: string;
148
+ encoding: "json" | "cbor" | "bare";
149
+ headers: Record<string, string>;
150
+ disableMetadataLookup: boolean;
151
+ managerPath: string;
152
+ fetch?: ExportedHandlerFetchHandler<{
153
+ RIVET: Client<any>;
154
+ }, unknown> | undefined;
155
+ overrideServerAddress?: string | undefined;
156
+ autoConfigureServerless?: boolean | {
157
+ metadata?: Record<string, unknown> | undefined;
158
+ headers?: Record<string, string> | undefined;
159
+ url?: string | undefined;
160
+ maxRunners?: number | undefined;
161
+ minRunners?: number | undefined;
162
+ requestLifespan?: number | undefined;
163
+ runnersMargin?: number | undefined;
164
+ slotsPerRunner?: number | undefined;
165
+ } | undefined;
166
+ runnerKey?: string | undefined;
167
+ endpoint?: string | undefined;
168
+ token?: string | undefined;
169
+ }, {
170
+ fetch?: ExportedHandlerFetchHandler<{
171
+ RIVET: Client<any>;
172
+ }, unknown> | undefined;
173
+ maxIncomingMessageSize?: number | undefined;
174
+ inspector?: {
175
+ enabled?: boolean | {
176
+ actor?: boolean | undefined;
177
+ manager?: boolean | undefined;
178
+ } | undefined;
179
+ token?: ((...args: unknown[]) => string) | undefined;
180
+ defaultEndpoint?: string | undefined;
181
+ } | undefined;
182
+ disableDefaultServer?: boolean | undefined;
183
+ defaultServerPort?: number | undefined;
184
+ runEngine?: boolean | undefined;
185
+ runEngineVersion?: string | undefined;
186
+ overrideServerAddress?: string | undefined;
187
+ disableActorDriver?: boolean | undefined;
188
+ runnerKind?: "serverless" | "normal" | undefined;
189
+ basePath?: string | undefined;
190
+ noWelcome?: boolean | undefined;
191
+ logging?: {
192
+ level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
193
+ baseLogger?: rivetkit_log.Logger | undefined;
194
+ } | undefined;
195
+ autoConfigureServerless?: boolean | {
196
+ metadata?: Record<string, unknown> | undefined;
197
+ headers?: Record<string, string> | undefined;
198
+ url?: string | undefined;
199
+ maxRunners?: number | undefined;
200
+ minRunners?: number | undefined;
201
+ requestLifespan?: number | undefined;
202
+ runnersMargin?: number | undefined;
203
+ slotsPerRunner?: number | undefined;
204
+ } | undefined;
205
+ runnerKey?: string | undefined;
206
+ totalSlots?: number | undefined;
207
+ endpoint?: string | undefined;
208
+ token?: string | undefined;
209
+ namespace?: string | undefined;
210
+ runnerName?: string | undefined;
211
+ encoding?: "json" | "cbor" | "bare" | undefined;
212
+ headers?: Record<string, string> | undefined;
213
+ disableMetadataLookup?: boolean | undefined;
214
+ managerPath?: string | undefined;
215
+ }>>;
75
216
  type InputConfig = z.input<typeof ConfigSchema>;
76
217
  type Config = z.infer<typeof ConfigSchema>;
77
218
 
package/dist/mod.js CHANGED
@@ -93,14 +93,11 @@ import { env } from "cloudflare:workers";
93
93
  // src/config.ts
94
94
  import { RunConfigSchema } from "rivetkit/driver-helpers";
95
95
  import { z } from "zod";
96
- var ConfigSchemaBase = RunConfigSchema.removeDefault().omit({ driver: true, getUpgradeWebSocket: true }).extend({
96
+ var ConfigSchema = RunConfigSchema.removeDefault().omit({ driver: true, getUpgradeWebSocket: true }).extend({
97
97
  /** Path that the Rivet manager API will be mounted. */
98
98
  managerPath: z.string().optional().default("/rivet"),
99
99
  fetch: z.custom().optional()
100
- });
101
- var ConfigSchema = ConfigSchemaBase.default(
102
- () => ConfigSchemaBase.parse({})
103
- );
100
+ }).default({});
104
101
 
105
102
  // src/manager-driver.ts
106
103
  import {
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../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"],"sourcesContent":["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\nconst ConfigSchemaBase = 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});\nexport const ConfigSchema = ConfigSchemaBase.default(() =>\n\tConfigSchemaBase.parse({}),\n);\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"],"mappings":"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","names":["env","invariant","env","WS_PROTOCOL_STANDARD","_a","env","env","invariant","env","doId","actorId"]}
1
+ {"version":3,"sources":["../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"],"sourcesContent":["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"],"mappings":"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","names":["env","invariant","env","WS_PROTOCOL_STANDARD","_a","env","env","invariant","env","doId","actorId"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivetkit/cloudflare-workers",
3
- "version": "2.0.26",
3
+ "version": "2.0.27",
4
4
  "description": "Cloudflare Workers adapter for RivetKit actors",
5
5
  "keywords": [
6
6
  "rivetkit",
@@ -44,9 +44,9 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "invariant": "^2.2.4",
47
- "zod": "^4.1.0",
47
+ "zod": "^3.25.76",
48
48
  "hono": "^4.7.0",
49
- "rivetkit": "2.0.26"
49
+ "rivetkit": "2.0.27"
50
50
  },
51
51
  "stableVersion": "0.8.0",
52
52
  "scripts": {
package/src/config.ts CHANGED
@@ -2,7 +2,7 @@ import type { Client } from "rivetkit";
2
2
  import { RunConfigSchema } from "rivetkit/driver-helpers";
3
3
  import { z } from "zod";
4
4
 
5
- const ConfigSchemaBase = RunConfigSchema.removeDefault()
5
+ export const ConfigSchema = RunConfigSchema.removeDefault()
6
6
  .omit({ driver: true, getUpgradeWebSocket: true })
7
7
  .extend({
8
8
  /** Path that the Rivet manager API will be mounted. */
@@ -13,9 +13,7 @@ const ConfigSchemaBase = RunConfigSchema.removeDefault()
13
13
  ExportedHandlerFetchHandler<{ RIVET: Client<any> }, unknown>
14
14
  >()
15
15
  .optional(),
16
- });
17
- export const ConfigSchema = ConfigSchemaBase.default(() =>
18
- ConfigSchemaBase.parse({}),
19
- );
16
+ })
17
+ .default({});
20
18
  export type InputConfig = z.input<typeof ConfigSchema>;
21
19
  export type Config = z.infer<typeof ConfigSchema>;