rivetkit 2.0.3 → 2.0.4
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/README.md +11 -0
- package/dist/schemas/actor-persist/v1.ts +21 -24
- package/dist/schemas/client-protocol/v1.ts +6 -0
- package/dist/tsup/actor/errors.cjs +10 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +17 -4
- package/dist/tsup/actor/errors.d.ts +17 -4
- package/dist/tsup/actor/errors.js +11 -3
- package/dist/tsup/{chunk-6PDXBYI5.js → chunk-3F2YSRJL.js} +8 -23
- package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
- package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
- package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
- package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
- package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
- package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-6LJT3QRL.cjs} +39 -25
- package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
- package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-GICQ3YCU.cjs} +143 -141
- package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
- package/dist/tsup/{chunk-FLMTTN27.js → chunk-H26RP6GD.js} +15 -8
- package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
- package/dist/tsup/chunk-HI3HWJRC.js +20 -0
- package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
- package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-HLLF4B4Q.js} +116 -114
- package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
- package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-IH6CKNDW.cjs} +12 -27
- package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
- package/dist/tsup/chunk-LV2S3OU3.js +250 -0
- package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
- package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LWNKVZG5.cjs} +20 -13
- package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
- package/dist/tsup/{chunk-INGJP237.js → chunk-NFU2BBT5.js} +102 -43
- package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
- package/dist/tsup/{chunk-3H7O2A7I.js → chunk-PQY7KKTL.js} +33 -19
- package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
- package/dist/tsup/{chunk-PO4VLDWA.js → chunk-QK72M5JB.js} +3 -5
- package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
- package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-QNNXFOQV.cjs} +3 -5
- package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
- package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-SBHHJ6QS.cjs} +102 -43
- package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
- package/dist/tsup/chunk-TQ62L3X7.js +325 -0
- package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
- package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
- package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
- package/dist/tsup/client/mod.cjs +10 -10
- package/dist/tsup/client/mod.d.cts +7 -13
- package/dist/tsup/client/mod.d.ts +7 -13
- package/dist/tsup/client/mod.js +9 -9
- package/dist/tsup/common/log.cjs +12 -4
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.d.cts +23 -17
- package/dist/tsup/common/log.d.ts +23 -17
- package/dist/tsup/common/log.js +15 -7
- package/dist/tsup/common/websocket.cjs +5 -5
- package/dist/tsup/common/websocket.js +4 -4
- package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
- package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
- package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BI-6UIBJ.d.ts} +196 -226
- package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-Dyd4NLGW.d.cts} +196 -226
- package/dist/tsup/driver-helpers/mod.cjs +6 -9
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +5 -6
- package/dist/tsup/driver-helpers/mod.d.ts +5 -6
- package/dist/tsup/driver-helpers/mod.js +6 -9
- package/dist/tsup/driver-test-suite/mod.cjs +155 -1363
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +11 -5
- package/dist/tsup/driver-test-suite/mod.d.ts +11 -5
- package/dist/tsup/driver-test-suite/mod.js +876 -2084
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -8
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +3 -3
- package/dist/tsup/inspector/mod.d.ts +3 -3
- package/dist/tsup/inspector/mod.js +8 -10
- package/dist/tsup/mod.cjs +9 -15
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +47 -42
- package/dist/tsup/mod.d.ts +47 -42
- package/dist/tsup/mod.js +10 -16
- package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-BTe_Rsdn.d.cts} +2 -3
- package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-CBSrKHmo.d.ts} +2 -3
- package/dist/tsup/test/mod.cjs +10 -14
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -5
- package/dist/tsup/test/mod.d.ts +4 -5
- package/dist/tsup/test/mod.js +9 -13
- package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
- package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +2 -2
- package/package.json +4 -4
- package/src/actor/action.ts +1 -5
- package/src/actor/config.ts +27 -295
- package/src/actor/connection.ts +9 -12
- package/src/actor/context.ts +1 -4
- package/src/actor/definition.ts +7 -11
- package/src/actor/errors.ts +97 -35
- package/src/actor/generic-conn-driver.ts +28 -16
- package/src/actor/instance.ts +177 -133
- package/src/actor/log.ts +4 -13
- package/src/actor/mod.ts +0 -5
- package/src/actor/protocol/old.ts +42 -26
- package/src/actor/protocol/serde.ts +1 -1
- package/src/actor/router-endpoints.ts +41 -38
- package/src/actor/router.ts +20 -18
- package/src/actor/unstable-react.ts +1 -1
- package/src/actor/utils.ts +6 -2
- package/src/client/actor-common.ts +1 -1
- package/src/client/actor-conn.ts +152 -91
- package/src/client/actor-handle.ts +85 -25
- package/src/client/actor-query.ts +65 -0
- package/src/client/client.ts +29 -98
- package/src/client/config.ts +44 -0
- package/src/client/errors.ts +1 -0
- package/src/client/log.ts +2 -4
- package/src/client/mod.ts +16 -12
- package/src/client/raw-utils.ts +82 -25
- package/src/client/utils.ts +5 -3
- package/src/common/fake-event-source.ts +10 -9
- package/src/common/inline-websocket-adapter2.ts +39 -30
- package/src/common/log.ts +176 -101
- package/src/common/logfmt.ts +21 -30
- package/src/common/router.ts +12 -19
- package/src/common/utils.ts +27 -13
- package/src/common/websocket.ts +0 -1
- package/src/driver-helpers/mod.ts +1 -1
- package/src/driver-test-suite/log.ts +1 -3
- package/src/driver-test-suite/mod.ts +86 -60
- package/src/driver-test-suite/tests/actor-handle.ts +33 -0
- package/src/driver-test-suite/tests/manager-driver.ts +5 -3
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
- package/src/driver-test-suite/tests/request-access.ts +112 -126
- package/src/driver-test-suite/utils.ts +13 -10
- package/src/drivers/default.ts +7 -4
- package/src/drivers/engine/actor-driver.ts +22 -13
- package/src/drivers/engine/config.ts +2 -10
- package/src/drivers/engine/kv.ts +1 -1
- package/src/drivers/engine/log.ts +1 -3
- package/src/drivers/engine/mod.ts +2 -3
- package/src/drivers/file-system/actor.ts +1 -1
- package/src/drivers/file-system/global-state.ts +33 -20
- package/src/drivers/file-system/log.ts +1 -3
- package/src/drivers/file-system/manager.ts +31 -8
- package/src/inspector/config.ts +9 -4
- package/src/inspector/log.ts +1 -1
- package/src/inspector/manager.ts +2 -2
- package/src/inspector/utils.ts +1 -1
- package/src/manager/driver.ts +10 -2
- package/src/manager/hono-websocket-adapter.ts +21 -12
- package/src/manager/log.ts +2 -4
- package/src/manager/mod.ts +1 -1
- package/src/manager/router.ts +277 -1657
- package/src/manager-api/routes/actors-create.ts +16 -0
- package/src/manager-api/routes/actors-delete.ts +4 -0
- package/src/manager-api/routes/actors-get-by-id.ts +7 -0
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
- package/src/manager-api/routes/actors-get.ts +7 -0
- package/src/manager-api/routes/common.ts +18 -0
- package/src/mod.ts +0 -2
- package/src/registry/config.ts +1 -1
- package/src/registry/log.ts +2 -4
- package/src/registry/mod.ts +57 -24
- package/src/registry/run-config.ts +31 -33
- package/src/registry/serve.ts +4 -5
- package/src/remote-manager-driver/actor-http-client.ts +72 -0
- package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
- package/src/remote-manager-driver/api-endpoints.ts +79 -0
- package/src/remote-manager-driver/api-utils.ts +43 -0
- package/src/remote-manager-driver/log.ts +5 -0
- package/src/remote-manager-driver/mod.ts +274 -0
- package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
- package/src/serde.ts +8 -2
- package/src/test/log.ts +1 -3
- package/src/test/mod.ts +17 -16
- package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
- package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
- package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
- package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
- package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
- package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
- package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
- package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
- package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
- package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
- package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
- package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
- package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
- package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
- package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
- package/dist/tsup/chunk-INGJP237.js.map +0 -1
- package/dist/tsup/chunk-KJCJLKRM.js +0 -116
- package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
- package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
- package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
- package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
- package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
- package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
- package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
- package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
- package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
- package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
- package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
- package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
- package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
- package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
- package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
- package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
- package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
- package/dist/tsup/chunk-UVUPOS46.js +0 -230
- package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
- package/dist/tsup/chunk-VRRHBNJC.js +0 -189
- package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
- package/dist/tsup/chunk-XFSS33EQ.js +0 -202
- package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
- package/src/client/http-client-driver.ts +0 -326
- package/src/driver-test-suite/test-inline-client-driver.ts +0 -402
- package/src/driver-test-suite/tests/actor-auth.ts +0 -591
- package/src/drivers/engine/api-endpoints.ts +0 -128
- package/src/drivers/engine/api-utils.ts +0 -70
- package/src/drivers/engine/manager-driver.ts +0 -391
- package/src/inline-client-driver/log.ts +0 -7
- package/src/inline-client-driver/mod.ts +0 -385
- package/src/manager/auth.ts +0 -121
- /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
- /package/src/{drivers/engine → actor}/keys.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-O2MBYIXO.cjs","../../src/actor/instance.ts","../../src/inspector/actor.ts","../../src/actor/context.ts","../../src/actor/schedule.ts","../../src/actor/definition.ts","../../src/client/errors.ts","../../src/client/actor-conn.ts","../../src/client/actor-handle.ts","../../src/client/raw-utils.ts","../../src/client/client.ts","../../src/client/utils.ts","../../src/common/eventsource.ts"],"names":["opts","InternalError"],"mappings":"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","file":"/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-O2MBYIXO.cjs","sourcesContent":[null,"import * as cbor from \"cbor-x\";\nimport invariant from \"invariant\";\nimport onChange from \"on-change\";\nimport type { ActorKey } from \"@/actor/mod\";\nimport type { Client } from \"@/client/client\";\nimport type { Logger } from \"@/common/log\";\nimport { isCborSerializable, stringifyError } from \"@/common/utils\";\nimport type { UniversalWebSocket } from \"@/common/websocket-interface\";\nimport { ActorInspector } from \"@/inspector/actor\";\nimport type { Registry } from \"@/mod\";\nimport type * as bareSchema from \"@/schemas/actor-persist/mod\";\nimport { PERSISTED_ACTOR_VERSIONED } from \"@/schemas/actor-persist/versioned\";\nimport type * as protocol from \"@/schemas/client-protocol/mod\";\nimport { TO_CLIENT_VERSIONED } from \"@/schemas/client-protocol/versioned\";\nimport { bufferToArrayBuffer, SinglePromiseQueue } from \"@/utils\";\nimport type { ActionContext } from \"./action\";\nimport type { ActorConfig, OnConnectOptions } from \"./config\";\nimport {\n\tCONNECTION_CHECK_LIVENESS_SYMBOL,\n\tConn,\n\ttype ConnectionDriver,\n\ttype ConnId,\n} from \"./connection\";\nimport { ActorContext } from \"./context\";\nimport type { AnyDatabaseProvider, InferDatabaseClient } from \"./database\";\nimport type { ActorDriver, ConnDriver, ConnectionDriversMap } from \"./driver\";\nimport * as errors from \"./errors\";\nimport { instanceLogger, logger } from \"./log\";\nimport type {\n\tPersistedActor,\n\tPersistedConn,\n\tPersistedScheduleEvent,\n} from \"./persisted\";\nimport { processMessage } from \"./protocol/old\";\nimport { CachedSerializer } from \"./protocol/serde\";\nimport { Schedule } from \"./schedule\";\nimport { DeadlineError, deadline } from \"./utils\";\n\n/**\n * Options for the `_saveState` method.\n */\nexport interface SaveStateOptions {\n\t/**\n\t * Forces the state to be saved immediately. This function will return when the state has saved successfully.\n\t */\n\timmediate?: boolean;\n\t/** Bypass ready check for stopping. */\n\tallowStoppingState?: boolean;\n}\n\n/** Actor type alias with all `any` types. Used for `extends` in classes referencing this actor. */\nexport type AnyActorInstance = ActorInstance<\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany,\n\t// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`\n\tany\n>;\n\nexport type ExtractActorState<A extends AnyActorInstance> =\n\tA extends ActorInstance<\n\t\tinfer State,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany\n\t>\n\t\t? State\n\t\t: never;\n\nexport type ExtractActorConnParams<A extends AnyActorInstance> =\n\tA extends ActorInstance<\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\tinfer ConnParams,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany\n\t>\n\t\t? ConnParams\n\t\t: never;\n\nexport type ExtractActorConnState<A extends AnyActorInstance> =\n\tA extends ActorInstance<\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\tinfer ConnState,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`\n\t\tany\n\t>\n\t\t? ConnState\n\t\t: never;\n\nexport class ActorInstance<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tAD,\n\tDB extends AnyDatabaseProvider,\n> {\n\t// Shared actor context for this instance\n\tactorContext: ActorContext<S, CP, CS, V, I, AD, DB>;\n\t#sleepCalled = false;\n\t#stopCalled = false;\n\n\tget isStopping() {\n\t\treturn this.#stopCalled || this.#sleepCalled;\n\t}\n\n\t#persistChanged = false;\n\t#isInOnStateChange = false;\n\n\t/**\n\t * The proxied state that notifies of changes automatically.\n\t *\n\t * Any data that should be stored indefinitely should be held within this object.\n\t */\n\t#persist!: PersistedActor<S, CP, CS, I>;\n\n\t/** Raw state without the proxy wrapper */\n\t#persistRaw!: PersistedActor<S, CP, CS, I>;\n\n\t#persistWriteQueue = new SinglePromiseQueue();\n\t#alarmWriteQueue = new SinglePromiseQueue();\n\n\t#lastSaveTime = 0;\n\t#pendingSaveTimeout?: NodeJS.Timeout;\n\n\t#vars?: V;\n\n\t#backgroundPromises: Promise<void>[] = [];\n\t#abortController = new AbortController();\n\t#config: ActorConfig<S, CP, CS, V, I, AD, DB>;\n\t#connectionDrivers!: ConnectionDriversMap;\n\t#actorDriver!: ActorDriver;\n\t#inlineClient!: Client<Registry<any>>;\n\t#actorId!: string;\n\t#name!: string;\n\t#key!: ActorKey;\n\t#region!: string;\n\t#ready = false;\n\n\t#connections = new Map<ConnId, Conn<S, CP, CS, V, I, AD, DB>>();\n\t#subscriptionIndex = new Map<string, Set<Conn<S, CP, CS, V, I, AD, DB>>>();\n\t#checkConnLivenessInterval?: NodeJS.Timeout;\n\n\t#sleepTimeout?: NodeJS.Timeout;\n\n\t// Track active raw requests so sleep logic can account for them\n\t#activeRawFetchCount = 0;\n\t#activeRawWebSockets = new Set<UniversalWebSocket>();\n\n\t#schedule!: Schedule;\n\t#db!: InferDatabaseClient<DB>;\n\n\t#inspector = new ActorInspector(() => {\n\t\treturn {\n\t\t\tisDbEnabled: async () => {\n\t\t\t\treturn this.#db !== undefined;\n\t\t\t},\n\t\t\tgetDb: async () => {\n\t\t\t\treturn this.db;\n\t\t\t},\n\t\t\tisStateEnabled: async () => {\n\t\t\t\treturn this.stateEnabled;\n\t\t\t},\n\t\t\tgetState: async () => {\n\t\t\t\tthis.#validateStateEnabled();\n\n\t\t\t\t// Must return from `#persistRaw` in order to not return the `onchange` proxy\n\t\t\t\treturn this.#persistRaw.state as Record<string, any> as unknown;\n\t\t\t},\n\t\t\tgetRpcs: async () => {\n\t\t\t\treturn Object.keys(this.#config.actions);\n\t\t\t},\n\t\t\tgetConnections: async () => {\n\t\t\t\treturn Array.from(this.#connections.entries()).map(([id, conn]) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tstateEnabled: conn._stateEnabled,\n\t\t\t\t\tparams: conn.params as {},\n\t\t\t\t\tstate: conn._stateEnabled ? conn.state : undefined,\n\t\t\t\t\tauth: conn.auth as {},\n\t\t\t\t}));\n\t\t\t},\n\t\t\tsetState: async (state: unknown) => {\n\t\t\t\tthis.#validateStateEnabled();\n\n\t\t\t\t// Must set on `#persist` instead of `#persistRaw` in order to ensure that the `Proxy` is correctly configured\n\t\t\t\t//\n\t\t\t\t// We have to use `...` so `on-change` recognizes the changes to `state` (i.e. set #persistChanged` to true). This is because:\n\t\t\t\t// 1. In `getState`, we returned the value from `persistRaw`, which does not have the Proxy to monitor state changes\n\t\t\t\t// 2. If we were to assign `state` to `#persist.s`, `on-change` would assume nothing changed since `state` is still === `#persist.s` since we returned a reference in `getState`\n\t\t\t\tthis.#persist.state = { ...(state as S) };\n\t\t\t\tawait this.saveState({ immediate: true });\n\t\t\t},\n\t\t};\n\t});\n\n\tget id() {\n\t\treturn this.#actorId;\n\t}\n\n\tget inlineClient(): Client<Registry<any>> {\n\t\treturn this.#inlineClient;\n\t}\n\n\tget inspector() {\n\t\treturn this.#inspector;\n\t}\n\n\tget #sleepingSupported(): boolean {\n\t\treturn this.#actorDriver.sleep !== undefined;\n\t}\n\n\t/**\n\t * This constructor should never be used directly.\n\t *\n\t * Constructed in {@link ActorInstance.start}.\n\t *\n\t * @private\n\t */\n\tconstructor(config: ActorConfig<S, CP, CS, V, I, AD, DB>) {\n\t\tthis.#config = config;\n\t\tthis.actorContext = new ActorContext(this);\n\t}\n\n\tasync start(\n\t\tconnectionDrivers: ConnectionDriversMap,\n\t\tactorDriver: ActorDriver,\n\t\tinlineClient: Client<Registry<any>>,\n\t\tactorId: string,\n\t\tname: string,\n\t\tkey: ActorKey,\n\t\tregion: string,\n\t) {\n\t\tthis.#connectionDrivers = connectionDrivers;\n\t\tthis.#actorDriver = actorDriver;\n\t\tthis.#inlineClient = inlineClient;\n\t\tthis.#actorId = actorId;\n\t\tthis.#name = name;\n\t\tthis.#key = key;\n\t\tthis.#region = region;\n\t\tthis.#schedule = new Schedule(this);\n\n\t\t// Initialize server\n\t\t//\n\t\t// Store the promise so network requests can await initialization\n\t\tawait this.#initialize();\n\n\t\t// TODO: Exit process if this errors\n\t\tif (this.#varsEnabled) {\n\t\t\tlet vars: V | undefined;\n\t\t\tif (\"createVars\" in this.#config) {\n\t\t\t\tconst dataOrPromise = this.#config.createVars(\n\t\t\t\t\tthis.actorContext as unknown as ActorContext<\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tany\n\t\t\t\t\t>,\n\t\t\t\t\tthis.#actorDriver.getContext(this.#actorId),\n\t\t\t\t);\n\t\t\t\tif (dataOrPromise instanceof Promise) {\n\t\t\t\t\tvars = await deadline(\n\t\t\t\t\t\tdataOrPromise,\n\t\t\t\t\t\tthis.#config.options.createVarsTimeout,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tvars = dataOrPromise;\n\t\t\t\t}\n\t\t\t} else if (\"vars\" in this.#config) {\n\t\t\t\tvars = structuredClone(this.#config.vars);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Could not variables from 'createVars' or 'vars'\");\n\t\t\t}\n\t\t\tthis.#vars = vars;\n\t\t}\n\n\t\t// TODO: Exit process if this errors\n\t\tlogger().info(\"actor starting\");\n\t\tif (this.#config.onStart) {\n\t\t\tconst result = this.#config.onStart(this.actorContext);\n\t\t\tif (result instanceof Promise) {\n\t\t\t\tawait result;\n\t\t\t}\n\t\t}\n\n\t\t// Setup Database\n\t\tif (\"db\" in this.#config && this.#config.db) {\n\t\t\tconst client = await this.#config.db.createClient({\n\t\t\t\tgetDatabase: () => actorDriver.getDatabase(this.#actorId),\n\t\t\t});\n\t\t\tlogger().info(\"database migration starting\");\n\t\t\tawait this.#config.db.onMigrate?.(client);\n\t\t\tlogger().info(\"database migration complete\");\n\t\t\tthis.#db = client;\n\t\t}\n\n\t\t// Set alarm for next scheduled event if any exist after finishing initiation sequence\n\t\tif (this.#persist.scheduledEvents.length > 0) {\n\t\t\tawait this.#queueSetAlarm(this.#persist.scheduledEvents[0].timestamp);\n\t\t}\n\n\t\tlogger().info(\"actor ready\");\n\t\tthis.#ready = true;\n\n\t\t// Must be called after setting `#ready` or else it will not schedule sleep\n\t\tthis.#resetSleepTimer();\n\n\t\t// Start conn liveness interval\n\t\t//\n\t\t// Check for liveness immediately since we may have connections that\n\t\t// were in `reconnecting` state when the actor went to sleep that we\n\t\t// need to purge.\n\t\t//\n\t\t// We don't use alarms for connection liveness since alarms require\n\t\t// durability & are expensive. Connection liveness is safe to assume\n\t\t// it only needs to be ran while the actor is awake and does not need\n\t\t// to manually wake the actor. The only case this is not true is if the\n\t\t// connection liveness timeout is greater than the actor sleep timeout\n\t\t// OR if the actor is manually put to sleep. In this case, the connections\n\t\t// will be stuck in a `reconnecting` state until the actor is awaken again.\n\t\tthis.#checkConnLivenessInterval = setInterval(\n\t\t\tthis.#checkConnectionsLiveness.bind(this),\n\t\t\tthis.#config.options.connectionLivenessInterval,\n\t\t);\n\t\tthis.#checkConnectionsLiveness();\n\t}\n\n\tasync #scheduleEventInner(newEvent: PersistedScheduleEvent) {\n\t\tthis.actorContext.log.info(\"scheduling event\", newEvent);\n\n\t\t// Insert event in to index\n\t\tconst insertIndex = this.#persist.scheduledEvents.findIndex(\n\t\t\t(x) => x.timestamp > newEvent.timestamp,\n\t\t);\n\t\tif (insertIndex === -1) {\n\t\t\tthis.#persist.scheduledEvents.push(newEvent);\n\t\t} else {\n\t\t\tthis.#persist.scheduledEvents.splice(insertIndex, 0, newEvent);\n\t\t}\n\n\t\t// Update alarm if:\n\t\t// - this is the newest event (i.e. at beginning of array) or\n\t\t// - this is the only event (i.e. the only event in the array)\n\t\tif (insertIndex === 0 || this.#persist.scheduledEvents.length === 1) {\n\t\t\tthis.actorContext.log.info(\"setting alarm\", {\n\t\t\t\ttimestamp: newEvent.timestamp,\n\t\t\t\teventCount: this.#persist.scheduledEvents.length,\n\t\t\t});\n\t\t\tawait this.#queueSetAlarm(newEvent.timestamp);\n\t\t}\n\t}\n\n\tasync _onAlarm() {\n\t\tconst now = Date.now();\n\t\tthis.actorContext.log.debug(\"alarm triggered\", {\n\t\t\tnow,\n\t\t\tevents: this.#persist.scheduledEvents.length,\n\t\t});\n\n\t\t// Update sleep\n\t\t//\n\t\t// Do this before any async logic\n\t\tthis.#resetSleepTimer();\n\n\t\t// Remove events from schedule that we're about to run\n\t\tconst runIndex = this.#persist.scheduledEvents.findIndex(\n\t\t\t(x) => x.timestamp <= now,\n\t\t);\n\t\tif (runIndex === -1) {\n\t\t\t// No events are due yet. This will happen if timers fire slightly early.\n\t\t\t// Ensure we reschedule the alarm for the next upcoming event to avoid losing it.\n\t\t\tlogger().warn(\"no events are due yet, time may have broken\");\n\t\t\tif (this.#persist.scheduledEvents.length > 0) {\n\t\t\t\tconst nextTs = this.#persist.scheduledEvents[0].timestamp;\n\t\t\t\tthis.actorContext.log.warn(\n\t\t\t\t\t\"alarm fired early, rescheduling for next event\",\n\t\t\t\t\t{\n\t\t\t\t\t\tnow,\n\t\t\t\t\t\tnextTs,\n\t\t\t\t\t\tdelta: nextTs - now,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tawait this.#queueSetAlarm(nextTs);\n\t\t\t}\n\t\t\tthis.actorContext.log.debug(\"no events to run\", { now });\n\t\t\treturn;\n\t\t}\n\t\tconst scheduleEvents = this.#persist.scheduledEvents.splice(\n\t\t\t0,\n\t\t\trunIndex + 1,\n\t\t);\n\t\tthis.actorContext.log.debug(\"running events\", {\n\t\t\tcount: scheduleEvents.length,\n\t\t});\n\n\t\t// Set alarm for next event\n\t\tif (this.#persist.scheduledEvents.length > 0) {\n\t\t\tconst nextTs = this.#persist.scheduledEvents[0].timestamp;\n\t\t\tthis.actorContext.log.info(\"setting next alarm\", {\n\t\t\t\tnextTs,\n\t\t\t\tremainingEvents: this.#persist.scheduledEvents.length,\n\t\t\t});\n\t\t\tawait this.#queueSetAlarm(nextTs);\n\t\t}\n\n\t\t// Iterate by event key in order to ensure we call the events in order\n\t\tfor (const event of scheduleEvents) {\n\t\t\ttry {\n\t\t\t\tthis.actorContext.log.info(\"running action for event\", {\n\t\t\t\t\tevent: event.eventId,\n\t\t\t\t\ttimestamp: event.timestamp,\n\t\t\t\t\taction: event.kind.generic.actionName,\n\t\t\t\t});\n\n\t\t\t\t// Look up function\n\t\t\t\tconst fn: unknown = this.#config.actions[event.kind.generic.actionName];\n\n\t\t\t\tif (!fn)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Missing action for alarm ${event.kind.generic.actionName}`,\n\t\t\t\t\t);\n\t\t\t\tif (typeof fn !== \"function\")\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Alarm function lookup for ${event.kind.generic.actionName} returned ${typeof fn}`,\n\t\t\t\t\t);\n\n\t\t\t\t// Call function\n\t\t\t\ttry {\n\t\t\t\t\tconst args = event.kind.generic.args\n\t\t\t\t\t\t? cbor.decode(new Uint8Array(event.kind.generic.args))\n\t\t\t\t\t\t: [];\n\t\t\t\t\tawait fn.call(undefined, this.actorContext, ...args);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.actorContext.log.error(\"error while running event\", {\n\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t\tevent: event.eventId,\n\t\t\t\t\t\ttimestamp: event.timestamp,\n\t\t\t\t\t\taction: event.kind.generic.actionName,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.actorContext.log.error(\"internal error while running event\", {\n\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t...event,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tasync scheduleEvent(\n\t\ttimestamp: number,\n\t\taction: string,\n\t\targs: unknown[],\n\t): Promise<void> {\n\t\treturn this.#scheduleEventInner({\n\t\t\teventId: crypto.randomUUID(),\n\t\t\ttimestamp,\n\t\t\tkind: {\n\t\t\t\tgeneric: {\n\t\t\t\t\tactionName: action,\n\t\t\t\t\targs: bufferToArrayBuffer(cbor.encode(args)),\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t}\n\n\tget stateEnabled() {\n\t\treturn \"createState\" in this.#config || \"state\" in this.#config;\n\t}\n\n\t#validateStateEnabled() {\n\t\tif (!this.stateEnabled) {\n\t\t\tthrow new errors.StateNotEnabled();\n\t\t}\n\t}\n\n\tget #connStateEnabled() {\n\t\treturn \"createConnState\" in this.#config || \"connState\" in this.#config;\n\t}\n\n\tget #varsEnabled() {\n\t\treturn \"createVars\" in this.#config || \"vars\" in this.#config;\n\t}\n\n\t#validateVarsEnabled() {\n\t\tif (!this.#varsEnabled) {\n\t\t\tthrow new errors.VarsNotEnabled();\n\t\t}\n\t}\n\n\t/** Promise used to wait for a save to complete. This is required since you cannot await `#saveStateThrottled`. */\n\t#onPersistSavedPromise?: PromiseWithResolvers<void>;\n\n\t/** Throttled save state method. Used to write to KV at a reasonable cadence. */\n\t#savePersistThrottled() {\n\t\tconst now = Date.now();\n\t\tconst timeSinceLastSave = now - this.#lastSaveTime;\n\t\tconst saveInterval = this.#config.options.stateSaveInterval;\n\n\t\t// If we're within the throttle window and not already scheduled, schedule the next save.\n\t\tif (timeSinceLastSave < saveInterval) {\n\t\t\tif (this.#pendingSaveTimeout === undefined) {\n\t\t\t\tthis.#pendingSaveTimeout = setTimeout(() => {\n\t\t\t\t\tthis.#pendingSaveTimeout = undefined;\n\t\t\t\t\tthis.#savePersistInner();\n\t\t\t\t}, saveInterval - timeSinceLastSave);\n\t\t\t}\n\t\t} else {\n\t\t\t// If we're outside the throttle window, save immediately\n\t\t\tthis.#savePersistInner();\n\t\t}\n\t}\n\n\t/** Saves the state to KV. You probably want to use #saveStateThrottled instead except for a few edge cases. */\n\tasync #savePersistInner() {\n\t\ttry {\n\t\t\tthis.#lastSaveTime = Date.now();\n\n\t\t\tif (this.#persistChanged) {\n\t\t\t\tconst finished = this.#persistWriteQueue.enqueue(async () => {\n\t\t\t\t\tlogger().debug(\"saving persist\");\n\n\t\t\t\t\t// There might be more changes while we're writing, so we set this\n\t\t\t\t\t// before writing to KV in order to avoid a race condition.\n\t\t\t\t\tthis.#persistChanged = false;\n\n\t\t\t\t\t// Convert to BARE types and write to KV\n\t\t\t\t\tconst bareData = this.#convertToBarePersisted(this.#persistRaw);\n\t\t\t\t\tawait this.#actorDriver.writePersistedData(\n\t\t\t\t\t\tthis.#actorId,\n\t\t\t\t\t\tPERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(bareData),\n\t\t\t\t\t);\n\n\t\t\t\t\tlogger().debug(\"persist saved\");\n\t\t\t\t});\n\n\t\t\t\tawait finished;\n\t\t\t}\n\n\t\t\tthis.#onPersistSavedPromise?.resolve();\n\t\t} catch (error) {\n\t\t\tthis.#onPersistSavedPromise?.reject(error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync #queueSetAlarm(timestamp: number): Promise<void> {\n\t\tawait this.#alarmWriteQueue.enqueue(async () => {\n\t\t\tawait this.#actorDriver.setAlarm(this, timestamp);\n\t\t});\n\t}\n\n\t/**\n\t * Creates proxy for `#persist` that handles automatically flagging when state needs to be updated.\n\t */\n\t#setPersist(target: PersistedActor<S, CP, CS, I>) {\n\t\t// Set raw persist object\n\t\tthis.#persistRaw = target;\n\n\t\t// TODO: Only validate this for conn state\n\t\t// TODO: Allow disabling in production\n\t\t// If this can't be proxied, return raw value\n\t\tif (target === null || typeof target !== \"object\") {\n\t\t\tlet invalidPath = \"\";\n\t\t\tif (\n\t\t\t\t!isCborSerializable(\n\t\t\t\t\ttarget,\n\t\t\t\t\t(path) => {\n\t\t\t\t\t\tinvalidPath = path;\n\t\t\t\t\t},\n\t\t\t\t\t\"\",\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tthrow new errors.InvalidStateType({ path: invalidPath });\n\t\t\t}\n\t\t\treturn target;\n\t\t}\n\n\t\t// Unsubscribe from old state\n\t\tif (this.#persist) {\n\t\t\tonChange.unsubscribe(this.#persist);\n\t\t}\n\n\t\t// Listen for changes to the object in order to automatically write state\n\t\tthis.#persist = onChange(\n\t\t\ttarget,\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Don't know types in proxy\n\t\t\t(path: string, value: any, _previousValue: any, _applyData: any) => {\n\t\t\t\tif (path !== \"state\" && !path.startsWith(\"state.\")) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet invalidPath = \"\";\n\t\t\t\tif (\n\t\t\t\t\t!isCborSerializable(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t(invalidPathPart) => {\n\t\t\t\t\t\t\tinvalidPath = invalidPathPart;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tthrow new errors.InvalidStateType({\n\t\t\t\t\t\tpath: path + (invalidPath ? `.${invalidPath}` : \"\"),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.#persistChanged = true;\n\n\t\t\t\t// Inform the inspector about state changes\n\t\t\t\tthis.inspector.emitter.emit(\"stateUpdated\", this.#persist.state);\n\n\t\t\t\t// Call onStateChange if it exists\n\t\t\t\t// Skip if we're already inside onStateChange to prevent infinite recursion\n\t\t\t\tif (\n\t\t\t\t\tthis.#config.onStateChange &&\n\t\t\t\t\tthis.#ready &&\n\t\t\t\t\t!this.#isInOnStateChange\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.#isInOnStateChange = true;\n\t\t\t\t\t\tthis.#config.onStateChange(\n\t\t\t\t\t\t\tthis.actorContext,\n\t\t\t\t\t\t\tthis.#persistRaw.state,\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tlogger().error(\"error in `_onStateChange`\", {\n\t\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t\t});\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tthis.#isInOnStateChange = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// State will be flushed at the end of the action\n\t\t\t},\n\t\t\t{ ignoreDetached: true },\n\t\t);\n\t}\n\n\tasync #initialize() {\n\t\t// Read initial state\n\t\tconst persistDataBuffer = await this.#actorDriver.readPersistedData(\n\t\t\tthis.#actorId,\n\t\t);\n\t\tinvariant(\n\t\t\tpersistDataBuffer !== undefined,\n\t\t\t\"persist data has not been set, it should be set when initialized\",\n\t\t);\n\t\tconst bareData =\n\t\t\tPERSISTED_ACTOR_VERSIONED.deserializeWithEmbeddedVersion(\n\t\t\t\tpersistDataBuffer,\n\t\t\t);\n\t\tconst persistData = this.#convertFromBarePersisted(bareData);\n\n\t\tif (persistData.hasInitiated) {\n\t\t\tlogger().info(\"actor restoring\", {\n\t\t\t\tconnections: persistData.connections.length,\n\t\t\t});\n\n\t\t\t// Set initial state\n\t\t\tthis.#setPersist(persistData);\n\n\t\t\t// Load connections\n\t\t\tfor (const connPersist of this.#persist.connections) {\n\t\t\t\t// Create connections\n\t\t\t\tconst driver = this.__getConnDriver(connPersist.connDriver);\n\t\t\t\tconst conn = new Conn<S, CP, CS, V, I, AD, DB>(\n\t\t\t\t\tthis,\n\t\t\t\t\tconnPersist,\n\t\t\t\t\tdriver,\n\t\t\t\t\tthis.#connStateEnabled,\n\t\t\t\t);\n\t\t\t\tthis.#connections.set(conn.id, conn);\n\n\t\t\t\t// Register event subscriptions\n\t\t\t\tfor (const sub of connPersist.subscriptions) {\n\t\t\t\t\tthis.#addSubscription(sub.eventName, conn, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlogger().info(\"actor creating\");\n\n\t\t\t// Initialize actor state\n\t\t\tlet stateData: unknown;\n\t\t\tif (this.stateEnabled) {\n\t\t\t\tlogger().info(\"actor state initializing\");\n\n\t\t\t\tif (\"createState\" in this.#config) {\n\t\t\t\t\tthis.#config.createState;\n\n\t\t\t\t\t// Convert state to undefined since state is not defined yet here\n\t\t\t\t\tstateData = await this.#config.createState(\n\t\t\t\t\t\tthis.actorContext as unknown as ActorContext<\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tundefined\n\t\t\t\t\t\t>,\n\t\t\t\t\t\tpersistData.input!,\n\t\t\t\t\t);\n\t\t\t\t} else if (\"state\" in this.#config) {\n\t\t\t\t\tstateData = structuredClone(this.#config.state);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Both 'createState' or 'state' were not defined\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger().debug(\"state not enabled\");\n\t\t\t}\n\n\t\t\t// Save state and mark as initialized\n\t\t\tpersistData.state = stateData as S;\n\t\t\tpersistData.hasInitiated = true;\n\n\t\t\t// Update state\n\t\t\tlogger().debug(\"writing state\");\n\t\t\tconst bareData = this.#convertToBarePersisted(persistData);\n\t\t\tawait this.#actorDriver.writePersistedData(\n\t\t\t\tthis.#actorId,\n\t\t\t\tPERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(bareData),\n\t\t\t);\n\n\t\t\tthis.#setPersist(persistData);\n\n\t\t\t// Notify creation\n\t\t\tif (this.#config.onCreate) {\n\t\t\t\tawait this.#config.onCreate(this.actorContext, persistData.input!);\n\t\t\t}\n\t\t}\n\t}\n\n\t__getConnForId(id: string): Conn<S, CP, CS, V, I, AD, DB> | undefined {\n\t\treturn this.#connections.get(id);\n\t}\n\n\t/**\n\t * Removes a connection and cleans up its resources.\n\t */\n\t__removeConn(conn: Conn<S, CP, CS, V, I, AD, DB> | undefined) {\n\t\tif (!conn) {\n\t\t\tlogger().warn(\"`conn` does not exist\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove from persist & save immediately\n\t\tconst connIdx = this.#persist.connections.findIndex(\n\t\t\t(c) => c.connId === conn.id,\n\t\t);\n\t\tif (connIdx !== -1) {\n\t\t\tthis.#persist.connections.splice(connIdx, 1);\n\t\t\tthis.saveState({ immediate: true, allowStoppingState: true });\n\t\t} else {\n\t\t\tlogger().warn(\"could not find persisted connection to remove\", {\n\t\t\t\tconnId: conn.id,\n\t\t\t});\n\t\t}\n\n\t\t// Remove from state\n\t\tthis.#connections.delete(conn.id);\n\n\t\t// Remove subscriptions\n\t\tfor (const eventName of [...conn.subscriptions.values()]) {\n\t\t\tthis.#removeSubscription(eventName, conn, true);\n\t\t}\n\n\t\tthis.inspector.emitter.emit(\"connectionUpdated\");\n\t\tif (this.#config.onDisconnect) {\n\t\t\ttry {\n\t\t\t\tconst result = this.#config.onDisconnect(this.actorContext, conn);\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t// Handle promise but don't await it to prevent blocking\n\t\t\t\t\tresult.catch((error) => {\n\t\t\t\t\t\tlogger().error(\"error in `onDisconnect`\", {\n\t\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger().error(\"error in `onDisconnect`\", {\n\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Update sleep\n\t\tthis.#resetSleepTimer();\n\t}\n\n\tasync prepareConn(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: TypeScript bug with ExtractActorConnParams<this>,\n\t\tparams: any,\n\t\trequest?: Request,\n\t): Promise<CS> {\n\t\t// Authenticate connection\n\t\tlet connState: CS | undefined;\n\n\t\tconst onBeforeConnectOpts = {\n\t\t\trequest,\n\t\t} satisfies OnConnectOptions;\n\n\t\tif (this.#config.onBeforeConnect) {\n\t\t\tawait this.#config.onBeforeConnect(\n\t\t\t\tthis.actorContext,\n\t\t\t\tonBeforeConnectOpts,\n\t\t\t\tparams,\n\t\t\t);\n\t\t}\n\n\t\tif (this.#connStateEnabled) {\n\t\t\tif (\"createConnState\" in this.#config) {\n\t\t\t\tconst dataOrPromise = this.#config.createConnState(\n\t\t\t\t\tthis.actorContext as unknown as ActorContext<\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined\n\t\t\t\t\t>,\n\t\t\t\t\tonBeforeConnectOpts,\n\t\t\t\t\tparams,\n\t\t\t\t);\n\t\t\t\tif (dataOrPromise instanceof Promise) {\n\t\t\t\t\tconnState = await deadline(\n\t\t\t\t\t\tdataOrPromise,\n\t\t\t\t\t\tthis.#config.options.createConnStateTimeout,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconnState = dataOrPromise;\n\t\t\t\t}\n\t\t\t} else if (\"connState\" in this.#config) {\n\t\t\t\tconnState = structuredClone(this.#config.connState);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Could not create connection state from 'createConnState' or 'connState'\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn connState as CS;\n\t}\n\n\t__getConnDriver(driverId: ConnectionDriver): ConnDriver {\n\t\t// Get driver\n\t\tconst driver = this.#connectionDrivers[driverId];\n\t\tif (!driver) throw new Error(`No connection driver: ${driverId}`);\n\t\treturn driver;\n\t}\n\n\t/**\n\t * Called after establishing a connection handshake.\n\t */\n\tasync createConn(\n\t\tconnectionId: string,\n\t\tconnectionToken: string,\n\t\tparams: CP,\n\t\tstate: CS,\n\t\tdriverId: ConnectionDriver,\n\t\tdriverState: unknown,\n\t\tauthData: unknown,\n\t): Promise<Conn<S, CP, CS, V, I, AD, DB>> {\n\t\tthis.#assertReady();\n\n\t\tif (this.#connections.has(connectionId)) {\n\t\t\tthrow new Error(`Connection already exists: ${connectionId}`);\n\t\t}\n\n\t\t// Create connection\n\t\tconst driver = this.__getConnDriver(driverId);\n\t\tconst persist: PersistedConn<CP, CS> = {\n\t\t\tconnId: connectionId,\n\t\t\ttoken: connectionToken,\n\t\t\tconnDriver: driverId,\n\t\t\tconnDriverState: driverState,\n\t\t\tparams: params,\n\t\t\tstate: state,\n\t\t\tauthData: authData,\n\t\t\tlastSeen: Date.now(),\n\t\t\tsubscriptions: [],\n\t\t};\n\t\tconst conn = new Conn<S, CP, CS, V, I, AD, DB>(\n\t\t\tthis,\n\t\t\tpersist,\n\t\t\tdriver,\n\t\t\tthis.#connStateEnabled,\n\t\t);\n\t\tthis.#connections.set(conn.id, conn);\n\n\t\t// Update sleep\n\t\t//\n\t\t// Do this immediately after adding connection & before any async logic in order to avoid race conditions with sleep timeouts\n\t\tthis.#resetSleepTimer();\n\n\t\t// Add to persistence & save immediately\n\t\tthis.#persist.connections.push(persist);\n\t\tthis.saveState({ immediate: true });\n\n\t\t// Handle connection\n\t\tif (this.#config.onConnect) {\n\t\t\ttry {\n\t\t\t\tconst result = this.#config.onConnect(this.actorContext, conn);\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\tdeadline(result, this.#config.options.onConnectTimeout).catch(\n\t\t\t\t\t\t(error) => {\n\t\t\t\t\t\t\tlogger().error(\"error in `onConnect`, closing socket\", {\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconn?.disconnect(\"`onConnect` failed\");\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger().error(\"error in `onConnect`\", {\n\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t});\n\t\t\t\tconn?.disconnect(\"`onConnect` failed\");\n\t\t\t}\n\t\t}\n\n\t\tthis.inspector.emitter.emit(\"connectionUpdated\");\n\n\t\t// Send init message\n\t\tconn._sendMessage(\n\t\t\tnew CachedSerializer<protocol.ToClient>(\n\t\t\t\t{\n\t\t\t\t\tbody: {\n\t\t\t\t\t\ttag: \"Init\",\n\t\t\t\t\t\tval: {\n\t\t\t\t\t\t\tactorId: this.id,\n\t\t\t\t\t\t\tconnectionId: conn.id,\n\t\t\t\t\t\t\tconnectionToken: conn._token,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tTO_CLIENT_VERSIONED,\n\t\t\t),\n\t\t);\n\n\t\treturn conn;\n\t}\n\n\t// MARK: Messages\n\tasync processMessage(\n\t\tmessage: protocol.ToServer,\n\t\tconn: Conn<S, CP, CS, V, I, AD, DB>,\n\t) {\n\t\tawait processMessage(message, this, conn, {\n\t\t\tonExecuteAction: async (ctx, name, args) => {\n\t\t\t\tthis.inspector.emitter.emit(\"eventFired\", {\n\t\t\t\t\ttype: \"action\",\n\t\t\t\t\tname,\n\t\t\t\t\targs,\n\t\t\t\t\tconnId: conn.id,\n\t\t\t\t});\n\t\t\t\treturn await this.executeAction(ctx, name, args);\n\t\t\t},\n\t\t\tonSubscribe: async (eventName, conn) => {\n\t\t\t\tthis.inspector.emitter.emit(\"eventFired\", {\n\t\t\t\t\ttype: \"subscribe\",\n\t\t\t\t\teventName,\n\t\t\t\t\tconnId: conn.id,\n\t\t\t\t});\n\t\t\t\tthis.#addSubscription(eventName, conn, false);\n\t\t\t},\n\t\t\tonUnsubscribe: async (eventName, conn) => {\n\t\t\t\tthis.inspector.emitter.emit(\"eventFired\", {\n\t\t\t\t\ttype: \"unsubscribe\",\n\t\t\t\t\teventName,\n\t\t\t\t\tconnId: conn.id,\n\t\t\t\t});\n\t\t\t\tthis.#removeSubscription(eventName, conn, false);\n\t\t\t},\n\t\t});\n\t}\n\n\t// MARK: Events\n\t#addSubscription(\n\t\teventName: string,\n\t\tconnection: Conn<S, CP, CS, V, I, AD, DB>,\n\t\tfromPersist: boolean,\n\t) {\n\t\tif (connection.subscriptions.has(eventName)) {\n\t\t\tlogger().debug(\"connection already has subscription\", { eventName });\n\t\t\treturn;\n\t\t}\n\n\t\t// Persist subscriptions & save immediately\n\t\t//\n\t\t// Don't update persistence if already restoring from persistence\n\t\tif (!fromPersist) {\n\t\t\tconnection.__persist.subscriptions.push({ eventName: eventName });\n\t\t\tthis.saveState({ immediate: true });\n\t\t}\n\n\t\t// Update subscriptions\n\t\tconnection.subscriptions.add(eventName);\n\n\t\t// Update subscription index\n\t\tlet subscribers = this.#subscriptionIndex.get(eventName);\n\t\tif (!subscribers) {\n\t\t\tsubscribers = new Set();\n\t\t\tthis.#subscriptionIndex.set(eventName, subscribers);\n\t\t}\n\t\tsubscribers.add(connection);\n\t}\n\n\t#removeSubscription(\n\t\teventName: string,\n\t\tconnection: Conn<S, CP, CS, V, I, AD, DB>,\n\t\tfromRemoveConn: boolean,\n\t) {\n\t\tif (!connection.subscriptions.has(eventName)) {\n\t\t\tlogger().warn(\"connection does not have subscription\", { eventName });\n\t\t\treturn;\n\t\t}\n\n\t\t// Persist subscriptions & save immediately\n\t\t//\n\t\t// Don't update the connection itself if the connection is already being removed\n\t\tif (!fromRemoveConn) {\n\t\t\tconnection.subscriptions.delete(eventName);\n\n\t\t\tconst subIdx = connection.__persist.subscriptions.findIndex(\n\t\t\t\t(s) => s.eventName === eventName,\n\t\t\t);\n\t\t\tif (subIdx !== -1) {\n\t\t\t\tconnection.__persist.subscriptions.splice(subIdx, 1);\n\t\t\t} else {\n\t\t\t\tlogger().warn(\"subscription does not exist with name\", { eventName });\n\t\t\t}\n\n\t\t\tthis.saveState({ immediate: true });\n\t\t}\n\n\t\t// Update scriptions index\n\t\tconst subscribers = this.#subscriptionIndex.get(eventName);\n\t\tif (subscribers) {\n\t\t\tsubscribers.delete(connection);\n\t\t\tif (subscribers.size === 0) {\n\t\t\t\tthis.#subscriptionIndex.delete(eventName);\n\t\t\t}\n\t\t}\n\t}\n\n\t#assertReady(allowStoppingState: boolean = false) {\n\t\tif (!this.#ready) throw new errors.InternalError(\"Actor not ready\");\n\t\tif (!allowStoppingState && this.#sleepCalled)\n\t\t\tthrow new errors.InternalError(\"Actor is going to sleep\");\n\t\tif (!allowStoppingState && this.#stopCalled)\n\t\t\tthrow new errors.InternalError(\"Actor is stopping\");\n\t}\n\n\t/**\n\t * Check the liveness of all connections.\n\t * Sets up a recurring check based on the configured interval.\n\t */\n\t#checkConnectionsLiveness() {\n\t\tlogger().debug(\"checking connections liveness\");\n\n\t\tfor (const conn of this.#connections.values()) {\n\t\t\tconst liveness = conn[CONNECTION_CHECK_LIVENESS_SYMBOL]();\n\t\t\tif (liveness.status === \"connected\") {\n\t\t\t\tlogger().debug(\"connection is alive\", { connId: conn.id });\n\t\t\t} else {\n\t\t\t\tconst lastSeen = liveness.lastSeen;\n\t\t\t\tconst sinceLastSeen = Date.now() - lastSeen;\n\t\t\t\tif (sinceLastSeen < this.#config.options.connectionLivenessTimeout) {\n\t\t\t\t\tlogger().debug(\"connection might be alive, will check later\", {\n\t\t\t\t\t\tconnId: conn.id,\n\t\t\t\t\t\tlastSeen,\n\t\t\t\t\t\tsinceLastSeen,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Connection is dead, remove it\n\t\t\t\tlogger().warn(\"connection is dead, removing\", {\n\t\t\t\t\tconnId: conn.id,\n\t\t\t\t\tlastSeen,\n\t\t\t\t});\n\n\t\t\t\t// TODO: Do we need to force disconnect the connection here?\n\n\t\t\t\tthis.__removeConn(conn);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check if the actor is ready to handle requests.\n\t */\n\tisReady(): boolean {\n\t\treturn this.#ready;\n\t}\n\n\t/**\n\t * Execute an action call from a client.\n\t *\n\t * This method handles:\n\t * 1. Validating the action name\n\t * 2. Executing the action function\n\t * 3. Processing the result through onBeforeActionResponse (if configured)\n\t * 4. Handling timeouts and errors\n\t * 5. Saving state changes\n\t *\n\t * @param ctx The action context\n\t * @param actionName The name of the action being called\n\t * @param args The arguments passed to the action\n\t * @returns The result of the action call\n\t * @throws {ActionNotFound} If the action doesn't exist\n\t * @throws {ActionTimedOut} If the action times out\n\t * @internal\n\t */\n\tasync executeAction(\n\t\tctx: ActionContext<S, CP, CS, V, I, AD, DB>,\n\t\tactionName: string,\n\t\targs: unknown[],\n\t): Promise<unknown> {\n\t\tinvariant(this.#ready, \"executing action before ready\");\n\n\t\t// Prevent calling private or reserved methods\n\t\tif (!(actionName in this.#config.actions)) {\n\t\t\tlogger().warn(\"action does not exist\", { actionName });\n\t\t\tthrow new errors.ActionNotFound(actionName);\n\t\t}\n\n\t\t// Check if the method exists on this object\n\t\tconst actionFunction = this.#config.actions[actionName];\n\t\tif (typeof actionFunction !== \"function\") {\n\t\t\tlogger().warn(\"action is not a function\", {\n\t\t\t\tactionName: actionName,\n\t\t\t\ttype: typeof actionFunction,\n\t\t\t});\n\t\t\tthrow new errors.ActionNotFound(actionName);\n\t\t}\n\n\t\t// TODO: pass abortable to the action to decide when to abort\n\t\t// TODO: Manually call abortable for better error handling\n\t\t// Call the function on this object with those arguments\n\t\ttry {\n\t\t\t// Log when we start executing the action\n\t\t\tlogger().debug(\"executing action\", { actionName: actionName, args });\n\n\t\t\tconst outputOrPromise = actionFunction.call(undefined, ctx, ...args);\n\t\t\tlet output: unknown;\n\t\t\tif (outputOrPromise instanceof Promise) {\n\t\t\t\t// Log that we're waiting for an async action\n\t\t\t\tlogger().debug(\"awaiting async action\", { actionName: actionName });\n\n\t\t\t\toutput = await deadline(\n\t\t\t\t\toutputOrPromise,\n\t\t\t\t\tthis.#config.options.actionTimeout,\n\t\t\t\t);\n\n\t\t\t\t// Log that async action completed\n\t\t\t\tlogger().debug(\"async action completed\", { actionName: actionName });\n\t\t\t} else {\n\t\t\t\toutput = outputOrPromise;\n\t\t\t}\n\n\t\t\t// Process the output through onBeforeActionResponse if configured\n\t\t\tif (this.#config.onBeforeActionResponse) {\n\t\t\t\ttry {\n\t\t\t\t\tconst processedOutput = this.#config.onBeforeActionResponse(\n\t\t\t\t\t\tthis.actorContext,\n\t\t\t\t\t\tactionName,\n\t\t\t\t\t\targs,\n\t\t\t\t\t\toutput,\n\t\t\t\t\t);\n\t\t\t\t\tif (processedOutput instanceof Promise) {\n\t\t\t\t\t\tlogger().debug(\"awaiting onBeforeActionResponse\", {\n\t\t\t\t\t\t\tactionName: actionName,\n\t\t\t\t\t\t});\n\t\t\t\t\t\toutput = await processedOutput;\n\t\t\t\t\t\tlogger().debug(\"onBeforeActionResponse completed\", {\n\t\t\t\t\t\t\tactionName: actionName,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput = processedOutput;\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger().error(\"error in `onBeforeActionResponse`\", {\n\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Log the output before returning\n\t\t\tlogger().debug(\"action completed\", {\n\t\t\t\tactionName: actionName,\n\t\t\t\toutputType: typeof output,\n\t\t\t\tisPromise: output instanceof Promise,\n\t\t\t});\n\n\t\t\t// This output *might* reference a part of the state (using onChange), but\n\t\t\t// that's OK since this value always gets serialized and sent over the\n\t\t\t// network.\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\tif (error instanceof DeadlineError) {\n\t\t\t\tthrow new errors.ActionTimedOut();\n\t\t\t}\n\t\t\tlogger().error(\"action error\", {\n\t\t\t\tactionName: actionName,\n\t\t\t\terror: stringifyError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.#savePersistThrottled();\n\t\t}\n\t}\n\n\t/**\n\t * Returns a list of action methods available on this actor.\n\t */\n\tget actions(): string[] {\n\t\treturn Object.keys(this.#config.actions);\n\t}\n\n\t/**\n\t * Handles raw HTTP requests to the actor.\n\t */\n\tasync handleFetch(request: Request, opts: { auth: AD }): Promise<Response> {\n\t\tthis.#assertReady();\n\n\t\tif (!this.#config.onFetch) {\n\t\t\tthrow new errors.FetchHandlerNotDefined();\n\t\t}\n\n\t\t// Track active raw fetch while handler runs\n\t\tthis.#activeRawFetchCount++;\n\t\tthis.#resetSleepTimer();\n\n\t\ttry {\n\t\t\tconst response = await this.#config.onFetch(\n\t\t\t\tthis.actorContext,\n\t\t\t\trequest,\n\t\t\t\topts,\n\t\t\t);\n\t\t\tif (!response) {\n\t\t\t\tthrow new errors.InvalidFetchResponse();\n\t\t\t}\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tlogger().error(\"onFetch error\", {\n\t\t\t\terror: stringifyError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\t// Decrement active raw fetch counter and re-evaluate sleep\n\t\t\tthis.#activeRawFetchCount = Math.max(0, this.#activeRawFetchCount - 1);\n\t\t\tthis.#resetSleepTimer();\n\t\t\tthis.#savePersistThrottled();\n\t\t}\n\t}\n\n\t/**\n\t * Handles raw WebSocket connections to the actor.\n\t */\n\tasync handleWebSocket(\n\t\twebsocket: UniversalWebSocket,\n\t\topts: { request: Request; auth: AD },\n\t): Promise<void> {\n\t\tthis.#assertReady();\n\n\t\tif (!this.#config.onWebSocket) {\n\t\t\tthrow new errors.InternalError(\"onWebSocket handler not defined\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Set up state tracking to detect changes during WebSocket handling\n\t\t\tconst stateBeforeHandler = this.#persistChanged;\n\n\t\t\t// Track active websocket until it fully closes\n\t\t\tthis.#activeRawWebSockets.add(websocket);\n\t\t\tthis.#resetSleepTimer();\n\n\t\t\t// Track socket close\n\t\t\tconst onSocketClosed = () => {\n\t\t\t\t// Remove listener and socket from tracking\n\t\t\t\ttry {\n\t\t\t\t\twebsocket.removeEventListener(\"close\", onSocketClosed);\n\t\t\t\t\twebsocket.removeEventListener(\"error\", onSocketClosed);\n\t\t\t\t} catch {}\n\t\t\t\tthis.#activeRawWebSockets.delete(websocket);\n\t\t\t\tthis.#resetSleepTimer();\n\t\t\t};\n\t\t\ttry {\n\t\t\t\twebsocket.addEventListener(\"close\", onSocketClosed);\n\t\t\t\twebsocket.addEventListener(\"error\", onSocketClosed);\n\t\t\t} catch {}\n\n\t\t\t// Handle WebSocket\n\t\t\tawait this.#config.onWebSocket(this.actorContext, websocket, opts);\n\n\t\t\t// If state changed during the handler, save it\n\t\t\tif (this.#persistChanged && !stateBeforeHandler) {\n\t\t\t\tawait this.saveState({ immediate: true });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger().error(\"onWebSocket error\", {\n\t\t\t\terror: stringifyError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.#savePersistThrottled();\n\t\t}\n\t}\n\n\t// MARK: Lifecycle hooks\n\n\t// MARK: Exposed methods\n\t/**\n\t * Gets the logger instance.\n\t */\n\tget log(): Logger {\n\t\treturn instanceLogger();\n\t}\n\n\t/**\n\t * Gets the name.\n\t */\n\tget name(): string {\n\t\treturn this.#name;\n\t}\n\n\t/**\n\t * Gets the key.\n\t */\n\tget key(): ActorKey {\n\t\treturn this.#key;\n\t}\n\n\t/**\n\t * Gets the region.\n\t */\n\tget region(): string {\n\t\treturn this.#region;\n\t}\n\n\t/**\n\t * Gets the scheduler.\n\t */\n\tget schedule(): Schedule {\n\t\treturn this.#schedule;\n\t}\n\n\t/**\n\t * Gets the map of connections.\n\t */\n\tget conns(): Map<ConnId, Conn<S, CP, CS, V, I, AD, DB>> {\n\t\treturn this.#connections;\n\t}\n\n\t/**\n\t * Gets the current state.\n\t *\n\t * Changing properties of this value will automatically be persisted.\n\t */\n\tget state(): S {\n\t\tthis.#validateStateEnabled();\n\t\treturn this.#persist.state;\n\t}\n\n\t/**\n\t * Gets the database.\n\t * @experimental\n\t * @throws {DatabaseNotEnabled} If the database is not enabled.\n\t */\n\tget db(): InferDatabaseClient<DB> {\n\t\tif (!this.#db) {\n\t\t\tthrow new errors.DatabaseNotEnabled();\n\t\t}\n\t\treturn this.#db;\n\t}\n\n\t/**\n\t * Sets the current state.\n\t *\n\t * This property will automatically be persisted.\n\t */\n\tset state(value: S) {\n\t\tthis.#validateStateEnabled();\n\t\tthis.#persist.state = value;\n\t}\n\n\tget vars(): V {\n\t\tthis.#validateVarsEnabled();\n\t\tinvariant(this.#vars !== undefined, \"vars not enabled\");\n\t\treturn this.#vars;\n\t}\n\n\t/**\n\t * Broadcasts an event to all connected clients.\n\t * @param name - The name of the event.\n\t * @param args - The arguments to send with the event.\n\t */\n\t_broadcast<Args extends Array<unknown>>(name: string, ...args: Args) {\n\t\tthis.#assertReady();\n\n\t\tthis.inspector.emitter.emit(\"eventFired\", {\n\t\t\ttype: \"broadcast\",\n\t\t\teventName: name,\n\t\t\targs,\n\t\t});\n\n\t\t// Send to all connected clients\n\t\tconst subscriptions = this.#subscriptionIndex.get(name);\n\t\tif (!subscriptions) return;\n\n\t\tconst toClientSerializer = new CachedSerializer<protocol.ToClient>(\n\t\t\t{\n\t\t\t\tbody: {\n\t\t\t\t\ttag: \"Event\",\n\t\t\t\t\tval: {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\targs: bufferToArrayBuffer(cbor.encode(args)),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tTO_CLIENT_VERSIONED,\n\t\t);\n\n\t\t// Send message to clients\n\t\tfor (const connection of subscriptions) {\n\t\t\tconnection._sendMessage(toClientSerializer);\n\t\t}\n\t}\n\n\t/**\n\t * Prevents the actor from sleeping until promise is complete.\n\t *\n\t * This allows the actor runtime to ensure that a promise completes while\n\t * returning from an action request early.\n\t *\n\t * @param promise - The promise to run in the background.\n\t */\n\t_waitUntil(promise: Promise<void>) {\n\t\tthis.#assertReady();\n\n\t\t// TODO: Should we force save the state?\n\t\t// Add logging to promise and make it non-failable\n\t\tconst nonfailablePromise = promise\n\t\t\t.then(() => {\n\t\t\t\tlogger().debug(\"wait until promise complete\");\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tlogger().error(\"wait until promise failed\", {\n\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t});\n\t\t\t});\n\t\tthis.#backgroundPromises.push(nonfailablePromise);\n\t}\n\n\t/**\n\t * Forces the state to get saved.\n\t *\n\t * This is helpful if running a long task that may fail later or when\n\t * running a background job that updates the state.\n\t *\n\t * @param opts - Options for saving the state.\n\t */\n\tasync saveState(opts: SaveStateOptions) {\n\t\tthis.#assertReady(opts.allowStoppingState);\n\n\t\tif (this.#persistChanged) {\n\t\t\tif (opts.immediate) {\n\t\t\t\t// Save immediately\n\t\t\t\tawait this.#savePersistInner();\n\t\t\t} else {\n\t\t\t\t// Create callback\n\t\t\t\tif (!this.#onPersistSavedPromise) {\n\t\t\t\t\tthis.#onPersistSavedPromise = Promise.withResolvers();\n\t\t\t\t}\n\n\t\t\t\t// Save state throttled\n\t\t\t\tthis.#savePersistThrottled();\n\n\t\t\t\t// Wait for save\n\t\t\t\tawait this.#onPersistSavedPromise.promise;\n\t\t\t}\n\t\t}\n\t}\n\n\t// MARK: Sleep\n\t/**\n\t * Reset timer from the last actor interaction that allows it to be put to sleep.\n\t *\n\t * This should be called any time a sleep-related event happens:\n\t * - Connection opens (will clear timer)\n\t * - Connection closes (will schedule timer if there are no open connections)\n\t * - Alarm triggers (will reset timer)\n\t *\n\t * We don't need to call this on events like individual action calls, since there will always be a connection open for these.\n\t **/\n\t#resetSleepTimer() {\n\t\tif (this.#config.options.noSleep || !this.#sleepingSupported) return;\n\n\t\tconst canSleep = this.#canSleep();\n\n\t\tlogger().debug(\"resetting sleep timer\", {\n\t\t\tcanSleep,\n\t\t\texistingTimeout: !!this.#sleepTimeout,\n\t\t});\n\n\t\tif (this.#sleepTimeout) {\n\t\t\tclearTimeout(this.#sleepTimeout);\n\t\t\tthis.#sleepTimeout = undefined;\n\t\t}\n\n\t\t// Don't set a new timer if already sleeping\n\t\tif (this.#sleepCalled) return;\n\n\t\tif (canSleep) {\n\t\t\tthis.#sleepTimeout = setTimeout(() => {\n\t\t\t\tthis._sleep().catch((error) => {\n\t\t\t\t\tlogger().error(\"error during sleep\", {\n\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}, this.#config.options.sleepTimeout);\n\t\t}\n\t}\n\n\t/** If this actor can be put in a sleeping state. */\n\t#canSleep(): boolean {\n\t\tif (!this.#ready) return false;\n\n\t\t// Check for active conns. This will also cover active actions, since all actions have a connection.\n\t\tfor (const conn of this.#connections.values()) {\n\t\t\tif (conn.status === \"connected\") return false;\n\t\t}\n\n\t\t// Do not sleep if raw fetches are in-flight\n\t\tif (this.#activeRawFetchCount > 0) return false;\n\n\t\t// Do not sleep if there are raw websockets open\n\t\tif (this.#activeRawWebSockets.size > 0) return false;\n\n\t\treturn true;\n\t}\n\n\t/** Puts an actor to sleep. This should just start the sleep sequence, most shutdown logic should be in _stop (which is called by the ActorDriver when sleeping). */\n\tasync _sleep() {\n\t\tconst sleep = this.#actorDriver.sleep?.bind(\n\t\t\tthis.#actorDriver,\n\t\t\tthis.#actorId,\n\t\t);\n\t\tinvariant(this.#sleepingSupported, \"sleeping not supported\");\n\t\tinvariant(sleep, \"no sleep on driver\");\n\n\t\tif (this.#sleepCalled) {\n\t\t\tlogger().warn(\"already sleeping actor\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#sleepCalled = true;\n\n\t\tlogger().info(\"actor sleeping\");\n\n\t\t// Schedule sleep to happen on the next tick. This allows for any action that calls _sleep to complete.\n\t\tsetImmediate(async () => {\n\t\t\t// The actor driver should call stop when ready to stop\n\t\t\t//\n\t\t\t// This will call _stop once Pegboard responds with the new status\n\t\t\tawait sleep();\n\t\t});\n\t}\n\n\t// MARK: Stop\n\tasync _stop() {\n\t\tif (this.#stopCalled) {\n\t\t\tlogger().warn(\"already stopping actor\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#stopCalled = true;\n\n\t\tlogger().info(\"actor stopping\");\n\n\t\t// Abort any listeners waiting for shutdown\n\t\ttry {\n\t\t\tthis.#abortController.abort();\n\t\t} catch {}\n\n\t\t// Call onStop lifecycle hook if defined\n\t\tif (this.#config.onStop) {\n\t\t\ttry {\n\t\t\t\tlogger().debug(\"calling onStop\");\n\t\t\t\tconst result = this.#config.onStop(this.actorContext);\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\tawait deadline(result, this.#config.options.onStopTimeout);\n\t\t\t\t}\n\t\t\t\tlogger().debug(\"onStop completed\");\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DeadlineError) {\n\t\t\t\t\tlogger().error(\"onStop timed out\");\n\t\t\t\t} else {\n\t\t\t\t\tlogger().error(\"error in onStop\", {\n\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Disconnect existing connections\n\t\tconst promises: Promise<unknown>[] = [];\n\t\tfor (const connection of this.#connections.values()) {\n\t\t\tpromises.push(connection.disconnect());\n\n\t\t\t// TODO: Figure out how to abort HTTP requests on shutdown\n\t\t}\n\n\t\t// Wait for any background tasks to finish, with timeout\n\t\tawait this.#waitBackgroundPromises(this.#config.options.waitUntilTimeout);\n\n\t\t// Clear timeouts\n\t\tif (this.#pendingSaveTimeout) clearTimeout(this.#pendingSaveTimeout);\n\t\tif (this.#sleepTimeout) clearTimeout(this.#sleepTimeout);\n\t\tif (this.#checkConnLivenessInterval)\n\t\t\tclearInterval(this.#checkConnLivenessInterval);\n\n\t\t// Write state\n\t\tawait this.saveState({ immediate: true, allowStoppingState: true });\n\n\t\t// Await all `close` event listeners with 1.5 second timeout\n\t\tconst res = Promise.race([\n\t\t\tPromise.all(promises).then(() => false),\n\t\t\tnew Promise<boolean>((res) =>\n\t\t\t\tglobalThis.setTimeout(() => res(true), 1500),\n\t\t\t),\n\t\t]);\n\n\t\tif (await res) {\n\t\t\tlogger().warn(\n\t\t\t\t\"timed out waiting for connections to close, shutting down anyway\",\n\t\t\t);\n\t\t}\n\n\t\t// Wait for queues to finish\n\t\tif (this.#persistWriteQueue.runningDrainLoop)\n\t\t\tawait this.#persistWriteQueue.runningDrainLoop;\n\t\tif (this.#alarmWriteQueue.runningDrainLoop)\n\t\t\tawait this.#alarmWriteQueue.runningDrainLoop;\n\t}\n\n\t/** Abort signal that fires when the actor is stopping. */\n\tget abortSignal(): AbortSignal {\n\t\treturn this.#abortController.signal;\n\t}\n\n\t/** Wait for background waitUntil promises with a timeout. */\n\tasync #waitBackgroundPromises(timeoutMs: number) {\n\t\tconst pending = this.#backgroundPromises;\n\t\tif (pending.length === 0) {\n\t\t\tlogger().debug(\"no background promises\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Race promises with timeout to determine if pending promises settled fast enough\n\t\tconst timedOut = await Promise.race([\n\t\t\tPromise.allSettled(pending).then(() => false),\n\t\t\tnew Promise<true>((resolve) =>\n\t\t\t\tsetTimeout(() => resolve(true), timeoutMs),\n\t\t\t),\n\t\t]);\n\n\t\tif (timedOut) {\n\t\t\tlogger().error(\n\t\t\t\t\"timed out waiting for background tasks, background promises may have leaked\",\n\t\t\t\t{\n\t\t\t\t\tcount: pending.length,\n\t\t\t\t\ttimeoutMs,\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tlogger().debug(\"background promises finished\");\n\t\t}\n\t}\n\n\t// MARK: BARE Conversion Helpers\n\t#convertToBarePersisted(\n\t\tpersist: PersistedActor<S, CP, CS, I>,\n\t): bareSchema.PersistedActor {\n\t\treturn {\n\t\t\tinput:\n\t\t\t\tpersist.input !== undefined\n\t\t\t\t\t? bufferToArrayBuffer(cbor.encode(persist.input))\n\t\t\t\t\t: null,\n\t\t\thasInitialized: persist.hasInitiated,\n\t\t\tstate: bufferToArrayBuffer(cbor.encode(persist.state)),\n\t\t\tconnections: persist.connections.map((conn) => ({\n\t\t\t\tid: conn.connId,\n\t\t\t\ttoken: conn.token,\n\t\t\t\tdriver: conn.connDriver as string,\n\t\t\t\tdriverState: bufferToArrayBuffer(\n\t\t\t\t\tcbor.encode(conn.connDriverState || {}),\n\t\t\t\t),\n\t\t\t\tparameters: bufferToArrayBuffer(cbor.encode(conn.params || {})),\n\t\t\t\tstate: bufferToArrayBuffer(cbor.encode(conn.state || {})),\n\t\t\t\tauth:\n\t\t\t\t\tconn.authData !== undefined\n\t\t\t\t\t\t? bufferToArrayBuffer(cbor.encode(conn.authData))\n\t\t\t\t\t\t: null,\n\t\t\t\tsubscriptions: conn.subscriptions.map((sub) => ({\n\t\t\t\t\teventName: sub.eventName,\n\t\t\t\t})),\n\t\t\t\tlastSeen: BigInt(conn.lastSeen),\n\t\t\t})),\n\t\t\tscheduledEvents: persist.scheduledEvents.map((event) => ({\n\t\t\t\teventId: event.eventId,\n\t\t\t\ttimestamp: BigInt(event.timestamp),\n\t\t\t\tkind: {\n\t\t\t\t\ttag: \"GenericPersistedScheduleEvent\" as const,\n\t\t\t\t\tval: {\n\t\t\t\t\t\taction: event.kind.generic.actionName,\n\t\t\t\t\t\targs: event.kind.generic.args ?? null,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})),\n\t\t};\n\t}\n\n\t#convertFromBarePersisted(\n\t\tbareData: bareSchema.PersistedActor,\n\t): PersistedActor<S, CP, CS, I> {\n\t\treturn {\n\t\t\tinput: bareData.input\n\t\t\t\t? cbor.decode(new Uint8Array(bareData.input))\n\t\t\t\t: undefined,\n\t\t\thasInitiated: bareData.hasInitialized,\n\t\t\tstate: cbor.decode(new Uint8Array(bareData.state)),\n\t\t\tconnections: bareData.connections.map((conn) => ({\n\t\t\t\tconnId: conn.id,\n\t\t\t\ttoken: conn.token,\n\t\t\t\tconnDriver: conn.driver as ConnectionDriver,\n\t\t\t\tconnDriverState: cbor.decode(new Uint8Array(conn.driverState)),\n\t\t\t\tparams: cbor.decode(new Uint8Array(conn.parameters)),\n\t\t\t\tstate: cbor.decode(new Uint8Array(conn.state)),\n\t\t\t\tauthData: conn.auth\n\t\t\t\t\t? cbor.decode(new Uint8Array(conn.auth))\n\t\t\t\t\t: undefined,\n\t\t\t\tsubscriptions: conn.subscriptions.map((sub) => ({\n\t\t\t\t\teventName: sub.eventName,\n\t\t\t\t})),\n\t\t\t\tlastSeen: Number(conn.lastSeen),\n\t\t\t})),\n\t\t\tscheduledEvents: bareData.scheduledEvents.map((event) => ({\n\t\t\t\teventId: event.eventId,\n\t\t\t\ttimestamp: Number(event.timestamp),\n\t\t\t\tkind: {\n\t\t\t\t\tgeneric: {\n\t\t\t\t\t\tactionName: event.kind.val.action,\n\t\t\t\t\t\targs: event.kind.val.args,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})),\n\t\t};\n\t}\n}\n","import { sValidator } from \"@hono/standard-validator\";\nimport jsonPatch from \"@rivetkit/fast-json-patch\";\nimport { Hono } from \"hono\";\nimport { streamSSE } from \"hono/streaming\";\nimport { createNanoEvents, type Unsubscribe } from \"nanoevents\";\nimport z from \"zod/v4\";\nimport type {\n\tAnyDatabaseProvider,\n\tInferDatabaseClient,\n} from \"@/actor/database\";\nimport {\n\tColumnsSchema,\n\ttype Connection,\n\tForeignKeysSchema,\n\tPatchSchema,\n\ttype RealtimeEvent,\n\ttype RecordedRealtimeEvent,\n\tTablesSchema,\n} from \"./protocol/common\";\n\nexport type ActorInspectorRouterEnv = {\n\tVariables: {\n\t\tinspector: ActorInspector;\n\t};\n};\n\n/**\n * Create a router for the Actor Inspector.\n * @internal\n */\nexport function createActorInspectorRouter() {\n\treturn new Hono<ActorInspectorRouterEnv>()\n\t\t.get(\"/ping\", (c) => {\n\t\t\treturn c.json({ message: \"pong\" }, 200);\n\t\t})\n\t\t.get(\"/state\", async (c) => {\n\t\t\tif (await c.var.inspector.accessors.isStateEnabled()) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tstate: await c.var.inspector.accessors.getState(),\n\t\t\t\t\t},\n\t\t\t\t\t200,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn c.json({ enabled: false, state: null }, 200);\n\t\t})\n\t\t.patch(\n\t\t\t\"/state\",\n\t\t\tsValidator(\n\t\t\t\t\"json\",\n\t\t\t\tz.object({ patch: PatchSchema }).or(z.object({ replace: z.any() })),\n\t\t\t),\n\t\t\tasync (c) => {\n\t\t\t\tif (!(await c.var.inspector.accessors.isStateEnabled())) {\n\t\t\t\t\treturn c.json({ enabled: false }, 200);\n\t\t\t\t}\n\n\t\t\t\tconst body = c.req.valid(\"json\");\n\t\t\t\tif (\"replace\" in body) {\n\t\t\t\t\tawait c.var.inspector.accessors.setState(body.replace);\n\t\t\t\t\treturn c.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\tstate: await c.var.inspector.accessors.getState(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t200,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst state = await c.var.inspector.accessors.getState();\n\n\t\t\t\tconst { newDocument: newState } = jsonPatch.applyPatch(\n\t\t\t\t\tstate,\n\t\t\t\t\tbody.patch,\n\t\t\t\t);\n\t\t\t\tawait c.var.inspector.accessors.setState(newState);\n\n\t\t\t\treturn c.json(\n\t\t\t\t\t{ enabled: true, state: await c.var.inspector.accessors.getState() },\n\t\t\t\t\t200,\n\t\t\t\t);\n\t\t\t},\n\t\t)\n\t\t.get(\"/state/stream\", async (c) => {\n\t\t\tif (!(await c.var.inspector.accessors.isStateEnabled())) {\n\t\t\t\treturn c.json({ enabled: false }, 200);\n\t\t\t}\n\n\t\t\tlet id = 0;\n\t\t\tlet unsub: Unsubscribe;\n\t\t\treturn streamSSE(\n\t\t\t\tc,\n\t\t\t\tasync (stream) => {\n\t\t\t\t\tunsub = c.var.inspector.emitter.on(\"stateUpdated\", async (state) => {\n\t\t\t\t\t\tstream.writeSSE({\n\t\t\t\t\t\t\tdata: JSON.stringify(state) || \"\",\n\t\t\t\t\t\t\tevent: \"state-update\",\n\t\t\t\t\t\t\tid: String(id++),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\tconst { promise } = Promise.withResolvers<void>();\n\n\t\t\t\t\treturn promise;\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tunsub?.();\n\t\t\t\t},\n\t\t\t);\n\t\t})\n\t\t.get(\"/connections\", async (c) => {\n\t\t\tconst connections = await c.var.inspector.accessors.getConnections();\n\t\t\treturn c.json({ connections }, 200);\n\t\t})\n\t\t.get(\"/connections/stream\", async (c) => {\n\t\t\tlet id = 0;\n\t\t\tlet unsub: Unsubscribe;\n\t\t\treturn streamSSE(\n\t\t\t\tc,\n\t\t\t\tasync (stream) => {\n\t\t\t\t\tunsub = c.var.inspector.emitter.on(\"connectionUpdated\", async () => {\n\t\t\t\t\t\tstream.writeSSE({\n\t\t\t\t\t\t\tdata: JSON.stringify(\n\t\t\t\t\t\t\t\tawait c.var.inspector.accessors.getConnections(),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tevent: \"connection-update\",\n\t\t\t\t\t\t\tid: String(id++),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\tconst { promise } = Promise.withResolvers<void>();\n\n\t\t\t\t\treturn promise;\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tunsub?.();\n\t\t\t\t},\n\t\t\t);\n\t\t})\n\t\t.get(\"/events\", async (c) => {\n\t\t\tconst events = c.var.inspector.lastRealtimeEvents;\n\t\t\treturn c.json({ events }, 200);\n\t\t})\n\t\t.post(\"/events/clear\", async (c) => {\n\t\t\tc.var.inspector.lastRealtimeEvents.length = 0; // Clear the events\n\t\t\treturn c.json({ message: \"Events cleared\" }, 200);\n\t\t})\n\t\t.get(\"/events/stream\", async (c) => {\n\t\t\tlet id = 0;\n\t\t\tlet unsub: Unsubscribe;\n\t\t\treturn streamSSE(\n\t\t\t\tc,\n\t\t\t\tasync (stream) => {\n\t\t\t\t\tunsub = c.var.inspector.emitter.on(\"eventFired\", () => {\n\t\t\t\t\t\tstream.writeSSE({\n\t\t\t\t\t\t\tdata: JSON.stringify(c.var.inspector.lastRealtimeEvents),\n\t\t\t\t\t\t\tevent: \"realtime-event\",\n\t\t\t\t\t\t\tid: String(id++),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\tconst { promise } = Promise.withResolvers<void>();\n\n\t\t\t\t\treturn promise;\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tunsub?.();\n\t\t\t\t},\n\t\t\t);\n\t\t})\n\t\t.get(\"/rpcs\", async (c) => {\n\t\t\tconst rpcs = await c.var.inspector.accessors.getRpcs();\n\t\t\treturn c.json({ rpcs }, 200);\n\t\t})\n\t\t.get(\"/db\", async (c) => {\n\t\t\tif (!(await c.var.inspector.accessors.isDbEnabled())) {\n\t\t\t\treturn c.json({ enabled: false, db: null }, 200);\n\t\t\t}\n\n\t\t\t// Access the SQLite database\n\t\t\tconst db = await c.var.inspector.accessors.getDb();\n\n\t\t\t// Get list of tables\n\t\t\tconst rows = await db.execute(`PRAGMA table_list`);\n\t\t\tconst tables = TablesSchema.parse(rows).filter(\n\t\t\t\t(table) => table.schema !== \"temp\" && !table.name.startsWith(\"sqlite_\"),\n\t\t\t);\n\t\t\t// Get columns for each table\n\t\t\tconst tablesInfo = await Promise.all(\n\t\t\t\ttables.map((table) => db.execute(`PRAGMA table_info(${table.name})`)),\n\t\t\t);\n\t\t\tconst columns = tablesInfo.map((def) => ColumnsSchema.parse(def));\n\n\t\t\t// Get foreign keys for each table\n\t\t\tconst foreignKeysList = await Promise.all(\n\t\t\t\ttables.map((table) =>\n\t\t\t\t\tdb.execute(`PRAGMA foreign_key_list(${table.name})`),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst foreignKeys = foreignKeysList.map((def) =>\n\t\t\t\tForeignKeysSchema.parse(def),\n\t\t\t);\n\n\t\t\t// Get record counts for each table\n\t\t\tconst countInfo = await Promise.all(\n\t\t\t\ttables.map((table) =>\n\t\t\t\t\tdb.execute(`SELECT COUNT(*) as count FROM ${table.name}`),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst counts = countInfo.map((def) => {\n\t\t\t\treturn def[0].count || 0;\n\t\t\t});\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tdb: tablesInfo.map((_, index) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttable: tables[index],\n\t\t\t\t\t\t\tcolumns: columns[index],\n\t\t\t\t\t\t\tforeignKeys: foreignKeys[index],\n\t\t\t\t\t\t\trecords: counts[index],\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t})\n\t\t.post(\n\t\t\t\"/db\",\n\t\t\tsValidator(\n\t\t\t\t\"json\",\n\t\t\t\tz.object({ query: z.string(), params: z.array(z.any()).optional() }),\n\t\t\t),\n\t\t\tasync (c) => {\n\t\t\t\tif (!(await c.var.inspector.accessors.isDbEnabled())) {\n\t\t\t\t\treturn c.json({ enabled: false }, 200);\n\t\t\t\t}\n\t\t\t\tconst db = await c.var.inspector.accessors.getDb();\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = (await db.execute(\n\t\t\t\t\t\tc.req.valid(\"json\").query,\n\t\t\t\t\t\t...(c.req.valid(\"json\").params || []),\n\t\t\t\t\t)) as unknown;\n\t\t\t\t\treturn c.json({ result }, 200);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tc;\n\t\t\t\t\treturn c.json({ error: (error as Error).message }, 500);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n}\n\ninterface ActorInspectorAccessors {\n\tisStateEnabled: () => Promise<boolean>;\n\tgetState: () => Promise<unknown>;\n\tsetState: (state: unknown) => Promise<void>;\n\tisDbEnabled: () => Promise<boolean>;\n\tgetDb: () => Promise<InferDatabaseClient<AnyDatabaseProvider>>;\n\tgetRpcs: () => Promise<string[]>;\n\tgetConnections: () => Promise<Connection[]>;\n}\n\ninterface ActorInspectorEmitterEvents {\n\tstateUpdated: (state: unknown) => void;\n\tconnectionUpdated: () => void;\n\teventFired: (event: RealtimeEvent) => void;\n}\n\n/**\n * Provides a unified interface for inspecting actor external and internal state.\n */\nexport class ActorInspector {\n\tpublic readonly accessors: ActorInspectorAccessors;\n\tpublic readonly emitter = createNanoEvents<ActorInspectorEmitterEvents>();\n\n\t#lastRealtimeEvents: RecordedRealtimeEvent[] = [];\n\n\tget lastRealtimeEvents() {\n\t\treturn this.#lastRealtimeEvents;\n\t}\n\n\tconstructor(accessors: () => ActorInspectorAccessors) {\n\t\tthis.accessors = accessors();\n\t\tthis.emitter.on(\"eventFired\", (event) => {\n\t\t\tthis.#lastRealtimeEvents.push({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t...event,\n\t\t\t});\n\t\t\t// keep the last 100 events\n\t\t\tif (this.#lastRealtimeEvents.length > 100) {\n\t\t\t\tthis.#lastRealtimeEvents = this.#lastRealtimeEvents.slice(-100);\n\t\t\t}\n\t\t});\n\t}\n}\n","import type { ActorKey } from \"@/actor/mod\";\nimport type { Client } from \"@/client/client\";\nimport type { Logger } from \"@/common/log\";\nimport type { Registry } from \"@/registry/mod\";\nimport type { Conn, ConnId } from \"./connection\";\nimport type { AnyDatabaseProvider, InferDatabaseClient } from \"./database\";\nimport type { ActorInstance, SaveStateOptions } from \"./instance\";\nimport type { Schedule } from \"./schedule\";\n\n/**\n * ActorContext class that provides access to actor methods and state\n */\nexport class ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTAuthData,\n\tTDatabase extends AnyDatabaseProvider,\n> {\n\t#actor: ActorInstance<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTAuthData,\n\t\tTDatabase\n\t>;\n\n\tconstructor(\n\t\tactor: ActorInstance<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTAuthData,\n\t\t\tTDatabase\n\t\t>,\n\t) {\n\t\tthis.#actor = actor;\n\t}\n\n\t/**\n\t * Get the actor state\n\t */\n\tget state(): TState {\n\t\treturn this.#actor.state;\n\t}\n\n\t/**\n\t * Get the actor variables\n\t */\n\tget vars(): TVars {\n\t\treturn this.#actor.vars;\n\t}\n\n\t/**\n\t * Broadcasts an event to all connected clients.\n\t * @param name - The name of the event.\n\t * @param args - The arguments to send with the event.\n\t */\n\tbroadcast<Args extends Array<unknown>>(name: string, ...args: Args): void {\n\t\tthis.#actor._broadcast(name, ...args);\n\t\treturn;\n\t}\n\n\t/**\n\t * Gets the logger instance.\n\t */\n\tget log(): Logger {\n\t\treturn this.#actor.log;\n\t}\n\n\t/**\n\t * Gets actor ID.\n\t */\n\tget actorId(): string {\n\t\treturn this.#actor.id;\n\t}\n\n\t/**\n\t * Gets the actor name.\n\t */\n\tget name(): string {\n\t\treturn this.#actor.name;\n\t}\n\n\t/**\n\t * Gets the actor key.\n\t */\n\tget key(): ActorKey {\n\t\treturn this.#actor.key;\n\t}\n\n\t/**\n\t * Gets the region.\n\t */\n\tget region(): string {\n\t\treturn this.#actor.region;\n\t}\n\n\t/**\n\t * Gets the scheduler.\n\t */\n\tget schedule(): Schedule {\n\t\treturn this.#actor.schedule;\n\t}\n\n\t/**\n\t * Gets the map of connections.\n\t */\n\tget conns(): Map<\n\t\tConnId,\n\t\tConn<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>\n\t> {\n\t\treturn this.#actor.conns;\n\t}\n\n\t/**\n\t * Returns the client for the given registry.\n\t */\n\tclient<R extends Registry<any>>(): Client<R> {\n\t\treturn this.#actor.inlineClient as Client<R>;\n\t}\n\n\t/**\n\t * Gets the database.\n\t * @experimental\n\t * @throws {DatabaseNotEnabled} If the database is not enabled.\n\t */\n\tget db(): InferDatabaseClient<TDatabase> {\n\t\treturn this.#actor.db;\n\t}\n\n\t/**\n\t * Forces the state to get saved.\n\t *\n\t * @param opts - Options for saving the state.\n\t */\n\tasync saveState(opts: SaveStateOptions): Promise<void> {\n\t\treturn this.#actor.saveState(opts);\n\t}\n\n\t/**\n\t * Prevents the actor from sleeping until promise is complete.\n\t */\n\twaitUntil(promise: Promise<void>): void {\n\t\tthis.#actor._waitUntil(promise);\n\t}\n\n\t/**\n\t * AbortSignal that fires when the actor is stopping.\n\t */\n\tget abortSignal(): AbortSignal {\n\t\treturn this.#actor.abortSignal;\n\t}\n\n\t/**\n\t * Forces the actor to sleep.\n\t *\n\t * Not supported on all drivers.\n\t *\n\t * @experimental\n\t */\n\tsleep() {\n\t\tthis.#actor._sleep();\n\t}\n}\n","import type { AnyActorInstance } from \"./instance\";\n\nexport class Schedule {\n\t#actor: AnyActorInstance;\n\n\tconstructor(actor: AnyActorInstance) {\n\t\tthis.#actor = actor;\n\t}\n\n\tasync after(duration: number, fn: string, ...args: unknown[]) {\n\t\tawait this.#actor.scheduleEvent(Date.now() + duration, fn, args);\n\t}\n\n\tasync at(timestamp: number, fn: string, ...args: unknown[]) {\n\t\tawait this.#actor.scheduleEvent(timestamp, fn, args);\n\t}\n}\n","import type { RegistryConfig } from \"@/registry/config\";\nimport type { ActionContext } from \"./action\";\nimport type { Actions, ActorConfig } from \"./config\";\nimport type { ActorContext } from \"./context\";\nimport type { AnyDatabaseProvider } from \"./database\";\nimport { ActorInstance } from \"./instance\";\n\nexport type AnyActorDefinition = ActorDefinition<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\n/**\n * Extracts the context type from an ActorDefinition\n */\nexport type ActorContextOf<AD extends AnyActorDefinition> =\n\tAD extends ActorDefinition<\n\t\tinfer S,\n\t\tinfer CP,\n\t\tinfer CS,\n\t\tinfer V,\n\t\tinfer I,\n\t\tinfer AD,\n\t\tinfer DB,\n\t\tany\n\t>\n\t\t? ActorContext<S, CP, CS, V, I, AD, DB>\n\t\t: never;\n\n/**\n * Extracts the context type from an ActorDefinition\n */\nexport type ActionContextOf<AD extends AnyActorDefinition> =\n\tAD extends ActorDefinition<\n\t\tinfer S,\n\t\tinfer CP,\n\t\tinfer CS,\n\t\tinfer V,\n\t\tinfer I,\n\t\tinfer AD,\n\t\tinfer DB,\n\t\tany\n\t>\n\t\t? ActionContext<S, CP, CS, V, I, AD, DB>\n\t\t: never;\n\nexport class ActorDefinition<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tAD,\n\tDB extends AnyDatabaseProvider,\n\tR extends Actions<S, CP, CS, V, I, AD, DB>,\n> {\n\t#config: ActorConfig<S, CP, CS, V, I, AD, DB>;\n\n\tconstructor(config: ActorConfig<S, CP, CS, V, I, AD, DB>) {\n\t\tthis.#config = config;\n\t}\n\n\tget config(): ActorConfig<S, CP, CS, V, I, AD, DB> {\n\t\treturn this.#config;\n\t}\n\n\tinstantiate(): ActorInstance<S, CP, CS, V, I, AD, DB> {\n\t\treturn new ActorInstance(this.#config);\n\t}\n}\n\nexport function lookupInRegistry(\n\tregistryConfig: RegistryConfig,\n\tname: string,\n): AnyActorDefinition {\n\t// Build actor\n\tconst definition = registryConfig.use[name];\n\tif (!definition) throw new Error(`no actor in registry for name ${name}`);\n\treturn definition;\n}\n","import { MAX_CONN_PARAMS_SIZE } from \"@/common//network\";\n\nexport class ActorClientError extends Error {}\n\nexport class InternalError extends ActorClientError {}\n\nexport class ManagerError extends ActorClientError {\n\tconstructor(error: string, opts?: ErrorOptions) {\n\t\tsuper(`Manager error: ${error}`, opts);\n\t}\n}\n\nexport class MalformedResponseMessage extends ActorClientError {\n\tconstructor(cause?: unknown) {\n\t\tsuper(`Malformed response message: ${cause}`, { cause });\n\t}\n}\n\nexport class ActorError extends ActorClientError {\n\t__type = \"ActorError\";\n\n\tconstructor(\n\t\tpublic readonly code: string,\n\t\tmessage: string,\n\t\tpublic readonly metadata?: unknown,\n\t) {\n\t\tsuper(message);\n\t}\n}\n\nexport class HttpRequestError extends ActorClientError {\n\tconstructor(message: string, opts?: { cause?: unknown }) {\n\t\tsuper(`HTTP request error: ${message}`, { cause: opts?.cause });\n\t}\n}\n\nexport class ActorConnDisposed extends ActorClientError {\n\tconstructor() {\n\t\tsuper(\"Attempting to interact with a disposed actor connection.\");\n\t}\n}\n","import * as cbor from \"cbor-x\";\nimport invariant from \"invariant\";\nimport pRetry from \"p-retry\";\nimport type { CloseEvent, WebSocket } from \"ws\";\nimport type { AnyActorDefinition } from \"@/actor/definition\";\nimport { inputDataToBuffer } from \"@/actor/protocol/old\";\nimport { type Encoding, jsonStringifyCompat } from \"@/actor/protocol/serde\";\nimport type {\n\tUniversalErrorEvent,\n\tUniversalEventSource,\n\tUniversalMessageEvent,\n} from \"@/common/eventsource-interface\";\nimport { assertUnreachable, stringifyError } from \"@/common/utils\";\nimport type { ActorQuery } from \"@/manager/protocol/query\";\nimport type * as protocol from \"@/schemas/client-protocol/mod\";\nimport {\n\tTO_CLIENT_VERSIONED,\n\tTO_SERVER_VERSIONED,\n} from \"@/schemas/client-protocol/versioned\";\nimport {\n\tdeserializeWithEncoding,\n\tencodingIsBinary,\n\tserializeWithEncoding,\n} from \"@/serde\";\nimport { bufferToArrayBuffer, getEnvUniversal } from \"@/utils\";\nimport type { ActorDefinitionActions } from \"./actor-common\";\nimport {\n\tACTOR_CONNS_SYMBOL,\n\ttype ClientDriver,\n\ttype ClientRaw,\n\tTRANSPORT_SYMBOL,\n} from \"./client\";\nimport * as errors from \"./errors\";\nimport { logger } from \"./log\";\nimport { type WebSocketMessage as ConnMessage, messageLength } from \"./utils\";\n\ninterface ActionInFlight {\n\tname: string;\n\tresolve: (response: protocol.ActionResponse) => void;\n\treject: (error: Error) => void;\n}\n\ninterface EventSubscriptions<Args extends Array<unknown>> {\n\tcallback: (...args: Args) => void;\n\tonce: boolean;\n}\n\n/**\n * A function that unsubscribes from an event.\n *\n * @typedef {Function} EventUnsubscribe\n */\nexport type EventUnsubscribe = () => void;\n\n/**\n * A function that handles connection errors.\n *\n * @typedef {Function} ActorErrorCallback\n */\nexport type ActorErrorCallback = (error: errors.ActorError) => void;\n\nexport interface SendHttpMessageOpts {\n\tephemeral: boolean;\n\tsignal?: AbortSignal;\n}\n\nexport type ConnTransport =\n\t| { websocket: WebSocket }\n\t| { sse: UniversalEventSource };\n\nexport const CONNECT_SYMBOL = Symbol(\"connect\");\n\n/**\n * Provides underlying functions for {@link ActorConn}. See {@link ActorConn} for using type-safe remote procedure calls.\n *\n * @see {@link ActorConn}\n */\nexport class ActorConnRaw {\n\t#disposed = false;\n\n\t/* Will be aborted on dispose. */\n\t#abortController = new AbortController();\n\n\t/** If attempting to connect. Helpful for knowing if in a retry loop when reconnecting. */\n\t#connecting = false;\n\n\t// These will only be set on SSE driver\n\t#actorId?: string;\n\t#connectionId?: string;\n\t#connectionToken?: string;\n\n\t#transport?: ConnTransport;\n\n\t#messageQueue: protocol.ToServer[] = [];\n\t#actionsInFlight = new Map<number, ActionInFlight>();\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Unknown subscription type\n\t#eventSubscriptions = new Map<string, Set<EventSubscriptions<any[]>>>();\n\n\t#errorHandlers = new Set<ActorErrorCallback>();\n\n\t#actionIdCounter = 0;\n\n\t/**\n\t * Interval that keeps the NodeJS process alive if this is the only thing running.\n\t *\n\t * See ttps://github.com/nodejs/node/issues/22088\n\t */\n\t#keepNodeAliveInterval: NodeJS.Timeout;\n\n\t/** Promise used to indicate the socket has connected successfully. This will be rejected if the connection fails. */\n\t#onOpenPromise?: PromiseWithResolvers<undefined>;\n\n\t#client: ClientRaw;\n\t#driver: ClientDriver;\n\t#params: unknown;\n\t#encodingKind: Encoding;\n\t#actorQuery: ActorQuery;\n\n\t// TODO: ws message queue\n\n\t/**\n\t * Do not call this directly.\n\t *\n\t * Creates an instance of ActorConnRaw.\n\t *\n\t * @protected\n\t */\n\tpublic constructor(\n\t\tclient: ClientRaw,\n\t\tdriver: ClientDriver,\n\t\tparams: unknown,\n\t\tencodingKind: Encoding,\n\t\tactorQuery: ActorQuery,\n\t) {\n\t\tthis.#client = client;\n\t\tthis.#driver = driver;\n\t\tthis.#params = params;\n\t\tthis.#encodingKind = encodingKind;\n\t\tthis.#actorQuery = actorQuery;\n\n\t\tthis.#keepNodeAliveInterval = setInterval(() => 60_000);\n\t}\n\n\t/**\n\t * Call a raw action connection. See {@link ActorConn} for type-safe action calls.\n\t *\n\t * @see {@link ActorConn}\n\t * @template Args - The type of arguments to pass to the action function.\n\t * @template Response - The type of the response returned by the action function.\n\t * @param {string} name - The name of the action function to call.\n\t * @param {...Args} args - The arguments to pass to the action function.\n\t * @returns {Promise<Response>} - A promise that resolves to the response of the action function.\n\t */\n\tasync action<\n\t\tArgs extends Array<unknown> = unknown[],\n\t\tResponse = unknown,\n\t>(opts: {\n\t\tname: string;\n\t\targs: Args;\n\t\tsignal?: AbortSignal;\n\t}): Promise<Response> {\n\t\tlogger().debug(\"action\", { name: opts.name, args: opts.args });\n\n\t\t// If we have an active connection, use the websockactionId\n\t\tconst actionId = this.#actionIdCounter;\n\t\tthis.#actionIdCounter += 1;\n\n\t\tconst { promise, resolve, reject } =\n\t\t\tPromise.withResolvers<protocol.ActionResponse>();\n\t\tthis.#actionsInFlight.set(actionId, { name: opts.name, resolve, reject });\n\n\t\tthis.#sendMessage({\n\t\t\tbody: {\n\t\t\t\ttag: \"ActionRequest\",\n\t\t\t\tval: {\n\t\t\t\t\tid: BigInt(actionId),\n\t\t\t\t\tname: opts.name,\n\t\t\t\t\targs: bufferToArrayBuffer(cbor.encode(opts.args)),\n\t\t\t\t},\n\t\t\t},\n\t\t} satisfies protocol.ToServer);\n\n\t\t// TODO: Throw error if disconnect is called\n\n\t\tconst { id: responseId, output } = await promise;\n\t\tif (responseId !== BigInt(actionId))\n\t\t\tthrow new Error(\n\t\t\t\t`Request ID ${actionId} does not match response ID ${responseId}`,\n\t\t\t);\n\n\t\treturn cbor.decode(new Uint8Array(output)) as Response;\n\t}\n\n\t/**\n\t * Do not call this directly.\nenc\n\t * Establishes a connection to the server using the specified endpoint & encoding & driver.\n\t *\n\t * @protected\n\t */\n\tpublic [CONNECT_SYMBOL]() {\n\t\tthis.#connectWithRetry();\n\t}\n\n\tasync #connectWithRetry() {\n\t\tthis.#connecting = true;\n\n\t\t// Attempt to reconnect indefinitely\n\t\ttry {\n\t\t\tawait pRetry(this.#connectAndWait.bind(this), {\n\t\t\t\tforever: true,\n\t\t\t\tminTimeout: 250,\n\t\t\t\tmaxTimeout: 30_000,\n\n\t\t\t\tonFailedAttempt: (error) => {\n\t\t\t\t\tlogger().warn(\"failed to reconnect\", {\n\t\t\t\t\t\tattempt: error.attemptNumber,\n\t\t\t\t\t\terror: stringifyError(error),\n\t\t\t\t\t});\n\t\t\t\t},\n\n\t\t\t\t// Cancel retry if aborted\n\t\t\t\tsignal: this.#abortController.signal,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif ((err as Error).name === \"AbortError\") {\n\t\t\t\t// Ignore abortions\n\t\t\t\tlogger().info(\"connection retry aborted\");\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t// Unknown error\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\tthis.#connecting = false;\n\t}\n\n\tasync #connectAndWait() {\n\t\ttry {\n\t\t\t// Create promise for open\n\t\t\tif (this.#onOpenPromise)\n\t\t\t\tthrow new Error(\"#onOpenPromise already defined\");\n\t\t\tthis.#onOpenPromise = Promise.withResolvers();\n\n\t\t\t// Connect transport\n\t\t\tif (this.#client[TRANSPORT_SYMBOL] === \"websocket\") {\n\t\t\t\tawait this.#connectWebSocket();\n\t\t\t} else if (this.#client[TRANSPORT_SYMBOL] === \"sse\") {\n\t\t\t\tawait this.#connectSse();\n\t\t\t} else {\n\t\t\t\tassertUnreachable(this.#client[TRANSPORT_SYMBOL]);\n\t\t\t}\n\n\t\t\t// Wait for result\n\t\t\tawait this.#onOpenPromise.promise;\n\t\t} finally {\n\t\t\tthis.#onOpenPromise = undefined;\n\t\t}\n\t}\n\n\tasync #connectWebSocket({ signal }: { signal?: AbortSignal } = {}) {\n\t\tconst ws = await this.#driver.connectWebSocket(\n\t\t\tundefined,\n\t\t\tthis.#actorQuery,\n\t\t\tthis.#encodingKind,\n\t\t\tthis.#params,\n\t\t\tsignal ? { signal } : undefined,\n\t\t);\n\t\tthis.#transport = { websocket: ws };\n\t\tws.addEventListener(\"open\", () => {\n\t\t\tlogger().debug(\"websocket open\");\n\t\t});\n\t\tws.addEventListener(\"message\", async (ev) => {\n\t\t\tthis.#handleOnMessage(ev.data);\n\t\t});\n\t\tws.addEventListener(\"close\", (ev) => {\n\t\t\tthis.#handleOnClose(ev);\n\t\t});\n\t\tws.addEventListener(\"error\", (_ev) => {\n\t\t\tthis.#handleOnError();\n\t\t});\n\t}\n\n\tasync #connectSse({ signal }: { signal?: AbortSignal } = {}) {\n\t\tconst eventSource = await this.#driver.connectSse(\n\t\t\tundefined,\n\t\t\tthis.#actorQuery,\n\t\t\tthis.#encodingKind,\n\t\t\tthis.#params,\n\t\t\tsignal ? { signal } : undefined,\n\t\t);\n\t\tthis.#transport = { sse: eventSource };\n\t\teventSource.onopen = () => {\n\t\t\tlogger().debug(\"eventsource open\");\n\t\t\t// #handleOnOpen is called on \"i\" event\n\t\t};\n\t\teventSource.onmessage = (ev: UniversalMessageEvent) => {\n\t\t\tthis.#handleOnMessage(ev.data);\n\t\t};\n\t\teventSource.onerror = (_ev: UniversalErrorEvent) => {\n\t\t\tif (eventSource.readyState === eventSource.CLOSED) {\n\t\t\t\t// This error indicates a close event\n\t\t\t\tthis.#handleOnClose(new Event(\"error\"));\n\t\t\t} else {\n\t\t\t\t// Log error since event source is still open\n\t\t\t\tthis.#handleOnError();\n\t\t\t}\n\t\t};\n\t}\n\n\t/** Called by the onopen event from drivers. */\n\t#handleOnOpen() {\n\t\tlogger().debug(\"socket open\", {\n\t\t\tmessageQueueLength: this.#messageQueue.length,\n\t\t});\n\n\t\t// Resolve open promise\n\t\tif (this.#onOpenPromise) {\n\t\t\tthis.#onOpenPromise.resolve(undefined);\n\t\t} else {\n\t\t\tlogger().warn(\"#onOpenPromise is undefined\");\n\t\t}\n\n\t\t// Resubscribe to all active events\n\t\tfor (const eventName of this.#eventSubscriptions.keys()) {\n\t\t\tthis.#sendSubscription(eventName, true);\n\t\t}\n\n\t\t// Flush queue\n\t\t//\n\t\t// If the message fails to send, the message will be re-queued\n\t\tconst queue = this.#messageQueue;\n\t\tthis.#messageQueue = [];\n\t\tfor (const msg of queue) {\n\t\t\tthis.#sendMessage(msg);\n\t\t}\n\t}\n\n\t/** Called by the onmessage event from drivers. */\n\tasync #handleOnMessage(data: any) {\n\t\tlogger().trace(\"received message\", {\n\t\t\tdataType: typeof data,\n\t\t\tisBlob: data instanceof Blob,\n\t\t\tisArrayBuffer: data instanceof ArrayBuffer,\n\t\t});\n\n\t\tconst response = await this.#parseMessage(data as ConnMessage);\n\t\tlogger().trace(\n\t\t\t\"parsed message\",\n\t\t\tgetEnvUniversal(\"_RIVETKIT_LOG_MESSAGE\")\n\t\t\t\t? {\n\t\t\t\t\t\tmessage: jsonStringifyCompat(response).substring(0, 100) + \"...\",\n\t\t\t\t\t}\n\t\t\t\t: {},\n\t\t);\n\n\t\tif (response.body.tag === \"Init\") {\n\t\t\t// This is only called for SSE\n\t\t\tthis.#actorId = response.body.val.actorId;\n\t\t\tthis.#connectionId = response.body.val.connectionId;\n\t\t\tthis.#connectionToken = response.body.val.connectionToken;\n\t\t\tlogger().trace(\"received init message\", {\n\t\t\t\tactorId: this.#actorId,\n\t\t\t\tconnectionId: this.#connectionId,\n\t\t\t});\n\t\t\tthis.#handleOnOpen();\n\t\t} else if (response.body.tag === \"Error\") {\n\t\t\t// Connection error\n\t\t\tconst { code, message, metadata, actionId } = response.body.val;\n\n\t\t\tif (actionId) {\n\t\t\t\tconst inFlight = this.#takeActionInFlight(Number(actionId));\n\n\t\t\t\tlogger().warn(\"action error\", {\n\t\t\t\t\tactionId: actionId,\n\t\t\t\t\tactionName: inFlight?.name,\n\t\t\t\t\tcode,\n\t\t\t\t\tmessage,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\n\t\t\t\tinFlight.reject(new errors.ActorError(code, message, metadata));\n\t\t\t} else {\n\t\t\t\tlogger().warn(\"connection error\", {\n\t\t\t\t\tcode,\n\t\t\t\t\tmessage,\n\t\t\t\t\tmetadata,\n\t\t\t\t});\n\n\t\t\t\t// Create a connection error\n\t\t\t\tconst actorError = new errors.ActorError(code, message, metadata);\n\n\t\t\t\t// If we have an onOpenPromise, reject it with the error\n\t\t\t\tif (this.#onOpenPromise) {\n\t\t\t\t\tthis.#onOpenPromise.reject(actorError);\n\t\t\t\t}\n\n\t\t\t\t// Reject any in-flight requests\n\t\t\t\tfor (const [id, inFlight] of this.#actionsInFlight.entries()) {\n\t\t\t\t\tinFlight.reject(actorError);\n\t\t\t\t\tthis.#actionsInFlight.delete(id);\n\t\t\t\t}\n\n\t\t\t\t// Dispatch to error handler if registered\n\t\t\t\tthis.#dispatchActorError(actorError);\n\t\t\t}\n\t\t} else if (response.body.tag === \"ActionResponse\") {\n\t\t\t// Action response OK\n\t\t\tconst { id: actionId } = response.body.val;\n\t\t\tlogger().trace(\"received action response\", {\n\t\t\t\tactionId,\n\t\t\t});\n\n\t\t\tconst inFlight = this.#takeActionInFlight(Number(actionId));\n\t\t\tlogger().trace(\"resolving action promise\", {\n\t\t\t\tactionId,\n\t\t\t\tactionName: inFlight?.name,\n\t\t\t});\n\t\t\tinFlight.resolve(response.body.val);\n\t\t} else if (response.body.tag === \"Event\") {\n\t\t\tlogger().trace(\"received event\", { name: response.body.val.name });\n\t\t\tthis.#dispatchEvent(response.body.val);\n\t\t} else {\n\t\t\tassertUnreachable(response.body);\n\t\t}\n\t}\n\n\t/** Called by the onclose event from drivers. */\n\t#handleOnClose(event: Event | CloseEvent) {\n\t\t// TODO: Handle queue\n\t\t// TODO: Reconnect with backoff\n\n\t\t// Reject open promise\n\t\tif (this.#onOpenPromise) {\n\t\t\tthis.#onOpenPromise.reject(new Error(\"Closed\"));\n\t\t}\n\n\t\t// We can't use `event instanceof CloseEvent` because it's not defined in NodeJS\n\t\t//\n\t\t// These properties will be undefined\n\t\tconst closeEvent = event as CloseEvent;\n\t\tif (closeEvent.wasClean) {\n\t\t\tlogger().info(\"socket closed\", {\n\t\t\t\tcode: closeEvent.code,\n\t\t\t\treason: closeEvent.reason,\n\t\t\t\twasClean: closeEvent.wasClean,\n\t\t\t});\n\t\t} else {\n\t\t\tlogger().warn(\"socket closed\", {\n\t\t\t\tcode: closeEvent.code,\n\t\t\t\treason: closeEvent.reason,\n\t\t\t\twasClean: closeEvent.wasClean,\n\t\t\t});\n\t\t}\n\n\t\tthis.#transport = undefined;\n\n\t\t// Automatically reconnect. Skip if already attempting to connect.\n\t\tif (!this.#disposed && !this.#connecting) {\n\t\t\t// TODO: Fetch actor to check if it's destroyed\n\t\t\t// TODO: Add backoff for reconnect\n\t\t\t// TODO: Add a way of preserving connection ID for connection state\n\n\t\t\t// Attempt to connect again\n\t\t\tthis.#connectWithRetry();\n\t\t}\n\t}\n\n\t/** Called by the onerror event from drivers. */\n\t#handleOnError() {\n\t\tif (this.#disposed) return;\n\n\t\t// More detailed information will be logged in onclose\n\t\tlogger().warn(\"socket error\");\n\t}\n\n\t#takeActionInFlight(id: number): ActionInFlight {\n\t\tconst inFlight = this.#actionsInFlight.get(id);\n\t\tif (!inFlight) {\n\t\t\tthrow new errors.InternalError(`No in flight response for ${id}`);\n\t\t}\n\t\tthis.#actionsInFlight.delete(id);\n\t\treturn inFlight;\n\t}\n\n\t#dispatchEvent(event: protocol.Event) {\n\t\tconst { name, args: argsRaw } = event;\n\t\tconst args = cbor.decode(new Uint8Array(argsRaw));\n\n\t\tconst listeners = this.#eventSubscriptions.get(name);\n\t\tif (!listeners) return;\n\n\t\t// Create a new array to avoid issues with listeners being removed during iteration\n\t\tfor (const listener of [...listeners]) {\n\t\t\tlistener.callback(...args);\n\n\t\t\t// Remove if this was a one-time listener\n\t\t\tif (listener.once) {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t}\n\t\t}\n\n\t\t// Clean up empty listener sets\n\t\tif (listeners.size === 0) {\n\t\t\tthis.#eventSubscriptions.delete(name);\n\t\t}\n\t}\n\n\t#dispatchActorError(error: errors.ActorError) {\n\t\t// Call all registered error handlers\n\t\tfor (const handler of [...this.#errorHandlers]) {\n\t\t\ttry {\n\t\t\t\thandler(error);\n\t\t\t} catch (err) {\n\t\t\t\tlogger().error(\"Error in connection error handler\", {\n\t\t\t\t\terror: stringifyError(err),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t#addEventSubscription<Args extends Array<unknown>>(\n\t\teventName: string,\n\t\tcallback: (...args: Args) => void,\n\t\tonce: boolean,\n\t): EventUnsubscribe {\n\t\tconst listener: EventSubscriptions<Args> = {\n\t\t\tcallback,\n\t\t\tonce,\n\t\t};\n\n\t\tlet subscriptionSet = this.#eventSubscriptions.get(eventName);\n\t\tif (subscriptionSet === undefined) {\n\t\t\tsubscriptionSet = new Set();\n\t\t\tthis.#eventSubscriptions.set(eventName, subscriptionSet);\n\t\t\tthis.#sendSubscription(eventName, true);\n\t\t}\n\t\tsubscriptionSet.add(listener);\n\n\t\t// Return unsubscribe function\n\t\treturn () => {\n\t\t\tconst listeners = this.#eventSubscriptions.get(eventName);\n\t\t\tif (listeners) {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t\tif (listeners.size === 0) {\n\t\t\t\t\tthis.#eventSubscriptions.delete(eventName);\n\t\t\t\t\tthis.#sendSubscription(eventName, false);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Subscribes to an event that will happen repeatedly.\n\t *\n\t * @template Args - The type of arguments the event callback will receive.\n\t * @param {string} eventName - The name of the event to subscribe to.\n\t * @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.\n\t * @returns {EventUnsubscribe} - A function to unsubscribe from the event.\n\t * @see {@link https://rivet.gg/docs/events|Events Documentation}\n\t */\n\ton<Args extends Array<unknown> = unknown[]>(\n\t\teventName: string,\n\t\tcallback: (...args: Args) => void,\n\t): EventUnsubscribe {\n\t\treturn this.#addEventSubscription<Args>(eventName, callback, false);\n\t}\n\n\t/**\n\t * Subscribes to an event that will be triggered only once.\n\t *\n\t * @template Args - The type of arguments the event callback will receive.\n\t * @param {string} eventName - The name of the event to subscribe to.\n\t * @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.\n\t * @returns {EventUnsubscribe} - A function to unsubscribe from the event.\n\t * @see {@link https://rivet.gg/docs/events|Events Documentation}\n\t */\n\tonce<Args extends Array<unknown> = unknown[]>(\n\t\teventName: string,\n\t\tcallback: (...args: Args) => void,\n\t): EventUnsubscribe {\n\t\treturn this.#addEventSubscription<Args>(eventName, callback, true);\n\t}\n\n\t/**\n\t * Subscribes to connection errors.\n\t *\n\t * @param {ActorErrorCallback} callback - The callback function to execute when a connection error occurs.\n\t * @returns {() => void} - A function to unsubscribe from the error handler.\n\t */\n\tonError(callback: ActorErrorCallback): () => void {\n\t\tthis.#errorHandlers.add(callback);\n\n\t\t// Return unsubscribe function\n\t\treturn () => {\n\t\t\tthis.#errorHandlers.delete(callback);\n\t\t};\n\t}\n\n\t#sendMessage(message: protocol.ToServer, opts?: SendHttpMessageOpts) {\n\t\tif (this.#disposed) {\n\t\t\tthrow new errors.ActorConnDisposed();\n\t\t}\n\n\t\tlet queueMessage = false;\n\t\tif (!this.#transport) {\n\t\t\t// No transport connected yet\n\t\t\tqueueMessage = true;\n\t\t} else if (\"websocket\" in this.#transport) {\n\t\t\tif (this.#transport.websocket.readyState === 1) {\n\t\t\t\ttry {\n\t\t\t\t\tconst messageSerialized = serializeWithEncoding(\n\t\t\t\t\t\tthis.#encodingKind,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t\tTO_SERVER_VERSIONED,\n\t\t\t\t\t);\n\t\t\t\t\tthis.#transport.websocket.send(messageSerialized);\n\t\t\t\t\tlogger().trace(\"sent websocket message\", {\n\t\t\t\t\t\tlen: messageLength(messageSerialized),\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger().warn(\"failed to send message, added to queue\", {\n\t\t\t\t\t\terror,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Assuming the socket is disconnected and will be reconnected soon\n\t\t\t\t\tqueueMessage = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tqueueMessage = true;\n\t\t\t}\n\t\t} else if (\"sse\" in this.#transport) {\n\t\t\tif (this.#transport.sse.readyState === 1) {\n\t\t\t\t// Spawn in background since #sendMessage cannot be async\n\t\t\t\tthis.#sendHttpMessage(message, opts);\n\t\t\t} else {\n\t\t\t\tqueueMessage = true;\n\t\t\t}\n\t\t} else {\n\t\t\tassertUnreachable(this.#transport);\n\t\t}\n\n\t\tif (!opts?.ephemeral && queueMessage) {\n\t\t\tthis.#messageQueue.push(message);\n\t\t\tlogger().debug(\"queued connection message\");\n\t\t}\n\t}\n\n\tasync #sendHttpMessage(\n\t\tmessage: protocol.ToServer,\n\t\topts?: SendHttpMessageOpts,\n\t) {\n\t\ttry {\n\t\t\tif (!this.#actorId || !this.#connectionId || !this.#connectionToken)\n\t\t\t\tthrow new errors.InternalError(\"Missing connection ID or token.\");\n\n\t\t\tlogger().trace(\n\t\t\t\t\"sent http message\",\n\t\t\t\tgetEnvUniversal(\"_RIVETKIT_LOG_MESSAGE\")\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmessage: jsonStringifyCompat(message).substring(0, 100) + \"...\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: {},\n\t\t\t);\n\n\t\t\tawait this.#driver.sendHttpMessage(\n\t\t\t\tundefined,\n\t\t\t\tthis.#actorId,\n\t\t\t\tthis.#encodingKind,\n\t\t\t\tthis.#connectionId,\n\t\t\t\tthis.#connectionToken,\n\t\t\t\tmessage,\n\t\t\t\topts?.signal ? { signal: opts.signal } : undefined,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// TODO: This will not automatically trigger a re-broadcast of HTTP events since SSE is separate from the HTTP action\n\n\t\t\tlogger().warn(\"failed to send message, added to queue\", {\n\t\t\t\terror,\n\t\t\t});\n\n\t\t\t// Assuming the socket is disconnected and will be reconnected soon\n\t\t\t//\n\t\t\t// Will attempt to resend soon\n\t\t\tif (!opts?.ephemeral) {\n\t\t\t\tthis.#messageQueue.unshift(message);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #parseMessage(data: ConnMessage): Promise<protocol.ToClient> {\n\t\tinvariant(this.#transport, \"transport must be defined\");\n\n\t\t// Decode base64 since SSE sends raw strings\n\t\tif (encodingIsBinary(this.#encodingKind) && \"sse\" in this.#transport) {\n\t\t\tif (typeof data === \"string\") {\n\t\t\t\tconst binaryString = atob(data);\n\t\t\t\tdata = new Uint8Array(\n\t\t\t\t\t[...binaryString].map((char) => char.charCodeAt(0)),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new errors.InternalError(\n\t\t\t\t\t`Expected data to be a string for SSE, got ${data}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst buffer = await inputDataToBuffer(data);\n\n\t\treturn deserializeWithEncoding(\n\t\t\tthis.#encodingKind,\n\t\t\tbuffer,\n\t\t\tTO_CLIENT_VERSIONED,\n\t\t);\n\t}\n\n\t/**\n\t * Disconnects from the actor.\n\t *\n\t * @returns {Promise<void>} A promise that resolves when the socket is gracefully closed.\n\t */\n\tasync dispose(): Promise<void> {\n\t\t// Internally, this \"disposes\" the connection\n\n\t\tif (this.#disposed) {\n\t\t\tlogger().warn(\"connection already disconnected\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#disposed = true;\n\n\t\tlogger().debug(\"disposing actor conn\");\n\n\t\t// Clear interval so NodeJS process can exit\n\t\tclearInterval(this.#keepNodeAliveInterval);\n\n\t\t// Abort\n\t\tthis.#abortController.abort();\n\n\t\t// Remove from registry\n\t\tthis.#client[ACTOR_CONNS_SYMBOL].delete(this);\n\n\t\t// Disconnect transport cleanly\n\t\tif (!this.#transport) {\n\t\t\t// Nothing to do\n\t\t} else if (\"websocket\" in this.#transport) {\n\t\t\tconst ws = this.#transport.websocket;\n\t\t\t// Check if WebSocket is already closed or closing\n\t\t\tif (\n\t\t\t\tws.readyState === 2 /* CLOSING */ ||\n\t\t\t\tws.readyState === 3 /* CLOSED */\n\t\t\t) {\n\t\t\t\tlogger().debug(\"ws already closed or closing\");\n\t\t\t} else {\n\t\t\t\tconst { promise, resolve } = Promise.withResolvers();\n\t\t\t\tws.addEventListener(\"close\", () => {\n\t\t\t\t\tlogger().debug(\"ws closed\");\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t});\n\t\t\t\tws.close();\n\t\t\t\tawait promise;\n\t\t\t}\n\t\t} else if (\"sse\" in this.#transport) {\n\t\t\tthis.#transport.sse.close();\n\t\t} else {\n\t\t\tassertUnreachable(this.#transport);\n\t\t}\n\t\tthis.#transport = undefined;\n\t}\n\n\t#sendSubscription(eventName: string, subscribe: boolean) {\n\t\tthis.#sendMessage(\n\t\t\t{\n\t\t\t\tbody: {\n\t\t\t\t\ttag: \"SubscriptionRequest\",\n\t\t\t\t\tval: {\n\t\t\t\t\t\teventName,\n\t\t\t\t\t\tsubscribe,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ephemeral: true },\n\t\t);\n\t}\n}\n\n/**\n * Connection to a actor. Allows calling actor's remote procedure calls with inferred types. See {@link ActorConnRaw} for underlying methods.\n *\n * @example\n * ```\n * const room = client.connect<ChatRoom>(...etc...);\n * // This calls the action named `sendMessage` on the `ChatRoom` actor.\n * await room.sendMessage('Hello, world!');\n * ```\n *\n * Private methods (e.g. those starting with `_`) are automatically excluded.\n *\n * @template AD The actor class that this connection is for.\n * @see {@link ActorConnRaw}\n */\nexport type ActorConn<AD extends AnyActorDefinition> = ActorConnRaw &\n\tActorDefinitionActions<AD>;\n","import invariant from \"invariant\";\nimport type { AnyActorDefinition } from \"@/actor/definition\";\nimport type { Encoding } from \"@/actor/protocol/serde\";\nimport { assertUnreachable } from \"@/actor/utils\";\nimport { importWebSocket } from \"@/common/websocket\";\nimport type { ActorQuery } from \"@/manager/protocol/query\";\nimport type { ActorDefinitionActions } from \"./actor-common\";\nimport { type ActorConn, ActorConnRaw } from \"./actor-conn\";\nimport {\n\ttype ClientDriver,\n\ttype ClientRaw,\n\tCREATE_ACTOR_CONN_PROXY,\n} from \"./client\";\nimport { logger } from \"./log\";\nimport { rawHttpFetch, rawWebSocket } from \"./raw-utils\";\n\n/**\n * Provides underlying functions for stateless {@link ActorHandle} for action calls.\n * Similar to ActorConnRaw but doesn't maintain a connection.\n *\n * @see {@link ActorHandle}\n */\nexport class ActorHandleRaw {\n\t#client: ClientRaw;\n\t#driver: ClientDriver;\n\t#encodingKind: Encoding;\n\t#actorQuery: ActorQuery;\n\t#params: unknown;\n\n\t/**\n\t * Do not call this directly.\n\t *\n\t * Creates an instance of ActorHandleRaw.\n\t *\n\t * @protected\n\t */\n\tpublic constructor(\n\t\tclient: any,\n\t\tdriver: ClientDriver,\n\t\tparams: unknown,\n\t\tencodingKind: Encoding,\n\t\tactorQuery: ActorQuery,\n\t) {\n\t\tthis.#client = client;\n\t\tthis.#driver = driver;\n\t\tthis.#encodingKind = encodingKind;\n\t\tthis.#actorQuery = actorQuery;\n\t\tthis.#params = params;\n\t}\n\n\t/**\n\t * Call a raw action. This method sends an HTTP request to invoke the named action.\n\t *\n\t * @see {@link ActorHandle}\n\t * @template Args - The type of arguments to pass to the action function.\n\t * @template Response - The type of the response returned by the action function.\n\t */\n\tasync action<\n\t\tArgs extends Array<unknown> = unknown[],\n\t\tResponse = unknown,\n\t>(opts: {\n\t\tname: string;\n\t\targs: Args;\n\t\tsignal?: AbortSignal;\n\t}): Promise<Response> {\n\t\treturn await this.#driver.action<Args, Response>(\n\t\t\tundefined,\n\t\t\tthis.#actorQuery,\n\t\t\tthis.#encodingKind,\n\t\t\tthis.#params,\n\t\t\topts.name,\n\t\t\topts.args,\n\t\t\t{ signal: opts.signal },\n\t\t);\n\t}\n\n\t/**\n\t * Establishes a persistent connection to the actor.\n\t *\n\t * @template AD The actor class that this connection is for.\n\t * @returns {ActorConn<AD>} A connection to the actor.\n\t */\n\tconnect(): ActorConn<AnyActorDefinition> {\n\t\tlogger().debug(\"establishing connection from handle\", {\n\t\t\tquery: this.#actorQuery,\n\t\t});\n\n\t\tconst conn = new ActorConnRaw(\n\t\t\tthis.#client,\n\t\t\tthis.#driver,\n\t\t\tthis.#params,\n\t\t\tthis.#encodingKind,\n\t\t\tthis.#actorQuery,\n\t\t);\n\n\t\treturn this.#client[CREATE_ACTOR_CONN_PROXY](\n\t\t\tconn,\n\t\t) as ActorConn<AnyActorDefinition>;\n\t}\n\n\t/**\n\t * Makes a raw HTTP request to the actor.\n\t *\n\t * @param input - The URL, path, or Request object\n\t * @param init - Standard fetch RequestInit options\n\t * @returns Promise<Response> - The raw HTTP response\n\t */\n\tasync fetch(\n\t\tinput: string | URL | Request,\n\t\tinit?: RequestInit,\n\t): Promise<Response> {\n\t\treturn rawHttpFetch(\n\t\t\tthis.#driver,\n\t\t\tthis.#actorQuery,\n\t\t\tthis.#params,\n\t\t\tinput,\n\t\t\tinit,\n\t\t);\n\t}\n\n\t/**\n\t * Creates a raw WebSocket connection to the actor.\n\t *\n\t * @param path - The path for the WebSocket connection (e.g., \"stream\")\n\t * @param protocols - Optional WebSocket subprotocols\n\t * @returns WebSocket - A raw WebSocket connection\n\t */\n\tasync websocket(\n\t\tpath?: string,\n\t\tprotocols?: string | string[],\n\t): Promise<WebSocket> {\n\t\treturn rawWebSocket(\n\t\t\tthis.#driver,\n\t\t\tthis.#actorQuery,\n\t\t\tthis.#params,\n\t\t\tpath,\n\t\t\tprotocols,\n\t\t);\n\t}\n\n\t/**\n\t * Resolves the actor to get its unique actor ID\n\t *\n\t * @returns {Promise<string>} - A promise that resolves to the actor's ID\n\t */\n\tasync resolve({ signal }: { signal?: AbortSignal } = {}): Promise<string> {\n\t\tif (\n\t\t\t\"getForKey\" in this.#actorQuery ||\n\t\t\t\"getOrCreateForKey\" in this.#actorQuery\n\t\t) {\n\t\t\t// TODO:\n\t\t\tlet name: string;\n\t\t\tif (\"getForKey\" in this.#actorQuery) {\n\t\t\t\tname = this.#actorQuery.getForKey.name;\n\t\t\t} else if (\"getOrCreateForKey\" in this.#actorQuery) {\n\t\t\t\tname = this.#actorQuery.getOrCreateForKey.name;\n\t\t\t} else {\n\t\t\t\tassertUnreachable(this.#actorQuery);\n\t\t\t}\n\n\t\t\tconst actorId = await this.#driver.resolveActorId(\n\t\t\t\tundefined,\n\t\t\t\tthis.#actorQuery,\n\t\t\t\tthis.#encodingKind,\n\t\t\t\tthis.#params,\n\t\t\t\tsignal ? { signal } : undefined,\n\t\t\t);\n\n\t\t\tthis.#actorQuery = { getForId: { actorId, name } };\n\n\t\t\treturn actorId;\n\t\t} else if (\"getForId\" in this.#actorQuery) {\n\t\t\t// SKip since it's already resolved\n\t\t\treturn this.#actorQuery.getForId.actorId;\n\t\t} else if (\"create\" in this.#actorQuery) {\n\t\t\t// Cannot create a handle with this query\n\t\t\tinvariant(false, \"actorQuery cannot be create\");\n\t\t} else {\n\t\t\tassertUnreachable(this.#actorQuery);\n\t\t}\n\t}\n}\n\n/**\n * Stateless handle to a actor. Allows calling actor's remote procedure calls with inferred types\n * without establishing a persistent connection.\n *\n * @example\n * ```\n * const room = client.get<ChatRoom>(...etc...);\n * // This calls the action named `sendMessage` on the `ChatRoom` actor without a connection.\n * await room.sendMessage('Hello, world!');\n * ```\n *\n * Private methods (e.g. those starting with `_`) are automatically excluded.\n *\n * @template AD The actor class that this handle is for.\n * @see {@link ActorHandleRaw}\n */\nexport type ActorHandle<AD extends AnyActorDefinition> = Omit<\n\tActorHandleRaw,\n\t\"connect\"\n> & {\n\t// Add typed version of ActorConn (instead of using AnyActorDefinition)\n\tconnect(): ActorConn<AD>;\n\t// Resolve method returns the actor ID\n\tresolve(): Promise<string>;\n} & ActorDefinitionActions<AD>;\n","import type { ActorQuery } from \"@/manager/protocol/query\";\nimport type { ClientDriver } from \"./client\";\n\n/**\n * Shared implementation for raw HTTP fetch requests\n */\nexport async function rawHttpFetch(\n\tdriver: ClientDriver,\n\tactorQuery: ActorQuery,\n\tparams: unknown,\n\tinput: string | URL | Request,\n\tinit?: RequestInit,\n): Promise<Response> {\n\t// Extract path and merge init options\n\tlet path: string;\n\tlet mergedInit: RequestInit = init || {};\n\n\tif (typeof input === \"string\") {\n\t\tpath = input;\n\t} else if (input instanceof URL) {\n\t\tpath = input.pathname + input.search;\n\t} else if (input instanceof Request) {\n\t\t// Extract path from Request URL\n\t\tconst url = new URL(input.url);\n\t\tpath = url.pathname + url.search;\n\t\t// Merge Request properties with init\n\t\tconst requestHeaders = new Headers(input.headers);\n\t\tconst initHeaders = new Headers(init?.headers || {});\n\n\t\t// Merge headers - init headers override request headers\n\t\tconst mergedHeaders = new Headers(requestHeaders);\n\t\tfor (const [key, value] of initHeaders) {\n\t\t\tmergedHeaders.set(key, value);\n\t\t}\n\n\t\tmergedInit = {\n\t\t\tmethod: input.method,\n\t\t\tbody: input.body,\n\t\t\tmode: input.mode,\n\t\t\tcredentials: input.credentials,\n\t\t\tredirect: input.redirect,\n\t\t\treferrer: input.referrer,\n\t\t\treferrerPolicy: input.referrerPolicy,\n\t\t\tintegrity: input.integrity,\n\t\t\tkeepalive: input.keepalive,\n\t\t\tsignal: input.signal,\n\t\t\t...mergedInit, // init overrides Request properties\n\t\t\theaders: mergedHeaders, // headers must be set after spread to ensure proper merge\n\t\t};\n\t\t// Add duplex if body is present\n\t\tif (mergedInit.body) {\n\t\t\t(mergedInit as any).duplex = \"half\";\n\t\t}\n\t} else {\n\t\tthrow new TypeError(\"Invalid input type for fetch\");\n\t}\n\n\t// Use the driver's raw HTTP method - just pass the sub-path\n\treturn await driver.rawHttpRequest(\n\t\tundefined,\n\t\tactorQuery,\n\t\t// Force JSON so it's readable by the user\n\t\t\"json\",\n\t\tparams,\n\t\tpath,\n\t\tmergedInit,\n\t\tundefined,\n\t);\n}\n\n/**\n * Shared implementation for raw WebSocket connections\n */\nexport async function rawWebSocket(\n\tdriver: ClientDriver,\n\tactorQuery: ActorQuery,\n\tparams: unknown,\n\tpath?: string,\n\tprotocols?: string | string[],\n): Promise<any> {\n\t// Use the driver's raw WebSocket method\n\treturn await driver.rawWebSocket(\n\t\tundefined,\n\t\tactorQuery,\n\t\t// Force JSON so it's readable by the user\n\t\t\"json\",\n\t\tparams,\n\t\tpath || \"\",\n\t\tprotocols,\n\t\tundefined,\n\t);\n}\n","import type { Context as HonoContext } from \"hono\";\nimport type { WebSocket } from \"ws\";\nimport type { AnyActorDefinition } from \"@/actor/definition\";\nimport type { Transport } from \"@/actor/protocol/old\";\nimport type { Encoding } from \"@/actor/protocol/serde\";\nimport type { UniversalEventSource } from \"@/common/eventsource-interface\";\nimport type { ActorQuery } from \"@/manager/protocol/query\";\nimport type { Registry } from \"@/mod\";\nimport type { ToServer } from \"@/schemas/client-protocol/mod\";\nimport type { ActorActionFunction } from \"./actor-common\";\nimport {\n\ttype ActorConn,\n\ttype ActorConnRaw,\n\tCONNECT_SYMBOL,\n} from \"./actor-conn\";\nimport { type ActorHandle, ActorHandleRaw } from \"./actor-handle\";\nimport { logger } from \"./log\";\n\n/** Extract the actor registry from the registry definition. */\nexport type ExtractActorsFromRegistry<A extends Registry<any>> =\n\tA extends Registry<infer Actors> ? Actors : never;\n\n/** Extract the registry definition from the client. */\nexport type ExtractRegistryFromClient<C extends Client<Registry<{}>>> =\n\tC extends Client<infer A> ? A : never;\n\n/**\n * Represents a actor accessor that provides methods to interact with a specific actor.\n */\nexport interface ActorAccessor<AD extends AnyActorDefinition> {\n\t/**\n\t * Gets a stateless handle to a actor by its key, but does not create the actor if it doesn't exist.\n\t * The actor name is automatically injected from the property accessor.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {GetWithIdOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tget(key?: string | string[], opts?: GetWithIdOptions): ActorHandle<AD>;\n\n\t/**\n\t * Gets a stateless handle to a actor by its key, creating it if necessary.\n\t * The actor name is automatically injected from the property accessor.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {GetOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tgetOrCreate(\n\t\tkey?: string | string[],\n\t\topts?: GetOrCreateOptions,\n\t): ActorHandle<AD>;\n\n\t/**\n\t * Gets a stateless handle to a actor by its ID.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string} actorId - The ID of the actor.\n\t * @param {GetWithIdOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tgetForId(actorId: string, opts?: GetWithIdOptions): ActorHandle<AD>;\n\n\t/**\n\t * Creates a new actor with the name automatically injected from the property accessor,\n\t * and returns a stateless handle to it with the actor ID resolved.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string | string[]} key - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {CreateOptions} [opts] - Options for creating the actor (excluding name and key).\n\t * @returns {Promise<ActorHandle<AD>>} - A promise that resolves to a handle to the actor.\n\t */\n\tcreate(\n\t\tkey?: string | string[],\n\t\topts?: CreateOptions,\n\t): Promise<ActorHandle<AD>>;\n}\n\n/**\n * Options for configuring the client.\n * @typedef {Object} ClientOptions\n */\nexport interface ClientOptions {\n\tencoding?: Encoding;\n\ttransport?: Transport;\n}\n\n/**\n * Options for querying actors.\n * @typedef {Object} QueryOptions\n * @property {unknown} [parameters] - Parameters to pass to the connection.\n */\nexport interface QueryOptions {\n\t/** Parameters to pass to the connection. */\n\tparams?: unknown;\n\t/** Signal to abort the request. */\n\tsignal?: AbortSignal;\n}\n\n/**\n * Options for getting a actor by ID.\n * @typedef {QueryOptions} GetWithIdOptions\n */\nexport interface GetWithIdOptions extends QueryOptions {}\n\n/**\n * Options for getting a actor.\n * @typedef {QueryOptions} GetOptions\n */\nexport interface GetOptions extends QueryOptions {}\n\n/**\n * Options for getting or creating a actor.\n * @typedef {QueryOptions} GetOrCreateOptions\n * @property {string} [createInRegion] - Region to create the actor in if it doesn't exist.\n */\nexport interface GetOrCreateOptions extends QueryOptions {\n\t/** Region to create the actor in if it doesn't exist. */\n\tcreateInRegion?: string;\n\t/** Input data to pass to the actor. */\n\tcreateWithInput?: unknown;\n}\n\n/**\n * Options for creating a actor.\n * @typedef {QueryOptions} CreateOptions\n * @property {string} [region] - The region to create the actor in.\n */\nexport interface CreateOptions extends QueryOptions {\n\t/** The region to create the actor in. */\n\tregion?: string;\n\t/** Input data to pass to the actor. */\n\tinput?: unknown;\n}\n\n/**\n * Represents a region to connect to.\n * @typedef {Object} Region\n * @property {string} id - The region ID.\n * @property {string} name - The region name.\n * @see {@link https://rivet.gg/docs/edge|Edge Networking}\n * @see {@link https://rivet.gg/docs/regions|Available Regions}\n */\nexport interface Region {\n\t/**\n\t * The region slug.\n\t */\n\tid: string;\n\n\t/**\n\t * The human-friendly region name.\n\t */\n\tname: string;\n}\n\nexport const ACTOR_CONNS_SYMBOL = Symbol(\"actorConns\");\nexport const CREATE_ACTOR_CONN_PROXY = Symbol(\"createActorConnProxy\");\nexport const TRANSPORT_SYMBOL = Symbol(\"transport\");\n\nexport interface ClientDriver {\n\taction<Args extends Array<unknown> = unknown[], Response = unknown>(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t\tname: string,\n\t\targs: Args,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<Response>;\n\tresolveActorId(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencodingKind: Encoding,\n\t\tparams: unknown,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<string>;\n\tconnectWebSocket(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencodingKind: Encoding,\n\t\tparams: unknown,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<WebSocket>;\n\tconnectSse(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencodingKind: Encoding,\n\t\tparams: unknown,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<UniversalEventSource>;\n\tsendHttpMessage(\n\t\tc: HonoContext | undefined,\n\t\tactorId: string,\n\t\tencoding: Encoding,\n\t\tconnectionId: string,\n\t\tconnectionToken: string,\n\t\tmessage: ToServer,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<void>;\n\trawHttpRequest(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t\tpath: string,\n\t\tinit: RequestInit,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<Response>;\n\trawWebSocket(\n\t\tc: HonoContext | undefined,\n\t\tactorQuery: ActorQuery,\n\t\tencoding: Encoding,\n\t\tparams: unknown,\n\t\tpath: string,\n\t\tprotocols: string | string[] | undefined,\n\t\topts: { signal?: AbortSignal } | undefined,\n\t): Promise<WebSocket>;\n}\n\n/**\n * Client for managing & connecting to actors.\n *\n * @template A The actors map type that defines the available actors.\n * @see {@link https://rivet.gg/docs/manage|Create & Manage Actors}\n */\nexport class ClientRaw {\n\t#disposed = false;\n\n\t[ACTOR_CONNS_SYMBOL] = new Set<ActorConnRaw>();\n\n\t#driver: ClientDriver;\n\t#encodingKind: Encoding;\n\t[TRANSPORT_SYMBOL]: Transport;\n\n\t/**\n\t * Creates an instance of Client.\n\t *\n\t * @param {string} managerEndpoint - The manager endpoint. See {@link https://rivet.gg/docs/setup|Initial Setup} for instructions on getting the manager endpoint.\n\t * @param {ClientOptions} [opts] - Options for configuring the client.\n\t * @see {@link https://rivet.gg/docs/setup|Initial Setup}\n\t */\n\tpublic constructor(driver: ClientDriver, opts?: ClientOptions) {\n\t\tthis.#driver = driver;\n\n\t\tthis.#encodingKind = opts?.encoding ?? \"bare\";\n\t\tthis[TRANSPORT_SYMBOL] = opts?.transport ?? \"websocket\";\n\t}\n\n\t/**\n\t * Gets a stateless handle to a actor by its ID.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string} name - The name of the actor.\n\t * @param {string} actorId - The ID of the actor.\n\t * @param {GetWithIdOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tgetForId<AD extends AnyActorDefinition>(\n\t\tname: string,\n\t\tactorId: string,\n\t\topts?: GetWithIdOptions,\n\t): ActorHandle<AD> {\n\t\tlogger().debug(\"get handle to actor with id\", {\n\t\t\tname,\n\t\t\tactorId,\n\t\t\tparams: opts?.params,\n\t\t});\n\n\t\tconst actorQuery: ActorQuery = {\n\t\t\tgetForId: {\n\t\t\t\tname,\n\t\t\t\tactorId,\n\t\t\t},\n\t\t};\n\n\t\tconst handle = this.#createHandle(opts?.params, actorQuery);\n\t\treturn createActorProxy(handle) as ActorHandle<AD>;\n\t}\n\n\t/**\n\t * Gets a stateless handle to a actor by its key, but does not create the actor if it doesn't exist.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string} name - The name of the actor.\n\t * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {GetWithIdOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tget<AD extends AnyActorDefinition>(\n\t\tname: string,\n\t\tkey?: string | string[],\n\t\topts?: GetWithIdOptions,\n\t): ActorHandle<AD> {\n\t\t// Convert string to array of strings\n\t\tconst keyArray: string[] = typeof key === \"string\" ? [key] : key || [];\n\n\t\tlogger().debug(\"get handle to actor\", {\n\t\t\tname,\n\t\t\tkey: keyArray,\n\t\t\tparameters: opts?.params,\n\t\t});\n\n\t\tconst actorQuery: ActorQuery = {\n\t\t\tgetForKey: {\n\t\t\t\tname,\n\t\t\t\tkey: keyArray,\n\t\t\t},\n\t\t};\n\n\t\tconst handle = this.#createHandle(opts?.params, actorQuery);\n\t\treturn createActorProxy(handle) as ActorHandle<AD>;\n\t}\n\n\t/**\n\t * Gets a stateless handle to a actor by its key, creating it if necessary.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string} name - The name of the actor.\n\t * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {GetOptions} [opts] - Options for getting the actor.\n\t * @returns {ActorHandle<AD>} - A handle to the actor.\n\t */\n\tgetOrCreate<AD extends AnyActorDefinition>(\n\t\tname: string,\n\t\tkey?: string | string[],\n\t\topts?: GetOrCreateOptions,\n\t): ActorHandle<AD> {\n\t\t// Convert string to array of strings\n\t\tconst keyArray: string[] = typeof key === \"string\" ? [key] : key || [];\n\n\t\tlogger().debug(\"get or create handle to actor\", {\n\t\t\tname,\n\t\t\tkey: keyArray,\n\t\t\tparameters: opts?.params,\n\t\t\tcreateInRegion: opts?.createInRegion,\n\t\t});\n\n\t\tconst actorQuery: ActorQuery = {\n\t\t\tgetOrCreateForKey: {\n\t\t\t\tname,\n\t\t\t\tkey: keyArray,\n\t\t\t\tinput: opts?.createWithInput,\n\t\t\t\tregion: opts?.createInRegion,\n\t\t\t},\n\t\t};\n\n\t\tconst handle = this.#createHandle(opts?.params, actorQuery);\n\t\treturn createActorProxy(handle) as ActorHandle<AD>;\n\t}\n\n\t/**\n\t * Creates a new actor with the provided key and returns a stateless handle to it.\n\t * Resolves the actor ID and returns a handle with getForId query.\n\t *\n\t * @template AD The actor class that this handle is for.\n\t * @param {string} name - The name of the actor.\n\t * @param {string | string[]} key - The key to identify the actor. Can be a single string or an array of strings.\n\t * @param {CreateOptions} [opts] - Options for creating the actor (excluding name and key).\n\t * @returns {Promise<ActorHandle<AD>>} - A promise that resolves to a handle to the actor.\n\t */\n\tasync create<AD extends AnyActorDefinition>(\n\t\tname: string,\n\t\tkey?: string | string[],\n\t\topts?: CreateOptions,\n\t): Promise<ActorHandle<AD>> {\n\t\t// Convert string to array of strings\n\t\tconst keyArray: string[] = typeof key === \"string\" ? [key] : key || [];\n\n\t\tconst createQuery = {\n\t\t\tcreate: {\n\t\t\t\t...opts,\n\t\t\t\t// Do these last to override `opts`\n\t\t\t\tname,\n\t\t\t\tkey: keyArray,\n\t\t\t},\n\t\t} satisfies ActorQuery;\n\n\t\tlogger().debug(\"create actor handle\", {\n\t\t\tname,\n\t\t\tkey: keyArray,\n\t\t\tparameters: opts?.params,\n\t\t\tcreate: createQuery.create,\n\t\t});\n\n\t\t// Create the actor\n\t\tconst actorId = await this.#driver.resolveActorId(\n\t\t\tundefined,\n\t\t\tcreateQuery,\n\t\t\tthis.#encodingKind,\n\t\t\topts?.params,\n\t\t\topts?.signal ? { signal: opts.signal } : undefined,\n\t\t);\n\t\tlogger().debug(\"created actor with ID\", {\n\t\t\tname,\n\t\t\tkey: keyArray,\n\t\t\tactorId,\n\t\t});\n\n\t\t// Create handle with actor ID\n\t\tconst getForIdQuery = {\n\t\t\tgetForId: {\n\t\t\t\tname,\n\t\t\t\tactorId,\n\t\t\t},\n\t\t} satisfies ActorQuery;\n\t\tconst handle = this.#createHandle(opts?.params, getForIdQuery);\n\n\t\tconst proxy = createActorProxy(handle) as ActorHandle<AD>;\n\n\t\treturn proxy;\n\t}\n\n\t#createHandle(params: unknown, actorQuery: ActorQuery): ActorHandleRaw {\n\t\treturn new ActorHandleRaw(\n\t\t\tthis,\n\t\t\tthis.#driver,\n\t\t\tparams,\n\t\t\tthis.#encodingKind,\n\t\t\tactorQuery,\n\t\t);\n\t}\n\n\t[CREATE_ACTOR_CONN_PROXY]<AD extends AnyActorDefinition>(\n\t\tconn: ActorConnRaw,\n\t): ActorConn<AD> {\n\t\t// Save to connection list\n\t\tthis[ACTOR_CONNS_SYMBOL].add(conn);\n\n\t\t// Start connection\n\t\tconn[CONNECT_SYMBOL]();\n\n\t\treturn createActorProxy(conn) as ActorConn<AD>;\n\t}\n\n\t/**\n\t * Disconnects from all actors.\n\t *\n\t * @returns {Promise<void>} A promise that resolves when all connections are closed.\n\t */\n\tasync dispose(): Promise<void> {\n\t\tif (this.#disposed) {\n\t\t\tlogger().warn(\"client already disconnected\");\n\t\t\treturn;\n\t\t}\n\t\tthis.#disposed = true;\n\n\t\tlogger().debug(\"disposing client\");\n\n\t\tconst disposePromises = [];\n\n\t\t// Dispose all connections\n\t\tfor (const conn of this[ACTOR_CONNS_SYMBOL].values()) {\n\t\t\tdisposePromises.push(conn.dispose());\n\t\t}\n\n\t\tawait Promise.all(disposePromises);\n\t}\n}\n\n/**\n * Client type with actor accessors.\n * This adds property accessors for actor names to the ClientRaw base class.\n *\n * @template A The actor registry type.\n */\nexport type Client<A extends Registry<any>> = ClientRaw & {\n\t[K in keyof ExtractActorsFromRegistry<A>]: ActorAccessor<\n\t\tExtractActorsFromRegistry<A>[K]\n\t>;\n};\n\nexport type AnyClient = Client<Registry<any>>;\n\nexport function createClientWithDriver<A extends Registry<any>>(\n\tdriver: ClientDriver,\n\topts?: ClientOptions,\n): Client<A> {\n\tconst client = new ClientRaw(driver, opts);\n\n\t// Create proxy for accessing actors by name\n\treturn new Proxy(client, {\n\t\tget: (target: ClientRaw, prop: string | symbol, receiver: unknown) => {\n\t\t\t// Get the real property if it exists\n\t\t\tif (typeof prop === \"symbol\" || prop in target) {\n\t\t\t\tconst value = Reflect.get(target, prop, receiver);\n\t\t\t\t// Preserve method binding\n\t\t\t\tif (typeof value === \"function\") {\n\t\t\t\t\treturn value.bind(target);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\t// Handle actor accessor for string properties (actor names)\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\t// Return actor accessor object with methods\n\t\t\t\treturn {\n\t\t\t\t\t// Handle methods (stateless action)\n\t\t\t\t\tget: (\n\t\t\t\t\t\tkey?: string | string[],\n\t\t\t\t\t\topts?: GetWithIdOptions,\n\t\t\t\t\t): ActorHandle<ExtractActorsFromRegistry<A>[typeof prop]> => {\n\t\t\t\t\t\treturn target.get<ExtractActorsFromRegistry<A>[typeof prop]>(\n\t\t\t\t\t\t\tprop,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tgetOrCreate: (\n\t\t\t\t\t\tkey?: string | string[],\n\t\t\t\t\t\topts?: GetOptions,\n\t\t\t\t\t): ActorHandle<ExtractActorsFromRegistry<A>[typeof prop]> => {\n\t\t\t\t\t\treturn target.getOrCreate<\n\t\t\t\t\t\t\tExtractActorsFromRegistry<A>[typeof prop]\n\t\t\t\t\t\t>(prop, key, opts);\n\t\t\t\t\t},\n\t\t\t\t\tgetForId: (\n\t\t\t\t\t\tactorId: string,\n\t\t\t\t\t\topts?: GetWithIdOptions,\n\t\t\t\t\t): ActorHandle<ExtractActorsFromRegistry<A>[typeof prop]> => {\n\t\t\t\t\t\treturn target.getForId<ExtractActorsFromRegistry<A>[typeof prop]>(\n\t\t\t\t\t\t\tprop,\n\t\t\t\t\t\t\tactorId,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tcreate: async (\n\t\t\t\t\t\tkey: string | string[],\n\t\t\t\t\t\topts: CreateOptions = {},\n\t\t\t\t\t): Promise<\n\t\t\t\t\t\tActorHandle<ExtractActorsFromRegistry<A>[typeof prop]>\n\t\t\t\t\t> => {\n\t\t\t\t\t\treturn await target.create<\n\t\t\t\t\t\t\tExtractActorsFromRegistry<A>[typeof prop]\n\t\t\t\t\t\t>(prop, key, opts);\n\t\t\t\t\t},\n\t\t\t\t} as ActorAccessor<ExtractActorsFromRegistry<A>[typeof prop]>;\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t},\n\t}) as Client<A>;\n}\n\n/**\n * Creates a proxy for a actor that enables calling actions without explicitly using `.action`.\n **/\nfunction createActorProxy<AD extends AnyActorDefinition>(\n\thandle: ActorHandleRaw | ActorConnRaw,\n): ActorHandle<AD> | ActorConn<AD> {\n\t// Stores returned action functions for faster calls\n\tconst methodCache = new Map<string, ActorActionFunction>();\n\treturn new Proxy(handle, {\n\t\tget(target: ActorHandleRaw, prop: string | symbol, receiver: unknown) {\n\t\t\t// Handle built-in Symbol properties\n\t\t\tif (typeof prop === \"symbol\") {\n\t\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t\t}\n\n\t\t\t// Handle built-in Promise methods and existing properties\n\t\t\tif (prop === \"constructor\" || prop in target) {\n\t\t\t\tconst value = Reflect.get(target, prop, receiver);\n\t\t\t\t// Preserve method binding\n\t\t\t\tif (typeof value === \"function\") {\n\t\t\t\t\treturn value.bind(target);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\t// Create action function that preserves 'this' context\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\t// If JS is attempting to calling this as a promise, ignore it\n\t\t\t\tif (prop === \"then\") return undefined;\n\n\t\t\t\tlet method = methodCache.get(prop);\n\t\t\t\tif (!method) {\n\t\t\t\t\tmethod = (...args: unknown[]) => target.action({ name: prop, args });\n\t\t\t\t\tmethodCache.set(prop, method);\n\t\t\t\t}\n\t\t\t\treturn method;\n\t\t\t}\n\t\t},\n\n\t\t// Support for 'in' operator\n\t\thas(target: ActorHandleRaw, prop: string | symbol) {\n\t\t\t// All string properties are potentially action functions\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// For symbols, defer to the target's own has behavior\n\t\t\treturn Reflect.has(target, prop);\n\t\t},\n\n\t\t// Support instanceof checks\n\t\tgetPrototypeOf(target: ActorHandleRaw) {\n\t\t\treturn Reflect.getPrototypeOf(target);\n\t\t},\n\n\t\t// Prevent property enumeration of non-existent action methods\n\t\townKeys(target: ActorHandleRaw) {\n\t\t\treturn Reflect.ownKeys(target);\n\t\t},\n\n\t\t// Support proper property descriptors\n\t\tgetOwnPropertyDescriptor(target: ActorHandleRaw, prop: string | symbol) {\n\t\t\tconst targetDescriptor = Reflect.getOwnPropertyDescriptor(target, prop);\n\t\t\tif (targetDescriptor) {\n\t\t\t\treturn targetDescriptor;\n\t\t\t}\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\t// Make action methods appear non-enumerable\n\t\t\t\treturn {\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\twritable: false,\n\t\t\t\t\tvalue: (...args: unknown[]) => target.action({ name: prop, args }),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t}) as ActorHandle<AD> | ActorConn<AD>;\n}\n","import * as cbor from \"cbor-x\";\nimport invariant from \"invariant\";\nimport { assertUnreachable } from \"@/common/utils\";\nimport type { VersionedDataHandler } from \"@/common/versioned-data\";\nimport type { Encoding } from \"@/mod\";\nimport type { HttpResponseError } from \"@/schemas/client-protocol/mod\";\nimport { HTTP_RESPONSE_ERROR_VERSIONED } from \"@/schemas/client-protocol/versioned\";\nimport {\n\tcontentTypeForEncoding,\n\tdeserializeWithEncoding,\n\tserializeWithEncoding,\n} from \"@/serde\";\nimport { httpUserAgent } from \"@/utils\";\nimport { ActorError, HttpRequestError } from \"./errors\";\nimport { logger } from \"./log\";\n\nexport type WebSocketMessage = string | Blob | ArrayBuffer | Uint8Array;\n\nexport function messageLength(message: WebSocketMessage): number {\n\tif (message instanceof Blob) {\n\t\treturn message.size;\n\t}\n\tif (message instanceof ArrayBuffer) {\n\t\treturn message.byteLength;\n\t}\n\tif (message instanceof Uint8Array) {\n\t\treturn message.byteLength;\n\t}\n\tif (typeof message === \"string\") {\n\t\treturn message.length;\n\t}\n\tassertUnreachable(message);\n}\n\nexport interface HttpRequestOpts<RequestBody, ResponseBody> {\n\tmethod: string;\n\turl: string;\n\theaders: Record<string, string>;\n\tbody?: RequestBody;\n\tencoding: Encoding;\n\tskipParseResponse?: boolean;\n\tsignal?: AbortSignal;\n\tcustomFetch?: (req: Request) => Promise<Response>;\n\trequestVersionedDataHandler: VersionedDataHandler<RequestBody>;\n\tresponseVersionedDataHandler: VersionedDataHandler<ResponseBody>;\n}\n\nexport async function sendHttpRequest<\n\tRequestBody = unknown,\n\tResponseBody = unknown,\n>(opts: HttpRequestOpts<RequestBody, ResponseBody>): Promise<ResponseBody> {\n\tlogger().debug(\"sending http request\", {\n\t\turl: opts.url,\n\t\tencoding: opts.encoding,\n\t});\n\n\t// Serialize body\n\tlet contentType: string | undefined;\n\tlet bodyData: string | Uint8Array | undefined;\n\tif (opts.method === \"POST\" || opts.method === \"PUT\") {\n\t\tinvariant(opts.body !== undefined, \"missing body\");\n\t\tcontentType = contentTypeForEncoding(opts.encoding);\n\t\tbodyData = serializeWithEncoding<RequestBody>(\n\t\t\topts.encoding,\n\t\t\topts.body,\n\t\t\topts.requestVersionedDataHandler,\n\t\t);\n\t}\n\n\t// Send request\n\tlet response: Response;\n\ttry {\n\t\t// Make the HTTP request\n\t\tresponse = await (opts.customFetch ?? fetch)(\n\t\t\tnew Request(opts.url, {\n\t\t\t\tmethod: opts.method,\n\t\t\t\theaders: {\n\t\t\t\t\t...opts.headers,\n\t\t\t\t\t...(contentType\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\"Content-Type\": contentType,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t\"User-Agent\": httpUserAgent(),\n\t\t\t\t},\n\t\t\t\tbody: bodyData,\n\t\t\t\tcredentials: \"include\",\n\t\t\t\tsignal: opts.signal,\n\t\t\t}),\n\t\t);\n\t} catch (error) {\n\t\tthrow new HttpRequestError(`Request failed: ${error}`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\t// Parse response error\n\tif (!response.ok) {\n\t\t// Attempt to parse structured data\n\t\tconst bufferResponse = await response.arrayBuffer();\n\t\tlet responseData: HttpResponseError;\n\t\ttry {\n\t\t\tresponseData = deserializeWithEncoding(\n\t\t\t\topts.encoding,\n\t\t\t\tnew Uint8Array(bufferResponse),\n\t\t\t\tHTTP_RESPONSE_ERROR_VERSIONED,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t//logger().warn(\"failed to cleanly parse error, this is likely because a non-structured response is being served\", {\n\t\t\t//\terror: stringifyError(error),\n\t\t\t//});\n\n\t\t\t// Error is not structured\n\t\t\tconst textResponse = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n\t\t\t\tbufferResponse,\n\t\t\t);\n\t\t\tthrow new HttpRequestError(\n\t\t\t\t`${response.statusText} (${response.status}):\\n${textResponse}`,\n\t\t\t);\n\t\t}\n\n\t\t// Throw structured error\n\t\tthrow new ActorError(\n\t\t\tresponseData.code,\n\t\t\tresponseData.message,\n\t\t\tresponseData.metadata\n\t\t\t\t? cbor.decode(new Uint8Array(responseData.metadata))\n\t\t\t\t: undefined,\n\t\t);\n\t}\n\n\t// Some requests don't need the success response to be parsed, so this can speed things up\n\tif (opts.skipParseResponse) {\n\t\treturn undefined as ResponseBody;\n\t}\n\n\t// Parse the response based on encoding\n\ttry {\n\t\tconst buffer = new Uint8Array(await response.arrayBuffer());\n\t\treturn deserializeWithEncoding(\n\t\t\topts.encoding,\n\t\t\tbuffer,\n\t\t\topts.responseVersionedDataHandler,\n\t\t);\n\t} catch (error) {\n\t\tthrow new HttpRequestError(`Failed to parse response: ${error}`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n}\n","import type { EventSource } from \"eventsource\";\nimport { logger } from \"@/client/log\";\n\n// Global singleton promise that will be reused for subsequent calls\nlet eventSourcePromise: Promise<typeof EventSource> | null = null;\n\n/**\n * Import `eventsource` from the custom `eventsource` library. We need a custom implemnetation since we need to attach our own custom headers to the request.\n **/\nexport async function importEventSource(): Promise<typeof EventSource> {\n\t// Return existing promise if we already started loading\n\tif (eventSourcePromise !== null) {\n\t\treturn eventSourcePromise;\n\t}\n\n\t// Create and store the promise\n\teventSourcePromise = (async () => {\n\t\tlet _EventSource: typeof EventSource;\n\n\t\t// Node.js environment\n\t\ttry {\n\t\t\tconst es = await import(\"eventsource\");\n\t\t\t_EventSource = es.EventSource;\n\t\t\tlogger().debug(\"using eventsource from npm\");\n\t\t} catch (err) {\n\t\t\t// EventSource not available\n\t\t\t_EventSource = class MockEventSource {\n\t\t\t\tconstructor() {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'EventSource support requires installing the \"eventsource\" peer dependency.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} as unknown as typeof EventSource;\n\t\t\tlogger().debug(\"using mock eventsource\");\n\t\t}\n\n\t\treturn _EventSource;\n\t})();\n\n\treturn eventSourcePromise;\n}\n\n//export async function importEventSource(): Promise<typeof EventSource> {\n//\t// Return existing promise if we already started loading\n//\tif (eventSourcePromise !== null) {\n//\t\treturn eventSourcePromise;\n//\t}\n//\n//\t// Create and store the promise\n//\teventSourcePromise = (async () => {\n//\t\tlet _EventSource: typeof EventSource;\n//\n//\t\tif (typeof EventSource !== \"undefined\") {\n//\t\t\t// Browser environment\n//\t\t\t_EventSource = EventSource;\n//\t\t\tlogger().debug(\"using native eventsource\");\n//\t\t} else {\n//\t\t\t// Node.js environment\n//\t\t\ttry {\n//\t\t\t\tconst es = await import(\"eventsource\");\n//\t\t\t\t_EventSource = es.EventSource;\n//\t\t\t\tlogger().debug(\"using eventsource from npm\");\n//\t\t\t} catch (err) {\n//\t\t\t\t// EventSource not available\n//\t\t\t\t_EventSource = class MockEventSource {\n//\t\t\t\t\tconstructor() {\n//\t\t\t\t\t\tthrow new Error(\n//\t\t\t\t\t\t\t'EventSource support requires installing the \"eventsource\" peer dependency.',\n//\t\t\t\t\t\t);\n//\t\t\t\t\t}\n//\t\t\t\t} as unknown as typeof EventSource;\n//\t\t\t\tlogger().debug(\"using mock eventsource\");\n//\t\t\t}\n//\t\t}\n//\n//\t\treturn _EventSource;\n//\t})();\n//\n//\treturn eventSourcePromise;\n//}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-OGAPU3UG.cjs","../../src/common/utils.ts","../../package.json","../../src/utils.ts"],"names":[],"mappings":"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E,QAAA;AACb,MAAA;AACF,IAAA;AACS,IAAA;AACG,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACY,IAAA;AACA,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACW,IAAA;AACC,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACoB,IAAA;AACR,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AAC8B,IAAA;AAClB,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACuB,IAAA;AACX,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AAC2B,IAAA;AACf,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AAC0B,IAAA;AACd,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACU,IAAA;AACE,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACe,IAAA;AACH,MAAA;AACC,QAAA;AACE,QAAA;AACb,MAAA;AACW,MAAA;AACA,QAAA;AACE,QAAA;AACb,MAAA;AACF,IAAA;AACF,EAAA;AACW,EAAA;AACD,IAAA;AACV,EAAA;AACe,EAAA;AACJ,EAAA;AACF,IAAA;AACE,IAAA;AACO,IAAA;AACD,IAAA;AACP,IAAA;AACM,IAAA;AACE,IAAA;AAClB,EAAA;AACgB,EAAA;AACE,IAAA;AACY,IAAA;AACP,IAAA;AACM,IAAA;AACE,IAAA;AACnB,IAAA;AACF,IAAA;AACK,IAAA;AACC,IAAA;AACD,IAAA;AACF,IAAA;AACJ,IAAA;AACT,EAAA;AACmB,EAAA;AACC,IAAA;AACG,IAAA;AACJ,IAAA;AACO,IAAA;AACJ,IAAA;AACL,IAAA;AACF,IAAA;AACC,IAAA;AACI,IAAA;AACH,IAAA;AACP,IAAA;AACD,IAAA;AACO,IAAA;AACJ,IAAA;AACJ,IAAA;AACR,EAAA;AACoB,EAAA;AACG,IAAA;AACJ,IAAA;AACF,IAAA;AACT,IAAA;AACR,EAAA;AACwB,EAAA;AACD,IAAA;AACP,MAAA;AACd,IAAA;AACiB,IAAA;AACH,MAAA;AACd,IAAA;AACe,IAAA;AACD,MAAA;AACd,IAAA;AACM,IAAA;AACQ,MAAA;AACd,IAAA;AACF,EAAA;AACiB,EAAA;AACnB;AFoMyC;AACA;AGhZV;AAE3B;AAEoC;AAET,EAAA;AACtB,IAAA;AACR,EAAA;AAGmC,EAAA;AAGP,EAAA;AACxB,EAAA;AAES,EAAA;AAEN,EAAA;AACR;AAMiE;AAC/B,EAAA;AACT,IAAA;AACM,EAAA;AAEP,IAAA;AACvB,EAAA;AACD;AAEgC;AACjB,EAAA;AAAqB;AAC5B,EAAA;AACR;AAS8E;AAC7C,EAAA;AACxB,IAAA;AACmB,EAAA;AACA,IAAA;AACU,EAAA;AAEzB,IAAA;AACyB,MAAA;AACpC,IAAA;AACM,EAAA;AACc,IAAA;AACrB,EAAA;AACD;AAQoB;AAOC;AAChB,EAAA;AAE8B,EAAA;AACH,IAAA;AACE,MAAA;AACzB,IAAA;AACqB,MAAA;AACG,QAAA;AAChB,MAAA;AACf,IAAA;AACD,EAAA;AAEW,EAAA;AAEJ,EAAA;AACO,IAAA;AACe,MAAA;AAC5B,IAAA;AACD,EAAA;AACD;AAOgC;AAAA;AAE/B,EAAA;AAAA;AAGA,EAAA;AAAA;AAGA,EAAA;AAAA;AAGgD,EAAA;AAE9B,IAAA;AAGG,IAAA;AACK,MAAA;AACzB,IAAA;AAE8B,IAAA;AAGF,IAAA;AACE,MAAA;AAC9B,IAAA;AAEO,IAAA;AACR,EAAA;AAAA;AAGkC,EAAA;AAC7B,IAAA;AACoB,MAAA;AAEA,QAAA;AACN,QAAA;AAGA,QAAA;AACC,QAAA;AAEb,QAAA;AACM,UAAA;AACF,QAAA;AAER,QAAA;AAGA,QAAA;AACD,MAAA;AACC,IAAA;AACuB,MAAA;AACzB,IAAA;AACD,EAAA;AACD;AAE2E;AACxD,EAAA;AACb,IAAA;AACiB,IAAA;AACtB,EAAA;AACD;AHiVyC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-OGAPU3UG.cjs","sourcesContent":[null,"import type { Next } from \"hono\";\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\";\nimport * as errors from \"@/actor/errors\";\nimport { getEnvUniversal } from \"@/utils\";\nimport type { Logger } from \"./log\";\n\nexport function assertUnreachable(x: never): never {\n\tthrow new Error(`Unreachable case: ${x}`);\n}\n\n/**\n * Safely stringifies an object, ensuring that the stringified object is under a certain size.\n * @param obj any object to stringify\n * @param maxSize maximum size of the stringified object in bytes\n * @returns stringified object\n */\nexport function safeStringify(obj: unknown, maxSize: number) {\n\tlet size = 0;\n\n\tfunction replacer(key: string, value: unknown) {\n\t\tif (value === null || value === undefined) return value;\n\t\tconst valueSize =\n\t\t\ttypeof value === \"string\" ? value.length : JSON.stringify(value).length;\n\t\tsize += key.length + valueSize;\n\n\t\tif (size > maxSize) {\n\t\t\tthrow new Error(`JSON object exceeds size limit of ${maxSize} bytes.`);\n\t\t}\n\n\t\treturn value;\n\t}\n\n\treturn JSON.stringify(obj, replacer);\n}\n\n// TODO: Instead of doing this, use a temp var for state and attempt to write\n// it. Roll back state if fails to serialize.\n\n/**\n * Check if a value is CBOR serializable.\n * Optionally pass an onInvalid callback to receive the path to invalid values.\n *\n * For a complete list of supported CBOR tags, see:\n * https://github.com/kriszyp/cbor-x/blob/cc1cf9df8ba72288c7842af1dd374d73e34cdbc1/README.md#list-of-supported-tags-for-decoding\n */\nexport function isCborSerializable(\n\tvalue: unknown,\n\tonInvalid?: (path: string) => void,\n\tcurrentPath = \"\",\n): boolean {\n\t// Handle primitive types directly\n\tif (value === null || value === undefined) {\n\t\treturn true;\n\t}\n\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tonInvalid?.(currentPath);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tif (typeof value === \"boolean\" || typeof value === \"string\") {\n\t\treturn true;\n\t}\n\n\t// Handle BigInt (CBOR tags 2 and 3)\n\tif (typeof value === \"bigint\") {\n\t\treturn true;\n\t}\n\n\t// Handle Date objects (CBOR tags 0 and 1)\n\tif (value instanceof Date) {\n\t\treturn true;\n\t}\n\n\t// Handle typed arrays (CBOR tags 64-82)\n\tif (\n\t\tvalue instanceof Uint8Array ||\n\t\tvalue instanceof Uint8ClampedArray ||\n\t\tvalue instanceof Uint16Array ||\n\t\tvalue instanceof Uint32Array ||\n\t\tvalue instanceof BigUint64Array ||\n\t\tvalue instanceof Int8Array ||\n\t\tvalue instanceof Int16Array ||\n\t\tvalue instanceof Int32Array ||\n\t\tvalue instanceof BigInt64Array ||\n\t\tvalue instanceof Float32Array ||\n\t\tvalue instanceof Float64Array\n\t) {\n\t\treturn true;\n\t}\n\n\t// Handle Map (CBOR tag 259)\n\tif (value instanceof Map) {\n\t\tfor (const [key, val] of value.entries()) {\n\t\t\tconst keyPath = currentPath\n\t\t\t\t? `${currentPath}.key(${String(key)})`\n\t\t\t\t: `key(${String(key)})`;\n\t\t\tconst valPath = currentPath\n\t\t\t\t? `${currentPath}.value(${String(key)})`\n\t\t\t\t: `value(${String(key)})`;\n\t\t\tif (\n\t\t\t\t!isCborSerializable(key, onInvalid, keyPath) ||\n\t\t\t\t!isCborSerializable(val, onInvalid, valPath)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Handle Set (CBOR tag 258)\n\tif (value instanceof Set) {\n\t\tlet index = 0;\n\t\tfor (const item of value.values()) {\n\t\t\tconst itemPath = currentPath\n\t\t\t\t? `${currentPath}.set[${index}]`\n\t\t\t\t: `set[${index}]`;\n\t\t\tif (!isCborSerializable(item, onInvalid, itemPath)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Handle RegExp (CBOR tag 27)\n\tif (value instanceof RegExp) {\n\t\treturn true;\n\t}\n\n\t// Handle Error objects (CBOR tag 27)\n\tif (value instanceof Error) {\n\t\treturn true;\n\t}\n\n\t// Handle arrays\n\tif (Array.isArray(value)) {\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tconst itemPath = currentPath ? `${currentPath}[${i}]` : `[${i}]`;\n\t\t\tif (!isCborSerializable(value[i], onInvalid, itemPath)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Handle plain objects and records (CBOR tags 105, 51, 57344-57599)\n\tif (typeof value === \"object\") {\n\t\t// Allow plain objects and objects with prototypes (for records and named objects)\n\t\tconst proto = Object.getPrototypeOf(value);\n\t\tif (proto !== null && proto !== Object.prototype) {\n\t\t\t// Check if it's a known serializable object type\n\t\t\tconst protoConstructor = value.constructor;\n\t\t\tif (protoConstructor && typeof protoConstructor.name === \"string\") {\n\t\t\t\t// Allow objects with named constructors (records, named objects)\n\t\t\t\t// This includes user-defined classes and built-in objects\n\t\t\t\t// that CBOR can serialize with tag 27 or record tags\n\t\t\t}\n\t\t}\n\n\t\t// Check all properties recursively\n\t\tfor (const key in value) {\n\t\t\tconst propPath = currentPath ? `${currentPath}.${key}` : key;\n\t\t\tif (\n\t\t\t\t!isCborSerializable(\n\t\t\t\t\tvalue[key as keyof typeof value],\n\t\t\t\t\tonInvalid,\n\t\t\t\t\tpropPath,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Not serializable\n\tonInvalid?.(currentPath);\n\treturn false;\n}\n\nexport interface DeconstructedError {\n\t__type: \"ActorError\";\n\tstatusCode: ContentfulStatusCode;\n\tpublic: boolean;\n\tcode: string;\n\tmessage: string;\n\tmetadata?: unknown;\n}\n\n/** Deconstructs error in to components that are used to build responses. */\nexport function deconstructError(\n\terror: unknown,\n\tlogger: Logger,\n\textraLog: Record<string, unknown>,\n\texposeInternalError = false,\n): DeconstructedError {\n\t// Build response error information. Only return errors if flagged as public in order to prevent leaking internal behavior.\n\t//\n\t// We log the error here instead of after generating the code & message because we need to log the original error, not the masked internal error.\n\tlet statusCode: ContentfulStatusCode;\n\tlet public_: boolean;\n\tlet code: string;\n\tlet message: string;\n\tlet metadata: unknown;\n\tif (errors.ActorError.isActorError(error) && error.public) {\n\t\t// Check if error has statusCode (could be ActorError instance or DeconstructedError)\n\t\tstatusCode = (\n\t\t\t\"statusCode\" in error && error.statusCode ? error.statusCode : 400\n\t\t) as ContentfulStatusCode;\n\t\tpublic_ = true;\n\t\tcode = error.code;\n\t\tmessage = getErrorMessage(error);\n\t\tmetadata = error.metadata;\n\n\t\tlogger.info(\"public error\", {\n\t\t\tcode,\n\t\t\tmessage,\n\t\t\tissues: \"https://github.com/rivet-gg/rivetkit/issues\",\n\t\t\tsupport: \"https://rivet.gg/discord\",\n\t\t\t...extraLog,\n\t\t});\n\t} else if (exposeInternalError) {\n\t\tif (errors.ActorError.isActorError(error)) {\n\t\t\tstatusCode = 500;\n\t\t\tpublic_ = false;\n\t\t\tcode = error.code;\n\t\t\tmessage = getErrorMessage(error);\n\t\t\tmetadata = error.metadata;\n\n\t\t\tlogger.info(\"internal error\", {\n\t\t\t\tcode,\n\t\t\t\tmessage,\n\t\t\t\tissues: \"https://github.com/rivet-gg/rivetkit/issues\",\n\t\t\t\tsupport: \"https://rivet.gg/discord\",\n\t\t\t\t...extraLog,\n\t\t\t});\n\t\t} else {\n\t\t\tstatusCode = 500;\n\t\t\tpublic_ = false;\n\t\t\tcode = errors.INTERNAL_ERROR_CODE;\n\t\t\tmessage = getErrorMessage(error);\n\n\t\t\tlogger.info(\"internal error\", {\n\t\t\t\tcode,\n\t\t\t\tmessage,\n\t\t\t\tissues: \"https://github.com/rivet-gg/rivetkit/issues\",\n\t\t\t\tsupport: \"https://rivet.gg/discord\",\n\t\t\t\t...extraLog,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tstatusCode = 500;\n\t\tpublic_ = false;\n\t\tcode = errors.INTERNAL_ERROR_CODE;\n\t\tmessage = errors.INTERNAL_ERROR_DESCRIPTION;\n\t\tmetadata = {\n\t\t\t//url: `https://hub.rivet.gg/projects/${actorMetadata.project.slug}/environments/${actorMetadata.environment.slug}/actors?actorId=${actorMetadata.actor.id}`,\n\t\t} satisfies errors.InternalErrorMetadata;\n\n\t\tlogger.warn(\"internal error\", {\n\t\t\terror: getErrorMessage(error),\n\t\t\tstack: (error as Error)?.stack,\n\t\t\tissues: \"https://github.com/rivet-gg/rivetkit/issues\",\n\t\t\tsupport: \"https://rivet.gg/discord\",\n\t\t\t...extraLog,\n\t\t});\n\t}\n\n\treturn {\n\t\t__type: \"ActorError\",\n\t\tstatusCode,\n\t\tpublic: public_,\n\t\tcode,\n\t\tmessage,\n\t\tmetadata,\n\t};\n}\n\nexport function stringifyError(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tif (\n\t\t\ttypeof process !== \"undefined\" &&\n\t\t\tgetEnvUniversal(\"_RIVETKIT_ERROR_STACK\") === \"1\"\n\t\t) {\n\t\t\treturn `${error.name}: ${error.message}${error.stack ? `\\n${error.stack}` : \"\"}`;\n\t\t} else {\n\t\t\treturn `${error.name}: ${error.message}`;\n\t\t}\n\t} else if (typeof error === \"string\") {\n\t\treturn error;\n\t} else if (typeof error === \"object\" && error !== null) {\n\t\ttry {\n\t\t\treturn `${JSON.stringify(error)}`;\n\t\t} catch {\n\t\t\treturn \"[cannot stringify error]\";\n\t\t}\n\t} else {\n\t\treturn `Unknown error: ${getErrorMessage(error)}`;\n\t}\n}\n\nfunction getErrorMessage(err: unknown): string {\n\tif (\n\t\terr &&\n\t\ttypeof err === \"object\" &&\n\t\t\"message\" in err &&\n\t\ttypeof err.message === \"string\"\n\t) {\n\t\treturn err.message;\n\t} else {\n\t\treturn String(err);\n\t}\n}\n\n/** Generates a `Next` handler to pass to middleware in order to be able to call arbitrary middleware. */\nexport function noopNext(): Next {\n\treturn async () => {};\n}\n","{\n \"name\": \"rivetkit\",\n \"version\": \"2.0.3\",\n \"license\": \"Apache-2.0\",\n \"keywords\": [\n \"rivetkit\",\n \"stateful\",\n \"serverless\",\n \"actors\",\n \"agents\",\n \"realtime\",\n \"websocket\",\n \"actors\",\n \"framework\"\n ],\n \"files\": [\n \"dist\",\n \"src\",\n \"deno.json\",\n \"bun.json\",\n \"package.json\"\n ],\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/tsup/mod.d.ts\",\n \"default\": \"./dist/tsup/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/mod.d.cts\",\n \"default\": \"./dist/tsup/mod.cjs\"\n }\n },\n \"./client\": {\n \"import\": {\n \"types\": \"./dist/tsup/client/mod.d.ts\",\n \"default\": \"./dist/tsup/client/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/client/mod.d.cts\",\n \"default\": \"./dist/tsup/client/mod.cjs\"\n }\n },\n \"./log\": {\n \"import\": {\n \"types\": \"./dist/tsup/common/log.d.ts\",\n \"default\": \"./dist/tsup/common/log.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/common/log.d.cts\",\n \"default\": \"./dist/tsup/common/log.cjs\"\n }\n },\n \"./errors\": {\n \"import\": {\n \"types\": \"./dist/tsup/actor/errors.d.ts\",\n \"default\": \"./dist/tsup/actor/errors.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/actor/errors.d.cts\",\n \"default\": \"./dist/tsup/actor/errors.cjs\"\n }\n },\n \"./utils\": {\n \"import\": {\n \"types\": \"./dist/tsup/utils.d.ts\",\n \"default\": \"./dist/tsup/utils.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/utils.d.cts\",\n \"default\": \"./dist/tsup/utils.cjs\"\n }\n },\n \"./driver-helpers\": {\n \"import\": {\n \"types\": \"./dist/tsup/driver-helpers/mod.d.ts\",\n \"default\": \"./dist/tsup/driver-helpers/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/driver-helpers/mod.d.cts\",\n \"default\": \"./dist/tsup/driver-helpers/mod.cjs\"\n }\n },\n \"./driver-helpers/websocket\": {\n \"import\": {\n \"types\": \"./dist/tsup/common/websocket.d.ts\",\n \"default\": \"./dist/tsup/common/websocket.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/common/websocket.d.cts\",\n \"default\": \"./dist/tsup/common/websocket.cjs\"\n }\n },\n \"./driver-test-suite\": {\n \"import\": {\n \"types\": \"./dist/tsup/driver-test-suite/mod.d.ts\",\n \"default\": \"./dist/tsup/driver-test-suite/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/driver-test-suite/mod.d.cts\",\n \"default\": \"./dist/tsup/driver-test-suite/mod.cjs\"\n }\n },\n \"./topologies/coordinate\": {\n \"import\": {\n \"types\": \"./dist/tsup/topologies/coordinate/mod.d.ts\",\n \"default\": \"./dist/tsup/topologies/coordinate/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/topologies/coordinate/mod.d.cts\",\n \"default\": \"./dist/tsup/topologies/coordinate/mod.cjs\"\n }\n },\n \"./topologies/partition\": {\n \"import\": {\n \"types\": \"./dist/tsup/topologies/partition/mod.d.ts\",\n \"default\": \"./dist/tsup/topologies/partition/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/topologies/partition/mod.d.cts\",\n \"default\": \"./dist/tsup/topologies/partition/mod.cjs\"\n }\n },\n \"./test\": {\n \"import\": {\n \"types\": \"./dist/tsup/test/mod.d.ts\",\n \"default\": \"./dist/tsup/test/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/test/mod.d.cts\",\n \"default\": \"./dist/tsup/test/mod.cjs\"\n }\n },\n \"./inspector\": {\n \"import\": {\n \"types\": \"./dist/tsup/inspector/mod.d.ts\",\n \"default\": \"./dist/tsup/inspector/mod.js\"\n },\n \"require\": {\n \"types\": \"./dist/tsup/inspector/mod.d.cts\",\n \"default\": \"./dist/tsup/inspector/mod.cjs\"\n }\n }\n },\n \"engines\": {\n \"node\": \">=22.0.0\"\n },\n \"sideEffects\": false,\n \"scripts\": {\n \"dev\": \"pnpm build --watch\",\n \"build\": \"tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/topologies/coordinate/mod.ts src/topologies/partition/mod.ts src/utils.ts src/driver-helpers/mod.ts src/driver-test-suite/mod.ts src/test/mod.ts src/inspector/mod.ts\",\n \"build:schema\": \"./scripts/compile-bare.ts compile schemas/client-protocol/v1.bare -o dist/schemas/client-protocol/v1.ts && ./scripts/compile-bare.ts compile schemas/file-system-driver/v1.bare -o dist/schemas/file-system-driver/v1.ts && ./scripts/compile-bare.ts compile schemas/actor-persist/v1.bare -o dist/schemas/actor-persist/v1.ts\",\n \"check-types\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"dump-openapi\": \"tsx scripts/dump-openapi.ts\"\n },\n \"dependencies\": {\n \"@bare-ts/lib\": \"~0.3.0\",\n \"@hono/standard-validator\": \"^0.1.3\",\n \"@hono/zod-openapi\": \"^0.19.10\",\n \"@rivetkit/engine-runner\": \"https://pkg.pr.new/rivet-gg/engine/@rivetkit/engine-runner@664a377\",\n \"@rivetkit/fast-json-patch\": \"^3.1.2\",\n \"cbor-x\": \"^1.6.0\",\n \"hono\": \"^4.7.0\",\n \"invariant\": \"^2.2.4\",\n \"nanoevents\": \"^9.1.0\",\n \"on-change\": \"^5.0.1\",\n \"p-retry\": \"^6.2.1\",\n \"zod\": \"^3.25.76\"\n },\n \"devDependencies\": {\n \"@bare-ts/tools\": \"^0.13.0\",\n \"@hono/node-server\": \"^1.18.2\",\n \"@hono/node-ws\": \"^1.1.1\",\n \"@rivet-gg/actor-core\": \"^25.1.0\",\n \"@types/invariant\": \"^2\",\n \"@types/node\": \"^22.13.1\",\n \"@types/ws\": \"^8\",\n \"@vitest/ui\": \"3.1.1\",\n \"bundle-require\": \"^5.1.0\",\n \"eventsource\": \"^3.0.5\",\n \"tsup\": \"^8.4.0\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^3.1.1\",\n \"ws\": \"^8.18.1\"\n },\n \"peerDependencies\": {\n \"@hono/node-server\": \"^1.14.0\",\n \"@hono/node-ws\": \"^1.1.1\",\n \"eventsource\": \"^3.0.5\",\n \"ws\": \"^8.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@hono/node-server\": {\n \"optional\": true\n },\n \"@hono/node-ws\": {\n \"optional\": true\n },\n \"eventsource\": {\n \"optional\": true\n },\n \"ws\": {\n \"optional\": true\n }\n },\n \"stableVersion\": \"0.8.0\"\n}\n","export { stringifyError } from \"@/common/utils\";\nexport { assertUnreachable } from \"./common/utils\";\n\nimport type { Context as HonoContext, Handler as HonoHandler } from \"hono\";\n\nimport pkgJson from \"../package.json\" with { type: \"json\" };\n\nexport const VERSION = pkgJson.version;\n\nlet _userAgent: string | undefined;\n\nexport function httpUserAgent(): string {\n\t// Return cached value if already initialized\n\tif (_userAgent !== undefined) {\n\t\treturn _userAgent;\n\t}\n\n\t// Library\n\tlet userAgent = `RivetKit/${VERSION}`;\n\n\t// Navigator\n\tconst navigatorObj = typeof navigator !== \"undefined\" ? navigator : undefined;\n\tif (navigatorObj?.userAgent) userAgent += ` ${navigatorObj.userAgent}`;\n\n\t_userAgent = userAgent;\n\n\treturn userAgent;\n}\n\nexport type UpgradeWebSocket = (\n\tcreateEvents: (c: HonoContext) => any,\n) => HonoHandler;\n\nexport function getEnvUniversal(key: string): string | undefined {\n\tif (typeof Deno !== \"undefined\") {\n\t\treturn Deno.env.get(key);\n\t} else if (typeof process !== \"undefined\") {\n\t\t// Do this after Deno since `process` is sometimes polyfilled\n\t\treturn process.env[key];\n\t}\n}\n\nexport function dbg<T>(x: T): T {\n\tconsole.trace(`=== DEBUG ===\\n${x}`);\n\treturn x;\n}\n\n/**\n * Converts various ArrayBuffer-like types to Uint8Array.\n * Handles ArrayBuffer, ArrayBufferView (including typed arrays), and passes through existing Uint8Array.\n *\n * @param data - The ArrayBuffer or ArrayBufferView to convert\n * @returns A Uint8Array view of the data\n */\nexport function toUint8Array(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n\tif (data instanceof Uint8Array) {\n\t\treturn data;\n\t} else if (data instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(data);\n\t} else if (ArrayBuffer.isView(data)) {\n\t\t// Handle other ArrayBufferView types (Int8Array, Uint16Array, DataView, etc.)\n\t\treturn new Uint8Array(\n\t\t\tdata.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),\n\t\t);\n\t} else {\n\t\tthrow new TypeError(\"Input must be ArrayBuffer or ArrayBufferView\");\n\t}\n}\n\n// Long timeouts\n//\n// JavaScript timers use a signed 32-bit integer for delays, so values above 2^31-1 (~24.8 days)\n// are not reliable and may fire immediately or overflow.\n//\n// https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#maximum_delay_value\nconst TIMEOUT_MAX = 2147483647; // 2^31-1\n\nexport type LongTimeoutHandle = { abort: () => void };\n\nexport function setLongTimeout(\n\tlistener: () => void,\n\tafter: number,\n): LongTimeoutHandle {\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\n\tfunction start(remaining: number) {\n\t\tif (remaining <= TIMEOUT_MAX) {\n\t\t\ttimeout = setTimeout(listener, remaining);\n\t\t} else {\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\tstart(remaining - TIMEOUT_MAX);\n\t\t\t}, TIMEOUT_MAX);\n\t\t}\n\t}\n\n\tstart(after);\n\n\treturn {\n\t\tabort: () => {\n\t\t\tif (timeout !== undefined) clearTimeout(timeout);\n\t\t},\n\t};\n}\n\n/**\n * A tiny utility that coalesces/enqueues async operations so only the latest\n * queued task runs per cycle, while callers receive a promise that resolves\n * when the task for the cycle they joined has completed.\n */\nexport class SinglePromiseQueue {\n\t/** Next operation to execute in the queue. If attempting to enqueue another op, it will override the existing op. */\n\t#queuedOp?: () => Promise<void>;\n\n\t/** The currently running promise of #drainLoop. Do not await this, instead await `pending` to await the current cycle. */\n\trunningDrainLoop?: Promise<void>;\n\n\t/** Pending resolver fro the currently queued entry. */\n\t#pending?: PromiseWithResolvers<void>;\n\n\t/** Queue the next operation and return a promise that resolves when it flushes. */\n\tenqueue(op: () => Promise<void>): Promise<void> {\n\t\t// Replace any previously queued operation with the latest one\n\t\tthis.#queuedOp = op;\n\n\t\t// Ensure a shared resolver exists for all callers in this cycle\n\t\tif (!this.#pending) {\n\t\t\tthis.#pending = Promise.withResolvers<void>();\n\t\t}\n\n\t\tconst waitForThisCycle = this.#pending.promise;\n\n\t\t// Start runner if not already running\n\t\tif (!this.runningDrainLoop) {\n\t\t\tthis.runningDrainLoop = this.#drainLoop();\n\t\t}\n\n\t\treturn waitForThisCycle;\n\t}\n\n\t/** Drain queued operations sequentially until there is nothing left. */\n\tasync #drainLoop(): Promise<void> {\n\t\ttry {\n\t\t\twhile (this.#queuedOp) {\n\t\t\t\t// Capture current cycle resolver then reset for the next cycle\n\t\t\t\tconst resolver = this.#pending;\n\t\t\t\tthis.#pending = undefined;\n\n\t\t\t\t// Capture and clear the currently queued operation\n\t\t\t\tconst op = this.#queuedOp;\n\t\t\t\tthis.#queuedOp = undefined;\n\n\t\t\t\ttry {\n\t\t\t\t\tawait op();\n\t\t\t\t} catch {\n\t\t\t\t\t// Swallow errors: callers only await cycle completion, not success\n\t\t\t\t}\n\n\t\t\t\t// Notify all waiters for this cycle\n\t\t\t\tresolver?.resolve();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.runningDrainLoop = undefined;\n\t\t}\n\t}\n}\n\nexport function bufferToArrayBuffer(buf: Buffer | Uint8Array): ArrayBuffer {\n\treturn buf.buffer.slice(\n\t\tbuf.byteOffset,\n\t\tbuf.byteOffset + buf.byteLength,\n\t) as ArrayBuffer;\n}\n"]}
|