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
107 lines (94 loc) • 2.94 kB
text/typescript
import { z } from "zod";
export const BotManagementSchema = z.object({
corporateProxy: z.boolean(),
verifiedBot: z.boolean(),
jsDetection: z.object({
passed: z.boolean(),
}),
staticResource: z.boolean(),
detectionIds: z.record(z.any()),
score: z.number(),
});
export const EnvironmentSchema = z.object({
ACTOR_KIT_SECRET: z.string(),
ACTOR_KIT_HOST: z.string(),
});
export const RequestInfoSchema = z.object({
longitude: z.string(),
latitude: z.string(),
continent: z.string(),
country: z.string(),
city: z.string(),
timezone: z.string(),
postalCode: z.string(),
region: z.string(),
regionCode: z.string(),
metroCode: z.string(),
botManagement: BotManagementSchema,
});
export const CallerSchema = z.object({
id: z.string(),
type: z.enum(["client", "system", "service"]),
});
export const AnyEventSchema = z.object({
type: z.string(),
});
export const SystemEventSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("INITIALIZE"),
caller: z.object({ type: z.literal("system"), id: z.string() }),
}),
z.object({
type: z.literal("CONNECT"),
caller: z.object({ type: z.literal("system"), id: z.string() }),
connectingCaller: CallerSchema,
}),
z.object({
type: z.literal("DISCONNECT"),
caller: z.object({ type: z.literal("system"), id: z.string() }),
disconnectingCaller: CallerSchema,
}),
z.object({
type: z.literal("RESUME"),
caller: z.object({ type: z.literal("system"), id: z.string() }),
}),
z.object({
type: z.literal("MIGRATE"),
caller: z.object({ type: z.literal("system"), id: z.string() }),
operations: z.array(z.any()),
}),
]);
export const CallerIdTypeSchema = z.enum(["client", "service", "system"]);
export const CallerStringSchema = z.string().transform((val, ctx) => {
if (val === "anonymous") {
return { type: "client" as const, id: "anonymous" };
}
const parts = val.split("-");
if (parts.length < 2) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Caller string must be in the format 'type-id' or 'anonymous'. Received '${val}'.`,
});
return z.NEVER;
}
const typeStr = parts[0];
const id = parts.slice(1).join("-"); // Rejoin in case id contains hyphens
const callerTypeParseResult = CallerIdTypeSchema.safeParse(typeStr);
if (!callerTypeParseResult.success) {
callerTypeParseResult.error.issues.forEach(ctx.addIssue);
return z.NEVER;
}
const type = callerTypeParseResult.data;
// Basic validation: Ensure the ID part is not empty
if (id.length > 0) {
return { type, id };
} else {
// If the ID part is empty, add a custom issue
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `The ID part cannot be empty after the type prefix. Received '${id}' for value '${val}'.`,
});
// Return the special NEVER symbol to indicate a validation failure
return z.NEVER;
}
});