UNPKG

actor-kit

Version:

Actor Kit is a library for running state machines in Cloudflare Workers, leveraging XState for robust state management. It provides a framework for managing the logic, lifecycle, persistence, synchronization, and access control of actors in a distributed

174 lines 7.43 kB
import { DurableObject } from "cloudflare:workers"; import { Operation } from "fast-json-patch"; import type { AnyEventObject, AnyStateMachine, SnapshotFrom, StateMachine, StateValueFrom } from "xstate"; import type { z } from "zod"; import type { AnyEventSchema, CallerSchema, RequestInfoSchema, SystemEventSchema } from "./schemas"; export type EnvWithDurableObjects = { ACTOR_KIT_SECRET: string; [key: string]: DurableObjectNamespace<ActorServer<any>> | unknown; }; export type AnyEvent = z.infer<typeof AnyEventSchema>; export interface ActorServerMethods<TMachine extends BaseActorKitStateMachine> { fetch(request: Request): Promise<Response>; spawn(props: { actorType: string; actorId: string; caller: Caller; input: Record<string, unknown>; }): void; send(event: ClientEventFrom<TMachine> | ServiceEventFrom<TMachine>): void; getSnapshot(caller: Caller, options?: { waitForEvent?: ClientEventFrom<TMachine>; waitForState?: StateValueFrom<TMachine>; timeout?: number; errorOnWaitTimeout?: boolean; }): Promise<{ checksum: string; snapshot: CallerSnapshotFrom<TMachine>; }>; } export type ActorServer<TMachine extends AnyActorKitStateMachine> = DurableObject & ActorServerMethods<TMachine>; export type AnyActorServer = ActorServer<any>; export type Caller = z.infer<typeof CallerSchema>; export type RequestInfo = z.infer<typeof RequestInfoSchema>; export type ActorKitInputProps = { id: string; caller: Caller; storage: DurableObjectStorage; [key: string]: unknown; }; export type CallerType = "client" | "system" | "service"; type EventObject = { type: string; }; type EventSchemaUnion = z.ZodDiscriminatedUnion<"type", [ z.ZodObject<z.ZodRawShape & { type: z.ZodString; }>, ...z.ZodObject<z.ZodRawShape & { type: z.ZodString; }>[] ]>; export type EventSchemas = { client: EventSchemaUnion; service: EventSchemaUnion; }; export type BaseActorKitContext<TPublicProps extends { [key: string]: unknown; }, TPrivateProps extends { [key: string]: unknown; }> = { public: TPublicProps; private: Record<string, TPrivateProps>; }; export type ActorKitStateMachine<TEvent extends BaseActorKitEvent<EnvWithDurableObjects>, TInput extends { id: string; caller: Caller; storage: DurableObjectStorage; }, TContext extends BaseActorKitContext<any, any> & { [key: string]: unknown; }> = StateMachine<TContext, TEvent & EventObject, any, any, any, any, any, any, any, TInput, any, any, any, any>; export type BaseActorKitInput<TEnv = EnvWithDurableObjects> = { id: string; caller: Caller; env: TEnv; storage: DurableObjectStorage; }; export type WithActorKitInput<TInputProps extends { [key: string]: unknown; }, TEnv extends EnvWithDurableObjects> = TInputProps & BaseActorKitInput<TEnv>; export type AnyActorKitStateMachine = ActorKitStateMachine<any, any, any>; type AnyActorKitEvent = (WithActorKitEvent<AnyEventObject, "client"> | WithActorKitEvent<AnyEventObject, "service"> | ActorKitSystemEvent) & BaseActorKitEvent<EnvWithDurableObjects>; type AnyActorKitInput = WithActorKitInput<{ [key: string]: unknown; }, EnvWithDurableObjects> & { storage: DurableObjectStorage; }; type AnyActorKitContext = { public: { [key: string]: unknown; }; private: Record<string, { [key: string]: unknown; }>; }; export type BaseActorKitStateMachine = ActorKitStateMachine<AnyActorKitEvent, AnyActorKitInput, AnyActorKitContext>; export type MachineServerOptions = { persisted?: boolean; }; export type ExtraContext = { requestId: string; }; export interface BaseActorKitEvent<TEnv extends EnvWithDurableObjects> { caller: Caller; storage: DurableObjectStorage; requestInfo?: RequestInfo; env: TEnv; } export type ActorKitSystemEvent = z.infer<typeof SystemEventSchema>; export type WithActorKitEvent<T extends { type: string; }, C extends CallerType> = T & BaseActorKitEvent<EnvWithDurableObjects> & { caller: { type: C; }; }; export type WithActorKitContext<TExtraProps extends { [key: string]: unknown; }, TPrivateProps extends { [key: string]: unknown; }, TPublicProps extends { [key: string]: unknown; }> = TExtraProps & { public: TPublicProps; private: Record<string, TPrivateProps>; }; export type CallerSnapshotFrom<TMachine extends AnyStateMachine> = { public: SnapshotFrom<TMachine> extends { context: { public: infer P; }; } ? P : unknown; private: SnapshotFrom<TMachine> extends { context: { private: Partial<Record<string, infer PR>>; }; } ? PR : unknown; value: SnapshotFrom<TMachine> extends { value: infer V; } ? V : unknown; }; export type ClientEventFrom<T extends AnyActorKitStateMachine> = T extends StateMachine<any, infer TEvent, any, any, any, any, any, any, any, any, any, any, any, any> ? TEvent extends WithActorKitEvent<infer E, "client"> ? Omit<E, keyof BaseActorKitEvent<EnvWithDurableObjects>> : never : never; export type ServiceEventFrom<T extends AnyActorKitStateMachine> = T extends StateMachine<any, infer TEvent, any, any, any, any, any, any, any, any, any, any, any, any> ? TEvent extends WithActorKitEvent<infer E, "service"> ? Omit<E, keyof BaseActorKitEvent<EnvWithDurableObjects>> : never : never; export type ScreamingSnakeToKebab<S extends string> = S extends `${infer T}_${infer U}` ? `${Lowercase<T>}-${ScreamingSnakeToKebab<U>}` : Lowercase<S>; export type DurableObjectActor<TMachine extends AnyActorKitStateMachine> = ActorServer<TMachine>; type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}` ? U extends Uncapitalize<U> ? `${Lowercase<T>}${CamelToSnakeCase<U>}` : `${Lowercase<T>}_${CamelToSnakeCase<U>}` : S; type KebabToCamelCase<S extends string> = S extends `${infer T}-${infer U}` ? `${T}${Capitalize<KebabToCamelCase<U>>}` : S; export type KebabToScreamingSnake<S extends string> = Uppercase<CamelToSnakeCase<KebabToCamelCase<S>>>; export interface MatchesProps<TMachine extends AnyActorKitStateMachine> { state: StateValueFrom<TMachine>; and?: StateValueFrom<TMachine>; or?: StateValueFrom<TMachine>; not?: boolean; initialValueOverride?: boolean; } export type MachineFromServer<T> = T extends ActorServer<infer M> ? M : never; export type ActorKitEmittedEvent = { operations: Operation[]; checksum: string; }; export type ActorKitClient<TMachine extends AnyActorKitStateMachine> = { connect: () => Promise<void>; disconnect: () => void; send: (event: ClientEventFrom<TMachine>) => void; getState: () => CallerSnapshotFrom<TMachine>; subscribe: (listener: (state: CallerSnapshotFrom<TMachine>) => void) => () => void; waitFor: (predicateFn: (state: CallerSnapshotFrom<TMachine>) => boolean, timeoutMs?: number) => Promise<void>; }; type ExtractEventType<TMachine> = TMachine extends ActorKitStateMachine<infer TEvent, any, any> ? TEvent : never; type ExtractEnvType<TEvent> = TEvent extends { env: infer TEnv; } ? TEnv : never; export type EnvFromMachine<TMachine extends AnyActorKitStateMachine> = ExtractEnvType<ExtractEventType<TMachine>> extends never ? EnvWithDurableObjects : ExtractEnvType<ExtractEventType<TMachine>> & EnvWithDurableObjects; export {}; //# sourceMappingURL=types.d.ts.map