rivetkit
Version:
Lightweight libraries for building stateful actors on edge platforms
1,335 lines (1,313 loc) • 97.1 kB
TypeScript
import { SSEStreamingApi } from 'hono/streaming';
import { WSContext } from 'hono/ws';
import { GetUpgradeWebSocket, promiseWithResolvers } from './utils.js';
import z$1, { z } from 'zod';
import { Logger } from 'pino';
import * as hono from 'hono';
import { Env, Context, Hono } from 'hono';
import * as nanoevents from 'nanoevents';
import z__default from 'zod/v4';
type uint = bigint;
type Init = {
readonly actorId: string;
readonly connectionId: string;
readonly connectionToken: string;
};
type Error$1 = {
readonly group: string;
readonly code: string;
readonly message: string;
readonly metadata: ArrayBuffer | null;
readonly actionId: uint | null;
};
type ActionResponse = {
readonly id: uint;
readonly output: ArrayBuffer;
};
type Event = {
readonly name: string;
readonly args: ArrayBuffer;
};
type ToClientBody = {
readonly tag: "Init";
readonly val: Init;
} | {
readonly tag: "Error";
readonly val: Error$1;
} | {
readonly tag: "ActionResponse";
readonly val: ActionResponse;
} | {
readonly tag: "Event";
readonly val: Event;
};
type ToClient = {
readonly body: ToClientBody;
};
type ActionRequest = {
readonly id: uint;
readonly name: string;
readonly args: ArrayBuffer;
};
type SubscriptionRequest = {
readonly eventName: string;
readonly subscribe: boolean;
};
type ToServerBody = {
readonly tag: "ActionRequest";
readonly val: ActionRequest;
} | {
readonly tag: "SubscriptionRequest";
readonly val: SubscriptionRequest;
};
type ToServer = {
readonly body: ToServerBody;
};
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;
}
declare const ActorsSchema: z.ZodRecord<z.ZodString, z.ZodType<ActorDefinition<any, any, any, any, any, any, any>, z.ZodTypeDef, ActorDefinition<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;
};
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, {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
}, {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
}>;
type DriverConfig = z.infer<typeof DriverConfigSchema>;
/** Base config used for the actor config across all platforms. */
declare const RunnerConfigSchema: z.ZodDefault<z.ZodObject<{
driver: 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, {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
}, {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
}>>;
cors: z.ZodOptional<z.ZodType<{
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}, z.ZodTypeDef, {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}>>;
maxIncomingMessageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
inspector: z.ZodDefault<z.ZodOptional<z.ZodObject<{
enabled: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
actor: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
manager: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
}, "strip", z.ZodTypeAny, {
actor: boolean;
manager: boolean;
}, {
actor?: boolean | undefined;
manager?: boolean | undefined;
}>]>>>;
cors: z.ZodDefault<z.ZodOptional<z.ZodType<{
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
}, z.ZodTypeDef, {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | 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 | {
actor: boolean;
manager: boolean;
};
cors: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
};
token: (...args: unknown[]) => string;
defaultEndpoint?: string | undefined;
}, {
enabled?: boolean | {
actor?: boolean | undefined;
manager?: boolean | undefined;
} | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
token?: ((...args: unknown[]) => string) | undefined;
defaultEndpoint?: string | undefined;
}>>>;
disableDefaultServer: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
defaultServerPort: z.ZodDefault<z.ZodNumber>;
runEngine: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
runEngineVersion: z.ZodDefault<z.ZodOptional<z.ZodString>>;
overrideServerAddress: z.ZodOptional<z.ZodString>;
disableActorDriver: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
runnerKind: z.ZodDefault<z.ZodOptional<z.ZodEnum<["serverless", "normal"]>>>;
basePath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
noWelcome: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
logging: z.ZodDefault<z.ZodOptional<z.ZodObject<{
baseLogger: z.ZodOptional<z.ZodType<Logger, z.ZodTypeDef, Logger>>;
level: z.ZodOptional<z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal", "silent"]>>;
}, "strip", z.ZodTypeAny, {
level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
baseLogger?: Logger | undefined;
}, {
level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
baseLogger?: Logger | undefined;
}>>>;
autoConfigureServerless: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
url: z.ZodOptional<z.ZodString>;
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
maxRunners: z.ZodOptional<z.ZodNumber>;
minRunners: z.ZodOptional<z.ZodNumber>;
requestLifespan: z.ZodOptional<z.ZodNumber>;
runnersMargin: z.ZodOptional<z.ZodNumber>;
slotsPerRunner: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
headers?: Record<string, string> | undefined;
url?: string | undefined;
maxRunners?: number | undefined;
minRunners?: number | undefined;
requestLifespan?: number | undefined;
runnersMargin?: number | undefined;
slotsPerRunner?: number | undefined;
}, {
headers?: Record<string, string> | undefined;
url?: string | undefined;
maxRunners?: number | undefined;
minRunners?: number | undefined;
requestLifespan?: number | undefined;
runnersMargin?: number | undefined;
slotsPerRunner?: number | undefined;
}>]>>;
} & {
runnerKey: z.ZodDefault<z.ZodString>;
totalSlots: z.ZodDefault<z.ZodNumber>;
endpoint: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
token: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
namespace: z.ZodDefault<z.ZodString>;
runnerName: z.ZodDefault<z.ZodString>;
encoding: z.ZodDefault<z.ZodEnum<["json", "cbor", "bare"]>>;
transport: z.ZodDefault<z.ZodEnum<["websocket", "sse"]>>;
headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
getUpgradeWebSocket: z.ZodOptional<z.ZodType<GetUpgradeWebSocket, z.ZodTypeDef, GetUpgradeWebSocket>>;
}, "strip", z.ZodTypeAny, {
encoding: "json" | "cbor" | "bare";
inspector: {
enabled: boolean | {
actor: boolean;
manager: boolean;
};
cors: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
};
token: (...args: unknown[]) => string;
defaultEndpoint?: string | undefined;
};
namespace: string;
runnerName: string;
transport: "websocket" | "sse";
headers: Record<string, string>;
runnerKey: string;
totalSlots: number;
maxIncomingMessageSize: number;
disableDefaultServer: boolean;
defaultServerPort: number;
runEngine: boolean;
runEngineVersion: string;
disableActorDriver: boolean;
runnerKind: "serverless" | "normal";
basePath: string;
noWelcome: boolean;
logging: {
level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
baseLogger?: Logger | undefined;
};
driver?: {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
} | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
endpoint?: string | undefined;
token?: string | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
overrideServerAddress?: string | undefined;
autoConfigureServerless?: boolean | {
headers?: Record<string, string> | undefined;
url?: string | undefined;
maxRunners?: number | undefined;
minRunners?: number | undefined;
requestLifespan?: number | undefined;
runnersMargin?: number | undefined;
slotsPerRunner?: number | undefined;
} | undefined;
}, {
encoding?: "json" | "cbor" | "bare" | undefined;
driver?: {
actor: ActorDriverBuilder;
name: string;
manager: ManagerDriverBuilder;
} | undefined;
inspector?: {
enabled?: boolean | {
actor?: boolean | undefined;
manager?: boolean | undefined;
} | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
token?: ((...args: unknown[]) => string) | undefined;
defaultEndpoint?: string | undefined;
} | undefined;
cors?: {
origin: string | string[] | ((origin: string, c: hono.Context) => Promise<string | undefined | null> | string | undefined | null);
allowMethods?: string[] | ((origin: string, c: hono.Context) => Promise<string[]> | string[]);
allowHeaders?: string[];
maxAge?: number;
credentials?: boolean;
exposeHeaders?: string[];
} | undefined;
endpoint?: string | undefined;
token?: string | undefined;
namespace?: string | undefined;
runnerName?: string | undefined;
transport?: "websocket" | "sse" | undefined;
headers?: Record<string, string> | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
runnerKey?: string | undefined;
totalSlots?: number | undefined;
maxIncomingMessageSize?: number | undefined;
disableDefaultServer?: boolean | undefined;
defaultServerPort?: number | undefined;
runEngine?: boolean | undefined;
runEngineVersion?: string | undefined;
overrideServerAddress?: string | undefined;
disableActorDriver?: boolean | undefined;
runnerKind?: "serverless" | "normal" | undefined;
basePath?: string | undefined;
noWelcome?: boolean | undefined;
logging?: {
level?: "error" | "trace" | "fatal" | "warn" | "info" | "debug" | "silent" | undefined;
baseLogger?: Logger | undefined;
} | undefined;
autoConfigureServerless?: boolean | {
headers?: Record<string, string> | undefined;
url?: string | undefined;
maxRunners?: number | undefined;
minRunners?: number | undefined;
requestLifespan?: number | undefined;
runnersMargin?: number | undefined;
slotsPerRunner?: number | undefined;
} | undefined;
}>>;
type RunnerConfig = z.infer<typeof RunnerConfigSchema>;
type RunnerConfigInput = z.input<typeof RunnerConfigSchema>;
type ManagerDriverBuilder = (registryConfig: RegistryConfig, runConfig: RunnerConfig) => 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, connId?: string, connToken?: string): Promise<UniversalWebSocket>;
proxyRequest(c: Context, actorRequest: Request, actorId: string): Promise<Response>;
proxyWebSocket(c: Context, path: string, actorId: string, encoding: Encoding, params: unknown, connId?: string, connToken?: string): Promise<Response>;
displayInformation(): ManagerDisplayInformation;
extraStartupLog?: () => Record<string, unknown>;
modifyManagerRouter?: (registryConfig: RegistryConfig, router: Hono) => void;
/**
* Get or create the inspector access token.
* @experimental
* @returns creates or returns existing inspector access token
*/
getOrCreateInspectorAccessToken: () => string;
}
interface ManagerDisplayInformation {
name: string;
properties: Record<string, string>;
}
interface GetForIdInput<E extends Env = any> {
c?: Context | undefined;
name: string;
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 ActorDriverBuilder = (registryConfig: RegistryConfig, runConfig: RunnerConfig, managerDriver: ManagerDriver, inlineClient: AnyClient) => ActorDriver;
interface ActorDriver {
loadActor(actorId: string): Promise<AnyActorInstance>;
getContext(actorId: string): unknown;
readPersistedData(actorId: string): Promise<Uint8Array | undefined>;
/** ActorInstance ensure that only one instance of writePersistedData is called in parallel at a time. */
writePersistedData(actorId: string, data: Uint8Array): Promise<void>;
/** ActorInstance ensure that only one instance of setAlarm is called in parallel at a time. */
setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void>;
/**
* @experimental
* This is an experimental API that may change in the future.
*/
getDatabase(actorId: string): Promise<unknown | undefined>;
sleep?(actorId: string): Promise<void>;
shutdown?(immediate: boolean): Promise<void>;
/** This handles the serverless start request. This should manage the lifecycle of the runner tied to the request lifecycle. */
serverlessHandleStart?(c: Context): Promise<Response>;
}
type ServerlessActorDriverBuilder = (updateConfig: (config: RunnerConfig) => void) => ActorDriver;
interface ServerOutput<A extends Registry<any>> {
/** Client to communicate with the actors. */
client: Client<A>;
/** Fetch handler to manually route requests to the Rivet manager API. */
fetch: (request: Request, ...args: any) => Response | Promise<Response>;
}
declare class Registry<A extends RegistryActors> {
#private;
get config(): RegistryConfig;
constructor(config: RegistryConfig);
/**
* Runs the registry for a server.
*/
start(inputConfig?: RunnerConfigInput): ServerOutput<this>;
}
declare function setup<A extends RegistryActors>(input: RegistryConfigInput<A>): Registry<A>;
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>;
};
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>;
}
/**
* ActorContext class that provides access to actor methods and state
*/
declare class ActorContext<TState, TConnParams, TConnState, TVars, TInput, TDatabase extends AnyDatabaseProvider> {
#private;
constructor(actor: ActorInstance<TState, TConnParams, TConnState, TVars, TInput, 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, 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>;
/**
* Prevents the actor from sleeping until promise is complete.
*/
waitUntil(promise: Promise<void>): void;
/**
* AbortSignal that fires when the actor is stopping.
*/
get abortSignal(): AbortSignal;
/**
* Forces the actor to sleep.
*
* Not supported on all drivers.
*
* @experimental
*/
sleep(): void;
}
type AnyActorDefinition = ActorDefinition<any, any, any, any, any, any, any>;
/**
* Extracts the context type from an ActorDefinition
*/
type ActorContextOf<AD extends AnyActorDefinition> = AD extends ActorDefinition<infer S, infer CP, infer CS, infer V, infer I, infer DB, any> ? ActorContext<S, CP, CS, V, I, DB> : never;
/**
* Extracts the context type from an ActorDefinition
*/
type ActionContextOf<AD extends AnyActorDefinition> = AD extends ActorDefinition<infer S, infer CP, infer CS, infer V, infer I, infer DB, any> ? ActionContext<S, CP, CS, V, I, DB> : never;
declare class ActorDefinition<S, CP, CS, V, I, DB extends AnyDatabaseProvider, R extends Actions<S, CP, CS, V, I, DB>> {
#private;
constructor(config: ActorConfig<S, CP, CS, V, I, DB>);
get config(): ActorConfig<S, CP, CS, V, I, DB>;
instantiate(): ActorInstance<S, CP, CS, V, I, DB>;
}
declare function lookupInRegistry(registryConfig: RegistryConfig, name: string): AnyActorDefinition;
type MigrationFn<TFrom, TTo> = (data: TFrom) => TTo;
interface VersionedDataConfig<T> {
currentVersion: number;
migrations: Map<number, MigrationFn<any, any>>;
serializeVersion: (data: T) => Uint8Array;
deserializeVersion: (bytes: Uint8Array) => T;
}
declare class VersionedDataHandler<T> {
private config;
constructor(config: VersionedDataConfig<T>);
serializeWithEmbeddedVersion(data: T): Uint8Array;
deserializeWithEmbeddedVersion(bytes: Uint8Array): T;
serialize(data: T, version: number): Uint8Array;
deserialize(bytes: Uint8Array, version: number): T;
private embedVersion;
private extractVersion;
}
/** Data that's been serialized. */
type OutputData = string | Uint8Array;
declare const EncodingSchema: z.ZodEnum<["json", "cbor", "bare"]>;
/**
* 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, versionedDataHandler: VersionedDataHandler<T>);
get rawData(): T;
serialize(encoding: Encoding): OutputData;
}
declare const TransportSchema: z.ZodEnum<["websocket", "sse"]>;
/**
* Transport mechanism used to communicate between client & actor.
*/
type Transport = z.infer<typeof TransportSchema>;
declare const ActorKeySchema: z.ZodArray<z.ZodString, "many">;
type ActorKey = z.infer<typeof ActorKeySchema>;
declare const CreateRequestSchema: z.ZodObject<{
name: z.ZodString;
key: z.ZodArray<z.ZodString, "many">;
input: z.ZodOptional<z.ZodUnknown>;
region: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}>;
declare const ActorQuerySchema: z.ZodUnion<[z.ZodObject<{
getForId: z.ZodObject<{
name: z.ZodString;
actorId: z.ZodString;
}, "strip", z.ZodTypeAny, {
name: string;
actorId: string;
}, {
name: string;
actorId: string;
}>;
}, "strip", z.ZodTypeAny, {
getForId: {
name: string;
actorId: string;
};
}, {
getForId: {
name: string;
actorId: string;
};
}>, z.ZodObject<{
getForKey: z.ZodObject<{
name: z.ZodString;
key: z.ZodArray<z.ZodString, "many">;
}, "strip", z.ZodTypeAny, {
key: string[];
name: string;
}, {
key: string[];
name: string;
}>;
}, "strip", z.ZodTypeAny, {
getForKey: {
key: string[];
name: string;
};
}, {
getForKey: {
key: string[];
name: string;
};
}>, z.ZodObject<{
getOrCreateForKey: z.ZodObject<{
name: z.ZodString;
key: z.ZodArray<z.ZodString, "many">;
input: z.ZodOptional<z.ZodUnknown>;
region: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}>;
}, "strip", z.ZodTypeAny, {
getOrCreateForKey: {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
};
}, {
getOrCreateForKey: {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
};
}>, z.ZodObject<{
create: z.ZodObject<{
name: z.ZodString;
key: z.ZodArray<z.ZodString, "many">;
input: z.ZodOptional<z.ZodUnknown>;
region: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}, {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
}>;
}, "strip", z.ZodTypeAny, {
create: {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
};
}, {
create: {
key: string[];
name: string;
input?: unknown;
region?: string | undefined;
};
}>]>;
type ActorQuery = z.infer<typeof ActorQuerySchema>;
/**
* Interface representing a request to create a actor.
*/
type CreateRequest = z.infer<typeof CreateRequestSchema>;
/**
* Action function returned by Actor connections and handles.
*
* @typedef {Function} ActorActionFunction
* @template Args
* @template Response
* @param {...Args} args - Arguments for the action function.
* @returns {Promise<Response>}
*/
type ActorActionFunction<Args extends Array<unknown> = unknown[], Response = unknown> = (...args: Args extends [unknown, ...infer Rest] ? Rest : Args) => Promise<Response>;
/**
* Maps action methods from actor definition to typed function signatures.
*/
type ActorDefinitionActions<AD extends AnyActorDefinition> = AD extends ActorDefinition<any, any, any, any, any, any, infer R> ? {
[K in keyof R]: R[K] extends (...args: infer Args) => infer Return ? ActorActionFunction<Args, Return> : never;
} : never;
declare class ActorClientError extends Error {
}
declare class InternalError extends ActorClientError {
}
declare class ManagerError extends ActorClientError {
constructor(error: string, opts?: ErrorOptions);
}
declare class MalformedResponseMessage extends ActorClientError {
constructor(cause?: unknown);
}
declare class ActorError extends ActorClientError {
readonly group: string;
readonly code: string;
readonly metadata?: unknown | undefined;
__type: string;
constructor(group: string, code: string, message: string, metadata?: unknown | undefined);
}
/**
* A function that unsubscribes from an event.
*
* @typedef {Function} EventUnsubscribe
*/
type EventUnsubscribe = () => void;
/**
* A function that handles connection errors.
*
* @typedef {Function} ActorErrorCallback
*/
type ActorErrorCallback = (error: ActorError) => void;
declare const CONNECT_SYMBOL: unique symbol;
/**
* Provides underlying functions for {@link ActorConn}. See {@link ActorConn} for using type-safe remote procedure calls.
*
* @see {@link ActorConn}
*/
declare class ActorConnRaw {
#private;
/**
* Do not call this directly.
*
* Creates an instance of ActorConnRaw.
*
* @protected
*/
constructor(client: ClientRaw, driver: ManagerDriver, params: unknown, encoding: Encoding, actorQuery: ActorQuery);
/**
* Call a raw action connection. See {@link ActorConn} for type-safe action calls.
*
* @see {@link ActorConn}
* @template Args - The type of arguments to pass to the action function.
* @template Response - The type of the response returned by the action function.
* @param {string} name - The name of the action function to call.
* @param {...Args} args - The arguments to pass to the action function.
* @returns {Promise<Response>} - A promise that resolves to the response of the action function.
*/
action<Args extends Array<unknown> = unknown[], Response = unknown>(opts: {
name: string;
args: Args;
signal?: AbortSignal;
}): Promise<Response>;
/**
* Do not call this directly.
enc
* Establishes a connection to the server using the specified endpoint & encoding & driver.
*
* @protected
*/
[CONNECT_SYMBOL](): void;
/**
* Subscribes to an event that will happen repeatedly.
*
* @template Args - The type of arguments the event callback will receive.
* @param {string} eventName - The name of the event to subscribe to.
* @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.
* @returns {EventUnsubscribe} - A function to unsubscribe from the event.
* @see {@link https://rivet.dev/docs/events|Events Documentation}
*/
on<Args extends Array<unknown> = unknown[]>(eventName: string, callback: (...args: Args) => void): EventUnsubscribe;
/**
* Subscribes to an event that will be triggered only once.
*
* @template Args - The type of arguments the event callback will receive.
* @param {string} eventName - The name of the event to subscribe to.
* @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.
* @returns {EventUnsubscribe} - A function to unsubscribe from the event.
* @see {@link https://rivet.dev/docs/events|Events Documentation}
*/
once<Args extends Array<unknown> = unknown[]>(eventName: string, callback: (...args: Args) => void): EventUnsubscribe;
/**
* Subscribes to connection errors.
*
* @param {ActorErrorCallback} callback - The callback function to execute when a connection error occurs.
* @returns {() => void} - A function to unsubscribe from the error handler.
*/
onError(callback: ActorErrorCallback): () => void;
/**
* Disconnects from the actor.
*
* @returns {Promise<void>} A promise that resolves when the socket is gracefully closed.
*/
dispose(): Promise<void>;
}
/**
* Connection to a actor. Allows calling actor's remote procedure calls with inferred types. See {@link ActorConnRaw} for underlying methods.
*
* @example
* ```
* const room = client.connect<ChatRoom>(...etc...);
* // This calls the action named `sendMessage` on the `ChatRoom` actor.
* await room.sendMessage('Hello, world!');
* ```
*
* Private methods (e.g. those starting with `_`) are automatically excluded.
*
* @template AD The actor class that this connection is for.
* @see {@link ActorConnRaw}
*/
type ActorConn<AD extends AnyActorDefinition> = ActorConnRaw & ActorDefinitionActions<AD>;
/**
* Provides underlying functions for stateless {@link ActorHandle} for action calls.
* Similar to ActorConnRaw but doesn't maintain a connection.
*
* @see {@link ActorHandle}
*/
declare class ActorHandleRaw {
#private;
/**
* Do not call this directly.
*
* Creates an instance of ActorHandleRaw.
*
* @protected
*/
constructor(client: any, driver: ManagerDriver, params: unknown, encoding: Encoding, actorQuery: ActorQuery);
/**
* Call a raw action. This method sends an HTTP request to invoke the named action.
*
* @see {@link ActorHandle}
* @template Args - The type of arguments to pass to the action function.
* @template Response - The type of the response returned by the action function.
*/
action<Args extends Array<unknown> = unknown[], Response = unknown>(opts: {
name: string;
args: Args;
signal?: AbortSignal;
}): Promise<Response>;
/**
* Establishes a persistent connection to the actor.
*
* @template AD The actor class that this connection is for.
* @returns {ActorConn<AD>} A connection to the actor.
*/
connect(): ActorConn<AnyActorDefinition>;
/**
* Makes a raw HTTP request to the actor.
*
* @param input - The URL, path, or Request object
* @param init - Standard fetch RequestInit options
* @returns Promise<Response> - The raw HTTP response
*/
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
/**
* Creates a raw WebSocket connection to the actor.
*
* @param path - The path for the WebSocket connection (e.g., "stream")
* @param protocols - Optional WebSocket subprotocols
* @returns WebSocket - A raw WebSocket connection
*/
websocket(path?: string, protocols?: string | string[]): Promise<WebSocket>;
/**
* Resolves the actor to get its unique actor ID
*
* @returns {Promise<string>} - A promise that resolves to the actor's ID
*/
resolve({ signal }?: {
signal?: AbortSignal;
}): Promise<string>;
}
/**
* Stateless handle to a actor. Allows calling actor's remote procedure calls with inferred types
* without establishing a persistent connection.
*
* @example
* ```
* const room = client.get<ChatRoom>(...etc...);
* // This calls the action named `sendMessage` on the `ChatRoom` actor without a connection.
* await room.sendMessage('Hello, world!');
* ```
*
* Private methods (e.g. those starting with `_`) are automatically excluded.
*
* @template AD The actor class that this handle is for.
* @see {@link ActorHandleRaw}
*/
type ActorHandle<AD extends AnyActorDefinition> = Omit<ActorHandleRaw, "connect"> & {
connect(): ActorConn<AD>;
resolve(): Promise<string>;
} & ActorDefinitionActions<AD>;
declare const ClientConfigSchema: z$1.ZodObject<{
/** Endpoint to connect to for Rivet Engine or RivetKit manager API. */
endpoint: z$1.ZodEffects<z$1.ZodOptional<z$1.ZodString>, string | undefined, string | undefined>;
/** Token to use to authenticate with the API. */
token: z$1.ZodEffects<z$1.ZodOptional<z$1.ZodString>, string | undefined, string | undefined>;
/** Namespace to connect to. */
namespace: z$1.ZodDefault<z$1.ZodString>;
/** Name of the runner. This is used to group together runners in to different pools. */
runnerName: z$1.ZodDefault<z$1.ZodString>;
encoding: z$1.ZodDefault<z$1.ZodEnum<["json", "cbor", "bare"]>>;
transport: z$1.ZodDefault<z$1.ZodEnum<["websocket", "sse"]>>;
headers: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodString>>>;
getUpgradeWebSocket: z$1.ZodOptional<z$1.ZodType<GetUpgradeWebSocket, z$1.ZodTypeDef, GetUpgradeWebSocket>>;
}, "strip", z$1.ZodTypeAny, {
encoding: "json" | "cbor" | "bare";
namespace: string;
runnerName: string;
transport: "websocket" | "sse";
headers: Record<string, string>;
endpoint?: string | undefined;
token?: string | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
}, {
encoding?: "json" | "cbor" | "bare" | undefined;
endpoint?: string | undefined;
token?: string | undefined;
namespace?: string | undefined;
runnerName?: string | undefined;
transport?: "websocket" | "sse" | undefined;
headers?: Record<string, string> | undefined;
getUpgradeWebSocket?: GetUpgradeWebSocket | undefined;
}>;
type ClientConfig = z$1.infer<typeof ClientConfigSchema>;
type ClientConfigInput = z$1.input<typeof ClientConfigSchema>;
/** Extract the actor registry from the registry definition. */
type ExtractActorsFromRegistry<A extends Registry<any>> = A extends Registry<infer Actors> ? Actors : never;
/** Extract the registry definition from the client. */
type ExtractRegistryFromClient<C extends Client<Registry<{}>>> = C extends Client<infer A> ? A : never;
/**
* Represents a actor accessor that provides methods to interact with a specific actor.
*/
interface ActorAccessor<AD extends AnyActorDefinition> {
/**
* Gets a stateless handle to a actor by its key, but does not create the actor if it doesn't exist.
* The actor name is automatically injected from the property accessor.
*
* @template AD The actor class that this handle is for.
* @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
* @param {GetWithIdOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
get(key?: string | string[], opts?: GetWithIdOptions): ActorHandle<AD>;
/**
* Gets a stateless handle to a actor by its key, creating it if necessary.
* The actor name is automatically injected from the property accessor.
*
* @template AD The actor class that this handle is for.
* @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
* @param {GetOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
getOrCreate(key?: string | string[], opts?: GetOrCreateOptions): ActorHandle<AD>;
/**
* Gets a stateless handle to a actor by its ID.
*
* @template AD The actor class that this handle is for.
* @param {string} actorId - The ID of the actor.
* @param {GetWithIdOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
getForId(actorId: string, opts?: GetWithIdOptions): ActorHandle<AD>;
/**
* Creates a new actor with the name automatically injected from the property accessor,
* and returns a stateless handle to it with the actor ID resolved.
*
* @template AD The actor class that this handle is for.
* @param {string | string[]} key - The key to identify the actor. Can be a single string or an array of strings.
* @param {CreateOptions} [opts] - Options for creating the actor (excluding name and key).
* @returns {Promise<ActorHandle<AD>>} - A promise that resolves to a handle to the actor.
*/
create(key?: string | string[], opts?: CreateOptions): Promise<ActorHandle<AD>>;
}
/**
* Options for querying actors.
* @typedef {Object} QueryOptions
* @property {unknown} [parameters] - Parameters to pass to the connection.
*/
interface QueryOptions {
/** Parameters to pass to the connection. */
params?: unknown;
/** Signal to abort the request. */
signal?: AbortSignal;
}
/**
* Options for getting a actor by ID.
* @typedef {QueryOptions} GetWithIdOptions
*/
interface GetWithIdOptions extends QueryOptions {
}
/**
* Options for getting a actor.
* @typedef {QueryOptions} GetOptions
*/
interface GetOptions extends QueryOptions {
}
/**
* Options for getting or creating a actor.
* @typedef {QueryOptions} GetOrCreateOptions
* @property {string} [createInRegion] - Region to create the actor in if it doesn't exist.
*/
interface GetOrCreateOptions extends QueryOptions {
/** Region to create the actor in if it doesn't exist. */
createInRegion?: string;
/** Input data to pass to the actor. */
createWithInput?: unknown;
}
/**
* Options for creating a actor.
* @typedef {QueryOptions} CreateOptions
* @property {string} [region] - The region to create the actor in.
*/
interface CreateOptions extends QueryOptions {
/** The region to create the actor in. */
region?: string;
/** Input data to pass to the actor. */
input?: unknown;
}
/**
* Represents a region to connect to.
* @typedef {Object} Region
* @property {string} id - The region ID.
* @property {string} name - The region name.
* @see {@link https://rivet.dev/docs/edge|Edge Networking}
* @see {@link https://rivet.dev/docs/regions|Available Regions}
*/
interface Region {
/**
* The region slug.
*/
id: string;
/**
* The human-friendly region name.
*/
name: string;
}
declare const ACTOR_CONNS_SYMBOL: unique symbol;
declare const CREATE_ACTOR_CONN_PROXY: unique symbol;
declare const TRANSPORT_SYMBOL: unique symbol;
/**
* Client for managing & connecting to actors.
*
* @template A The actors map type that defines the available actors.
* @see {@link https://rivet.dev/docs/manage|Create & Manage Actors}
*/
declare class ClientRaw {
#private;
[ACTOR_CONNS_SYMBOL]: Set<ActorConnRaw>;
[TRANSPORT_SYMBOL]: Transport;
/**
* Creates an instance of Client.
*
* @param {string} managerEndpoint - The manager endpoint. See {@link https://rivet.dev/docs/setup|Initial Setup} for instructions on getting the manager endpoint.
* @param {ClientConfig} [opts] - Options for configuring the client.
* @see {@link https://rivet.dev/docs/setup|Initial Setup}
*/
constructor(driver: ManagerDriver, opts?: ClientConfig);
/**
* Gets a stateless handle to a actor by its ID.
*
* @template AD The actor class that this handle is for.
* @param {string} name - The name of the actor.
* @param {string} actorId - The ID of the actor.
* @param {GetWithIdOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
getForId<AD extends AnyActorDefinition>(name: string, actorId: string, opts?: GetWithIdOptions): ActorHandle<AD>;
/**
* Gets a stateless handle to a actor by its key, but does not create the actor if it doesn't exist.
*
* @template AD The actor class that this handle is for.
* @param {string} name - The name of the actor.
* @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
* @param {GetWithIdOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
get<AD extends AnyActorDefinition>(name: string, key?: string | string[], opts?: GetWithIdOptions): ActorHandle<AD>;
/**
* Gets a stateless handle to a actor by its key, creating it if necessary.
*
* @template AD The actor class that this handle is for.
* @param {string} name - The name of the actor.
* @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
* @param {GetOptions} [opts] - Options for getting the actor.
* @returns {ActorHandle<AD>} - A handle to the actor.
*/
getOrCreate<AD extends AnyActorDefinition>(name: string, key?: string | string[], opts?: GetOrCreateOptions): ActorHandle<AD>;
/**
* Creates a new actor with the provided key and returns a stateless handle to it.
* Resolves the actor ID and returns a handle with getForId query.
*
* @template AD The actor class that this handle is for.
* @param {string} name - The name of the actor.
* @param {string | string[]} key - The key to identify the actor. Can be a single string or an array of strings.
* @param {CreateOptions} [opts] - Options for creating the actor (excluding name and key).
* @returns {Promise<ActorHandle<AD>>} - A promise that resolves to a handle to the actor.
*/
create<AD extends AnyActorDefinition>(name: string, key?: string | string[], opts?: CreateOptions): Promise<ActorHandle<AD>>;
[CREATE_ACTOR_CONN_PROXY]<AD extends AnyActorDefinition>(conn: ActorConnRaw): ActorConn<AD>;
/**
* Disconnects from all actors.
*
* @returns {Promise<void>} A promise that resolves when all connections are closed.
*/
dispose(): Promise<void>;
}
/**
* Client type with actor accessors.
* This adds property accessors for actor names to the ClientRaw base class.
*
* @template A The actor registry type.
*/
type Client<A extends Registry<any>> = ClientRaw & {
[K in keyof ExtractActorsFromRegistry<A>]: ActorAccessor<ExtractActorsFromRegistry<A>[K]>;
};
type AnyClient = Client<Registry<any>>;
declare function createClientWithDriver<A extends Registry<any>>(driver: ManagerDriver, config?: ClientConfig): Client<A>;
/**
* Context for a remote procedure call.
*
* @typeParam A Actor this action belongs to
*/
declare class ActionContext<TState, TConnParams, TConnState, TVars, TInput, TDatabase extends AnyDatabaseProvider> {
#private;
readonly conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase>;
/**
* Should not be called directly.
*
* @param actorContext - The actor context
* @param conn - The connection associated with the action
*/
constructor(actorContext: ActorContext<TState, TConnParams, TConnState, TVars, TInput, TDatabase>, conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase>);
/**
* Get the actor state
*/
get state(): TState;
/**
* Get the actor variables
*/
get vars(): TVars;
/**
* Broadcasts an event to all connected clients.
*/
broadcast(name: string, ...args: any[]): 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, TDatabase>>;
/**
* Returns the client for the given registry.
*/
client<R extends Registry<any>>(): Client<R>;
/**
* @experimental
*/
get db(): InferDatabaseClient<TDatabase>;
/**
* Forces the state to get saved.
*/
saveState(opts: SaveStateOptions): Promise<void>;
/**
* Prevents the actor from sleeping until promise is