@rivetkit/core
Version:
1,383 lines (1,369 loc) • 83.9 kB
TypeScript
import { z } from 'zod';
import * as hono from 'hono';
import { Env, Context, Hono } from 'hono';
import { WebSocket as WebSocket$1 } from 'ws';
import { Logger } from './common/log.js';
import { UpgradeWebSocket } from './utils.js';
import * as nanoevents from 'nanoevents';
import { g as Connection, h as RealtimeEvent } from './common-CXCe7s6i.js';
import { SSEStreamingApi } from 'hono/streaming';
import { WSContext } from 'hono/ws';
declare const ToClientSchema: z.ZodObject<{
b: z.ZodUnion<[z.ZodObject<{
i: z.ZodObject<{
ai: z.ZodString;
ci: z.ZodString;
ct: z.ZodString;
}, "strip", z.ZodTypeAny, {
ai: string;
ci: string;
ct: string;
}, {
ai: string;
ci: string;
ct: string;
}>;
}, "strip", z.ZodTypeAny, {
i: {
ai: string;
ci: string;
ct: string;
};
}, {
i: {
ai: string;
ci: string;
ct: string;
};
}>, z.ZodObject<{
e: z.ZodObject<{
c: z.ZodString;
m: z.ZodString;
md: z.ZodOptional<z.ZodUnknown>;
ai: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
}, {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
}>;
}, "strip", z.ZodTypeAny, {
e: {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
};
}, {
e: {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
};
}>, z.ZodObject<{
ar: z.ZodObject<{
i: z.ZodNumber;
o: z.ZodUnknown;
}, "strip", z.ZodTypeAny, {
i: number;
o?: unknown;
}, {
i: number;
o?: unknown;
}>;
}, "strip", z.ZodTypeAny, {
ar: {
i: number;
o?: unknown;
};
}, {
ar: {
i: number;
o?: unknown;
};
}>, z.ZodObject<{
ev: z.ZodObject<{
n: z.ZodString;
a: z.ZodArray<z.ZodUnknown, "many">;
}, "strip", z.ZodTypeAny, {
n: string;
a: unknown[];
}, {
n: string;
a: unknown[];
}>;
}, "strip", z.ZodTypeAny, {
ev: {
n: string;
a: unknown[];
};
}, {
ev: {
n: string;
a: unknown[];
};
}>]>;
}, "strip", z.ZodTypeAny, {
b: {
i: {
ai: string;
ci: string;
ct: string;
};
} | {
e: {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
};
} | {
ar: {
i: number;
o?: unknown;
};
} | {
ev: {
n: string;
a: unknown[];
};
};
}, {
b: {
i: {
ai: string;
ci: string;
ct: string;
};
} | {
e: {
c: string;
m: string;
ai?: number | undefined;
md?: unknown;
};
} | {
ar: {
i: number;
o?: unknown;
};
} | {
ev: {
n: string;
a: unknown[];
};
};
}>;
type ToClient = z.infer<typeof ToClientSchema>;
type InferDatabaseClient<DBProvider extends AnyDatabaseProvider> = DBProvider extends DatabaseProvider<any> ? Awaited<ReturnType<DBProvider["createClient"]>> : never;
type AnyDatabaseProvider = DatabaseProvider<any> | undefined;
type DatabaseProvider<DB extends {
execute: (query: string) => any;
}> = {
/**
* Creates a new database client for the actor.
* The result is passed to the actor context as `c.db`.
* @experimental
*/
createClient: (ctx: {
getDatabase: () => Promise<string | unknown>;
}) => Promise<DB>;
/**
* Runs before the actor has started.
* Use this to run migrations or other setup tasks.
* @experimental
*/
onMigrate: (client: DB) => void | Promise<void>;
};
/** Data that's been serialized. */
type OutputData = string | Uint8Array;
declare const EncodingSchema: z.ZodEnum<["json", "cbor"]>;
/**
* Encoding used to communicate between the client & actor.
*/
type Encoding = z.infer<typeof EncodingSchema>;
/**
* Helper class that helps serialize data without re-serializing for the same encoding.
*/
declare class CachedSerializer<T> {
#private;
constructor(data: T);
get rawData(): T;
serialize(encoding: Encoding): OutputData;
}
declare const ActorsSchema: z.ZodRecord<z.ZodString, z.ZodType<ActorDefinition<any, any, any, any, any, any, any, any>, z.ZodTypeDef, ActorDefinition<any, any, any, any, any, any, any, any>>>;
type RegistryActors = z.infer<typeof ActorsSchema>;
/** Base config used for the actor config across all platforms. */
declare const RegistryConfigSchema: z.ZodObject<{
use: z.ZodRecord<z.ZodString, z.ZodType<AnyActorDefinition, z.ZodTypeDef, AnyActorDefinition>>;
/**
* Test configuration.
*
* DO NOT MANUALLY ENABLE. THIS IS USED INTERNALLY.
* @internal
**/
test: z.ZodDefault<z.ZodOptional<z.ZodObject<{
enabled: z.ZodBoolean;
}, "strip", z.ZodTypeAny, {
enabled: boolean;
}, {
enabled: boolean;
}>>>;
}, "strip", z.ZodTypeAny, {
use: Record<string, AnyActorDefinition>;
test: {
enabled: boolean;
};
}, {
use: Record<string, AnyActorDefinition>;
test?: {
enabled: boolean;
} | undefined;
}>;
type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
type RegistryConfigInput<A extends RegistryActors> = Omit<z.input<typeof RegistryConfigSchema>, "use"> & {
use: A;
};
interface RivetEvent {
type: string;
target?: any;
currentTarget?: any;
}
interface RivetMessageEvent extends RivetEvent {
data: any;
}
interface RivetCloseEvent extends RivetEvent {
code: number;
reason: string;
wasClean: boolean;
}
/**
* Common WebSocket interface that can be implemented by different WebSocket-like classes
* This is compatible with the standard WebSocket API but allows for custom implementations
*/
interface UniversalWebSocket {
readonly CONNECTING: 0;
readonly OPEN: 1;
readonly CLOSING: 2;
readonly CLOSED: 3;
readonly readyState: 0 | 1 | 2 | 3;
binaryType: "arraybuffer" | "blob";
readonly bufferedAmount: number;
readonly extensions: string;
readonly protocol: string;
readonly url: string;
send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
close(code?: number, reason?: string): void;
addEventListener(type: string, listener: (event: any) => void): void;
removeEventListener(type: string, listener: (event: any) => void): void;
dispatchEvent(event: RivetEvent): boolean;
onopen?: ((event: RivetEvent) => void) | null;
onclose?: ((event: RivetCloseEvent) => void) | null;
onerror?: ((event: RivetEvent) => void) | null;
onmessage?: ((event: RivetMessageEvent) => void) | null;
}
type ManagerDriverBuilder = (registryConfig: RegistryConfig, runConfig: RunConfig) => ManagerDriver;
interface ManagerDriver {
getForId(input: GetForIdInput): Promise<ActorOutput | undefined>;
getWithKey(input: GetWithKeyInput): Promise<ActorOutput | undefined>;
getOrCreateWithKey(input: GetOrCreateWithKeyInput): Promise<ActorOutput>;
createActor(input: CreateInput): Promise<ActorOutput>;
sendRequest(actorId: string, actorRequest: Request): Promise<Response>;
openWebSocket(path: string, actorId: string, encoding: Encoding, params: unknown): Promise<WebSocket>;
proxyRequest(c: Context, actorRequest: Request, actorId: string): Promise<Response>;
proxyWebSocket(c: Context, path: string, actorId: string, encoding: Encoding, params: unknown, authData: unknown): Promise<Response>;
extraStartupLog?: () => Record<string, unknown>;
modifyManagerRouter?: (registryConfig: RegistryConfig, router: Hono) => void;
}
interface GetForIdInput<E extends Env = any> {
c?: Context | undefined;
actorId: string;
}
interface GetWithKeyInput<E extends Env = any> {
c?: Context | undefined;
name: string;
key: ActorKey;
}
interface GetOrCreateWithKeyInput<E extends Env = any> {
c?: Context | undefined;
name: string;
key: ActorKey;
input?: unknown;
region?: string;
}
interface CreateInput<E extends Env = any> {
c?: Context | undefined;
name: string;
key: ActorKey;
input?: unknown;
region?: string;
}
interface ActorOutput {
actorId: string;
name: string;
key: ActorKey;
}
type GetUpgradeWebSocket = () => UpgradeWebSocket;
declare const DriverConfigSchema: z.ZodObject<{
/** Machine-readable name to identify this driver by. */
name: z.ZodString;
manager: z.ZodType<ManagerDriverBuilder, z.ZodTypeDef, ManagerDriverBuilder>;
actor: z.ZodType<ActorDriverBuilder, z.ZodTypeDef, ActorDriverBuilder>;
}, "strip", z.ZodTypeAny, {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
}, {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
}>;
type DriverConfig = z.infer<typeof DriverConfigSchema>;
/** Base config used for the actor config across all platforms. */
declare const RunConfigSchema: z.ZodDefault<z.ZodObject<{
driver: z.ZodDefault<z.ZodOptional<z.ZodObject<{
/** Machine-readable name to identify this driver by. */
name: z.ZodString;
manager: z.ZodType<ManagerDriverBuilder, z.ZodTypeDef, ManagerDriverBuilder>;
actor: z.ZodType<ActorDriverBuilder, z.ZodTypeDef, ActorDriverBuilder>;
}, "strip", z.ZodTypeAny, {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
}, {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
}>>>;
getUpgradeWebSocket: z.ZodOptional<z.ZodType<GetUpgradeWebSocket, z.ZodTypeDef, GetUpgradeWebSocket>>;
/** CORS configuration for the router. Uses Hono's CORS middleware options. */
cors: z.ZodOptional<z.ZodType<{
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}, z.ZodTypeDef, {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}>>;
maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
studio: z.ZodDefault<z.ZodOptional<z.ZodObject<{
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
cors: z.ZodDefault<z.ZodOptional<z.ZodType<{
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}, z.ZodTypeDef, {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}>>>;
token: z.ZodDefault<z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>>>;
defaultEndpoint: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
enabled: boolean;
cors: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
};
token: (...args: unknown[]) => string;
defaultEndpoint?: string | undefined;
}, {
enabled?: boolean | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
token?: ((...args: unknown[]) => string) | undefined;
defaultEndpoint?: string | undefined;
}>>>;
/**
* Base path for the router. This is used to prefix all routes.
* For example, if the base path is `/api`, then the route `/actors` will be
* available at `/api/actors`.
*/
basePath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
}, "strip", z.ZodTypeAny, {
driver: {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
};
maxIncomingMessageSize: number;
studio: {
enabled: boolean;
cors: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
};
token: (...args: unknown[]) => string;
defaultEndpoint?: string | undefined;
};
basePath: string;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
}, {
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
driver?: {
name: string;
actor: ActorDriverBuilder;
manager: ManagerDriverBuilder;
} | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
maxIncomingMessageSize?: number | undefined;
studio?: {
enabled?: boolean | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
token?: ((...args: unknown[]) => string) | undefined;
defaultEndpoint?: string | undefined;
} | undefined;
basePath?: string | undefined;
}>>;
type RunConfig = z.infer<typeof RunConfigSchema>;
type RunConfigInput = z.input<typeof RunConfigSchema>;
interface ServerOutput<A extends Registry<any>> {
client: Client<A>;
hono: Hono;
handler: (req: Request) => Promise<Response>;
serve: (hono?: Hono) => void;
}
interface ActorNodeOutput {
hono: Hono<any>;
handler: (req: Request) => Promise<Response>;
serve: (hono?: Hono) => void;
}
declare class Registry<A extends RegistryActors> {
#private;
get config(): RegistryConfig;
constructor(config: RegistryConfig);
/**
* Runs the registry for a server.
*/
createServer(inputConfig?: RunConfigInput): ServerOutput<this>;
/**
* Runs the registry as a standalone server.
*/
runServer(inputConfig?: RunConfigInput): Promise<void>;
/**
* Creates a worker for the registry.
*/
createWorker(inputConfig?: RunConfigInput): ActorNodeOutput;
/**
* Runs the standalone worker.
*/
runWorker(inputConfig?: RunConfigInput): Promise<void>;
}
declare function setup<A extends RegistryActors>(input: RegistryConfigInput<A>): Registry<A>;
declare const ToServerSchema: z.ZodObject<{
b: z.ZodUnion<[z.ZodObject<{
ar: z.ZodObject<{
i: z.ZodNumber;
n: z.ZodString;
a: z.ZodArray<z.ZodUnknown, "many">;
}, "strip", z.ZodTypeAny, {
i: number;
n: string;
a: unknown[];
}, {
i: number;
n: string;
a: unknown[];
}>;
}, "strip", z.ZodTypeAny, {
ar: {
i: number;
n: string;
a: unknown[];
};
}, {
ar: {
i: number;
n: string;
a: unknown[];
};
}>, z.ZodObject<{
sr: z.ZodObject<{
e: z.ZodString;
s: z.ZodBoolean;
}, "strip", z.ZodTypeAny, {
e: string;
s: boolean;
}, {
e: string;
s: boolean;
}>;
}, "strip", z.ZodTypeAny, {
sr: {
e: string;
s: boolean;
};
}, {
sr: {
e: string;
s: boolean;
};
}>]>;
}, "strip", z.ZodTypeAny, {
b: {
ar: {
i: number;
n: string;
a: unknown[];
};
} | {
sr: {
e: string;
s: boolean;
};
};
}, {
b: {
ar: {
i: number;
n: string;
a: unknown[];
};
} | {
sr: {
e: string;
s: boolean;
};
};
}>;
type ToServer = z.infer<typeof ToServerSchema>;
interface ActorInspectorAccessors {
isStateEnabled: () => Promise<boolean>;
getState: () => Promise<unknown>;
setState: (state: unknown) => Promise<void>;
isDbEnabled: () => Promise<boolean>;
getDb: () => Promise<InferDatabaseClient<AnyDatabaseProvider>>;
getRpcs: () => Promise<string[]>;
getConnections: () => Promise<Connection[]>;
}
interface ActorInspectorEmitterEvents {
stateUpdated: (state: unknown) => void;
connectionUpdated: () => void;
eventFired: (event: RealtimeEvent) => void;
}
/**
* Provides a unified interface for inspecting actor external and internal state.
*/
declare class ActorInspector {
#private;
readonly accessors: ActorInspectorAccessors;
readonly emitter: nanoevents.Emitter<ActorInspectorEmitterEvents>;
get lastRealtimeEvents(): (({
type: "action";
name: string;
args: any[];
connId: string;
} | {
type: "broadcast";
eventName: string;
args: any[];
} | {
type: "subscribe";
eventName: string;
connId: string;
} | {
type: "unsubscribe";
eventName: string;
connId: string;
} | {
type: "event";
eventName: string;
args: any[];
connId: string;
}) & {
id: string;
timestamp: number;
})[];
constructor(accessors: () => ActorInspectorAccessors);
}
declare class Schedule {
#private;
constructor(actor: AnyActorInstance);
after(duration: number, fn: string, ...args: unknown[]): Promise<void>;
at(timestamp: number, fn: string, ...args: unknown[]): Promise<void>;
}
/**
* Options for the `_saveState` method.
*/
interface SaveStateOptions {
/**
* Forces the state to be saved immediately. This function will return when the state has saved successfully.
*/
immediate?: boolean;
}
/** Actor type alias with all `any` types. Used for `extends` in classes referencing this actor. */
type AnyActorInstance = ActorInstance<any, any, any, any, any, any, any>;
declare class ActorInstance<S, CP, CS, V, I, AD, DB extends AnyDatabaseProvider> {
#private;
actorContext: ActorContext<S, CP, CS, V, I, AD, DB>;
isStopping: boolean;
get id(): string;
get inlineClient(): Client<Registry<any>>;
get inspector(): ActorInspector;
/**
* This constructor should never be used directly.
*
* Constructed in {@link ActorInstance.start}.
*
* @private
*/
constructor(config: ActorConfig<S, CP, CS, V, I, AD, DB>);
start(connectionDrivers: ConnDrivers, actorDriver: ActorDriver, inlineClient: Client<Registry<any>>, actorId: string, name: string, key: ActorKey, region: string): Promise<void>;
scheduleEvent(timestamp: number, fn: string, args: unknown[]): Promise<void>;
onAlarm(): Promise<void>;
get stateEnabled(): boolean;
__getConnForId(id: string): Conn<S, CP, CS, V, I, AD, DB> | undefined;
/**
* Removes a connection and cleans up its resources.
*/
__removeConn(conn: Conn<S, CP, CS, V, I, AD, DB> | undefined): void;
prepareConn(params: any, request?: Request): Promise<CS>;
__getConnDriver(driverId: string): ConnDriver;
/**
* Called after establishing a connection handshake.
*/
createConn(connectionId: string, connectionToken: string, params: CP, state: CS, driverId: string, driverState: unknown, authData: unknown): Promise<Conn<S, CP, CS, V, I, AD, DB>>;
processMessage(message: ToServer, conn: Conn<S, CP, CS, V, I, AD, DB>): Promise<void>;
/**
* Check if the actor is ready to handle requests.
*/
isReady(): boolean;
/**
* Returns a list of action methods available on this actor.
*/
get actions(): string[];
/**
* Handles raw HTTP requests to the actor.
*/
handleFetch(request: Request, opts: {
auth: AD;
}): Promise<Response>;
/**
* Handles raw WebSocket connections to the actor.
*/
handleWebSocket(websocket: UniversalWebSocket, opts: {
request: Request;
auth: AD;
}): Promise<void>;
/**
* Gets the logger instance.
*/
get log(): Logger;
/**
* Gets the name.
*/
get name(): string;
/**
* Gets the key.
*/
get key(): ActorKey;
/**
* Gets the region.
*/
get region(): string;
/**
* Gets the scheduler.
*/
get schedule(): Schedule;
/**
* Gets the map of connections.
*/
get conns(): Map<ConnId, Conn<S, CP, CS, V, I, AD, DB>>;
/**
* Gets the current state.
*
* Changing properties of this value will automatically be persisted.
*/
get state(): S;
/**
* Gets the database.
* @experimental
* @throws {DatabaseNotEnabled} If the database is not enabled.
*/
get db(): InferDatabaseClient<DB>;
/**
* Sets the current state.
*
* This property will automatically be persisted.
*/
set state(value: S);
get vars(): V;
/**
* Broadcasts an event to all connected clients.
* @param name - The name of the event.
* @param args - The arguments to send with the event.
*/
_broadcast<Args extends Array<unknown>>(name: string, ...args: Args): void;
/**
* Runs a promise in the background.
*
* This allows the actor runtime to ensure that a promise completes while
* returning from an action request early.
*
* @param promise - The promise to run in the background.
*/
_runInBackground(promise: Promise<void>): void;
/**
* Forces the state to get saved.
*
* This is helpful if running a long task that may fail later or when
* running a background job that updates the state.
*
* @param opts - Options for saving the state.
*/
saveState(opts: SaveStateOptions): Promise<void>;
stop(): Promise<void>;
}
/**
* ActorContext class that provides access to actor methods and state
*/
declare class ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase extends AnyDatabaseProvider> {
#private;
constructor(actor: ActorInstance<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>);
/**
* Get the actor state
*/
get state(): TState;
/**
* Get the actor variables
*/
get vars(): TVars;
/**
* Broadcasts an event to all connected clients.
* @param name - The name of the event.
* @param args - The arguments to send with the event.
*/
broadcast<Args extends Array<unknown>>(name: string, ...args: Args): void;
/**
* Gets the logger instance.
*/
get log(): Logger;
/**
* Gets actor ID.
*/
get actorId(): string;
/**
* Gets the actor name.
*/
get name(): string;
/**
* Gets the actor key.
*/
get key(): ActorKey;
/**
* Gets the region.
*/
get region(): string;
/**
* Gets the scheduler.
*/
get schedule(): Schedule;
/**
* Gets the map of connections.
*/
get conns(): Map<ConnId, Conn<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>>;
/**
* Returns the client for the given registry.
*/
client<R extends Registry<any>>(): Client<R>;
/**
* Gets the database.
* @experimental
* @throws {DatabaseNotEnabled} If the database is not enabled.
*/
get db(): InferDatabaseClient<TDatabase>;
/**
* Forces the state to get saved.
*
* @param opts - Options for saving the state.
*/
saveState(opts: SaveStateOptions): Promise<void>;
/**
* Runs a promise in the background.
*
* @param promise - The promise to run in the background.
*/
runInBackground(promise: Promise<void>): void;
}
type InitContext = ActorContext<undefined, undefined, undefined, undefined, undefined, undefined, undefined>;
interface ActorTypes<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase extends AnyDatabaseProvider> {
state?: TState;
connParams?: TConnParams;
connState?: TConnState;
vars?: TVars;
input?: TInput;
authData?: TAuthData;
database?: TDatabase;
}
declare const ActorConfigSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
onAuth: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onCreate: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onStart: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onStateChange: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onBeforeConnect: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onConnect: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onDisconnect: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onBeforeActionResponse: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onFetch: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
onWebSocket: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
actions: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>>;
state: z.ZodOptional<z.ZodAny>;
createState: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
connState: z.ZodOptional<z.ZodAny>;
createConnState: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
vars: z.ZodOptional<z.ZodAny>;
db: z.ZodOptional<z.ZodAny>;
createVars: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
options: z.ZodDefault<z.ZodObject<{
lifecycle: z.ZodDefault<z.ZodObject<{
createVarsTimeout: z.ZodDefault<z.ZodNumber>;
createConnStateTimeout: z.ZodDefault<z.ZodNumber>;
onConnectTimeout: z.ZodDefault<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
}, {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
}>>;
state: z.ZodDefault<z.ZodObject<{
saveInterval: z.ZodDefault<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
saveInterval: number;
}, {
saveInterval?: number | undefined;
}>>;
action: z.ZodDefault<z.ZodObject<{
timeout: z.ZodDefault<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
timeout: number;
}, {
timeout?: number | undefined;
}>>;
}, "strict", z.ZodTypeAny, {
state: {
saveInterval: number;
};
action: {
timeout: number;
};
lifecycle: {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
};
}, {
state?: {
saveInterval?: number | undefined;
} | undefined;
action?: {
timeout?: number | undefined;
} | undefined;
lifecycle?: {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
} | undefined;
}>>;
}, "strict", z.ZodTypeAny, {
options: {
state: {
saveInterval: number;
};
action: {
timeout: number;
};
lifecycle: {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
};
};
actions: Record<string, (...args: unknown[]) => unknown>;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}, {
options?: {
state?: {
saveInterval?: number | undefined;
} | undefined;
action?: {
timeout?: number | undefined;
} | undefined;
lifecycle?: {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
} | undefined;
} | undefined;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
actions?: Record<string, (...args: unknown[]) => unknown> | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}>, {
options: {
state: {
saveInterval: number;
};
action: {
timeout: number;
};
lifecycle: {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
};
};
actions: Record<string, (...args: unknown[]) => unknown>;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}, {
options?: {
state?: {
saveInterval?: number | undefined;
} | undefined;
action?: {
timeout?: number | undefined;
} | undefined;
lifecycle?: {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
} | undefined;
} | undefined;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
actions?: Record<string, (...args: unknown[]) => unknown> | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}>, {
options: {
state: {
saveInterval: number;
};
action: {
timeout: number;
};
lifecycle: {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
};
};
actions: Record<string, (...args: unknown[]) => unknown>;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}, {
options?: {
state?: {
saveInterval?: number | undefined;
} | undefined;
action?: {
timeout?: number | undefined;
} | undefined;
lifecycle?: {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
} | undefined;
} | undefined;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
actions?: Record<string, (...args: unknown[]) => unknown> | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}>, {
options: {
state: {
saveInterval: number;
};
action: {
timeout: number;
};
lifecycle: {
createVarsTimeout: number;
createConnStateTimeout: number;
onConnectTimeout: number;
};
};
actions: Record<string, (...args: unknown[]) => unknown>;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}, {
options?: {
state?: {
saveInterval?: number | undefined;
} | undefined;
action?: {
timeout?: number | undefined;
} | undefined;
lifecycle?: {
createVarsTimeout?: number | undefined;
createConnStateTimeout?: number | undefined;
onConnectTimeout?: number | undefined;
} | undefined;
} | undefined;
state?: any;
db?: any;
onAuth?: ((...args: unknown[]) => unknown) | undefined;
onCreate?: ((...args: unknown[]) => unknown) | undefined;
onStart?: ((...args: unknown[]) => unknown) | undefined;
onStateChange?: ((...args: unknown[]) => unknown) | undefined;
onBeforeConnect?: ((...args: unknown[]) => unknown) | undefined;
onConnect?: ((...args: unknown[]) => unknown) | undefined;
onDisconnect?: ((...args: unknown[]) => unknown) | undefined;
onBeforeActionResponse?: ((...args: unknown[]) => unknown) | undefined;
onFetch?: ((...args: unknown[]) => unknown) | undefined;
onWebSocket?: ((...args: unknown[]) => unknown) | undefined;
actions?: Record<string, (...args: unknown[]) => unknown> | undefined;
createState?: ((...args: unknown[]) => unknown) | undefined;
connState?: any;
createConnState?: ((...args: unknown[]) => unknown) | undefined;
vars?: any;
createVars?: ((...args: unknown[]) => unknown) | undefined;
}>;
interface OnConnectOptions {
/**
* The request object associated with the connection.
*
* @experimental
*/
request?: Request;
}
type CreateState<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase> = {
state: TState;
} | {
createState: (c: InitContext, input: TInput) => TState | Promise<TState>;
} | Record<never, never>;
type CreateConnState<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase> = {
connState: TConnState;
} | {
createConnState: (c: InitContext, opts: OnConnectOptions, params: TConnParams) => TConnState | Promise<TConnState>;
} | Record<never, never>;
/**
* @experimental
*/
type CreateVars<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase> = {
/**
* @experimental
*/
vars: TVars;
} | {
/**
* @experimental
*/
createVars: (c: InitContext, driverCtx: any) => TVars | Promise<TVars>;
} | Record<never, never>;
type OnAuth<TConnParams, TAuthData> = {
/**
* Called on the HTTP server before clients can interact with the actor.
*
* Only called for public endpoints. Calls to actors from within the backend
* do not trigger this handler.
*
* Data returned from this handler will be available on `c.conn.auth`.
*
* This function is required for any public HTTP endpoint access. Use this hook
* to validate client credentials and return authentication data that will be
* available on connections. This runs on the HTTP server (not the actor)
* in order to reduce load on the actor & prevent denial of server attacks
* against individual actors.
*
* If you need access to actor state for authentication, use onBeforeConnect
* with an empty onAuth function instead.
*
* You can also provide your own authentication middleware on your router if you
* choose, then use onAuth to pass the authentication data (e.g. user ID) to the
* actor itself.
*
* @param opts Authentication options including request and intent
* @returns Authentication data to attach to connections (must be serializable)
* @throws Throw an error to deny access to the actor
*/
onAuth: (opts: OnAuthOptions, params: TConnParams) => TAuthData | Promise<TAuthData>;
} | Record<never, never>;
interface Actions<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase extends AnyDatabaseProvider> {
[Action: string]: (c: ActionContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, ...args: any[]) => any;
}
/**
* @experimental
*/
type AuthIntent = "get" | "create" | "connect" | "action" | "message";
interface OnAuthOptions {
request: Request;
/**
* @experimental
*/
intents: Set<AuthIntent>;
}
interface BaseActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase extends AnyDatabaseProvider, TActions extends Actions<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>> {
/**
* Called when the actor is first initialized.
*
* Use this hook to initialize your actor's state.
* This is called before any other lifecycle hooks.
*/
onCreate?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, input: TInput) => void | Promise<void>;
/**
* Called when the actor is started and ready to receive connections and action.
*
* Use this hook to initialize resources needed for the actor's operation
* (timers, external connections, etc.)
*
* @returns Void or a Promise that resolves when startup is complete
*/
onStart?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>) => void | Promise<void>;
/**
* Called when the actor's state changes.
*
* Use this hook to react to state changes, such as updating
* external systems or triggering events.
*
* @param newState The updated state
*/
onStateChange?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, newState: TState) => void;
/**
* Called before a client connects to the actor.
*
* Unlike onAuth, this handler is still called for both internal and
* public clients.
*
* Use this hook to determine if a connection should be accepted
* and to initialize connection-specific state. Unlike onAuth, this runs
* on the actor and has access to actor state, but uses slightly
* more resources on the actor rather than authenticating with onAuth.
*
* For authentication without actor state access, prefer onAuth.
*
* For authentication with actor state, use onBeforeConnect with an empty
* onAuth handler.
*
* @param opts Connection parameters including client-provided data
* @returns The initial connection state or a Promise that resolves to it
* @throws Throw an error to reject the connection
*/
onBeforeConnect?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, opts: OnConnectOptions, params: TConnParams) => void | Promise<void>;
/**
* Called when a client successfully connects to the actor.
*
* Use this hook to perform actions when a connection is established,
* such as sending initial data or updating the actor's state.
*
* @param conn The connection object
* @returns Void or a Promise that resolves when connection handling is complete
*/
onConnect?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>) => void | Promise<void>;
/**
* Called when a client disconnects from the actor.
*
* Use this hook to clean up resources associated with the connection
* or update the actor's state.
*
* @param conn The connection that is being closed
* @returns Void or a Promise that resolves when disconnect handling is complete
*/
onDisconnect?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>) => void | Promise<void>;
/**
* Called before sending an action response to the client.
*
* Use this hook to modify or transform the output of an action before it's sent
* to the client. This is useful for formatting responses, adding metadata,
* or applying transformations to the output.
*
* @param name The name of the action that was called
* @param args The arguments that were passed to the action
* @param output The output that will be sent to the client
* @returns The modified output to send to the client
*/
onBeforeActionResponse?: <Out>(c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, name: string, args: unknown[], output: Out) => Out | Promise<Out>;
/**
* Called when a raw HTTP request is made to the actor.
*
* This handler receives raw HTTP requests made to `/actors/{actorName}/http/*` endpoints.
* Use this hook to handle custom HTTP patterns, REST APIs, or other HTTP-based protocols.
*
* @param request The raw HTTP request object
* @returns A Response object to send back, or void to continue with default routing
*/
onFetch?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, request: Request, opts: {
auth: TAuthData;
}) => Response | Promise<Response>;
/**
* Called when a raw WebSocket connection is established to the actor.
*
* This handler receives WebSocket connections made to `/actors/{actorName}/websocket/*` endpoints.
* Use this hook to handle custom WebSocket protocols, binary streams, or other WebSocket-based communication.
*
* @param websocket The raw WebSocket connection
* @param request The original HTTP upgrade request
*/
onWebSocket?: (c: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase>, websocket: UniversalWebSocket, opts: {
request: Request;
auth: TAuthData;
}) => void | Promise<void>;
actions: TActions;
}
type ActorDatabaseConfig<TDatabase extends AnyDatabaseProvider> = {
/**
* @experimental
*/
db: TDatabase;
} | Record<never, never>;
type ActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase extends AnyDatabaseProvider> = Omit<z.infer<typeof ActorConfigSchema>, "actions" | "onAuth" | "onCreate" | "onStart" | "onStateChange" | "onBeforeConnect" | "onConnect" | "onDisconnect" | "onBeforeActionResponse" | "onFetch" | "onWebSocket" | "state" | "createState" | "connState" | "createConnState" | "vars" | "createVars" | "db"> & BaseActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData, TDatabase, Actions<TState, TConnParams, TConnState, TVars, TInput, T