@beignet/core
Version:
Core framework primitives for Beignet
426 lines • 12.4 kB
TypeScript
import type { StandardSchemaV1 } from "@standard-schema/spec";
import { type ProviderInstrumentationTarget } from "../providers/index.js";
import type { TracingPort } from "../tracing/index.js";
/**
* Any Standard Schema compatible validator.
*/
export type StandardSchema = StandardSchemaV1<unknown, unknown>;
/**
* Value or promise of that value.
*/
export type MaybePromise<T> = T | Promise<T>;
/**
* Infer the parsed output type from a Standard Schema.
*/
export type InferSchemaOutput<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
/**
* Date input accepted by schedule runners.
*/
export type ScheduleDateInput = Date | string | number;
/**
* Metadata for one schedule run.
*/
export interface ScheduleRunContext {
/**
* Optional provider run ID.
*/
readonly id?: string;
/**
* One-based provider attempt number for this run, when available.
*/
readonly attempt?: number;
/**
* Time the provider planned the run.
*/
readonly scheduledAt?: Date;
/**
* Time the runner triggered this execution.
*/
readonly triggeredAt: Date;
/**
* Optional provider or app source label.
*/
readonly source?: string;
}
/**
* Minimal schedule definition shape accepted by schedule helpers.
*/
export interface SchedulePayloadDef<Name extends string = string, Payload extends StandardSchema = StandardSchema> {
/**
* Stable schedule name.
*/
readonly name: Name;
/**
* Standard Schema payload validator.
*/
readonly payload: Payload;
}
/**
* Schedule definition created by `defineSchedule(...)`.
*/
export interface ScheduleDef<Name extends string = string, Payload extends StandardSchema = StandardSchema, Ctx = unknown> extends SchedulePayloadDef<Name, Payload> {
/**
* Discriminator for schedule definitions.
*/
readonly kind: "schedule";
/**
* Cron expression consumed by schedule providers.
*/
readonly cron: string;
/**
* Optional IANA timezone consumed by schedule providers.
*/
readonly timezone?: string;
/**
* Optional human-readable description for docs and tooling.
*/
readonly description?: string;
/**
* Build a payload when the provider does not supply one.
*/
createPayload?(args: ScheduleCreatePayloadArgs<ScheduleDef<Name, Payload, Ctx>>): MaybePromise<InferSchemaOutput<Payload>>;
/**
* Handle a parsed schedule payload.
*/
handle(args: ScheduleHandleArgs<ScheduleDef<Name, Payload, Ctx>, Ctx>): MaybePromise<void>;
}
/**
* Infer the parsed payload type for a schedule definition.
*/
export type InferSchedulePayload<S extends SchedulePayloadDef> = S["payload"] extends StandardSchemaV1<unknown, infer Output> ? Output : never;
/**
* Arguments passed to a schedule `createPayload` callback.
*/
export interface ScheduleCreatePayloadArgs<S extends SchedulePayloadDef> {
/**
* Schedule definition being run.
*/
schedule: S;
/**
* Run metadata.
*/
run: ScheduleRunContext;
}
/**
* Arguments passed to a schedule handler.
*/
export interface ScheduleHandleArgs<S extends ScheduleDef, Ctx> {
/**
* Schedule definition being handled.
*/
schedule: S;
/**
* Parsed schedule payload.
*/
payload: InferSchedulePayload<S>;
/** Handler context. */
ctx: Ctx;
/**
* Run metadata.
*/
run: ScheduleRunContext;
}
/**
* Options for `defineSchedule(...)`.
*/
export interface DefineScheduleOptions<Name extends string, Payload extends StandardSchema, Ctx> {
/**
* Cron expression consumed by schedule providers.
*/
cron: string;
/**
* Optional IANA timezone consumed by schedule providers.
*/
timezone?: string;
/**
* Standard Schema payload validator.
*/
payload: Payload;
/**
* Optional human-readable description for docs and tooling.
*/
description?: string;
/**
* Build a payload when the provider does not supply one.
*/
createPayload?(args: ScheduleCreatePayloadArgs<ScheduleDef<Name, Payload, Ctx>>): MaybePromise<InferSchemaOutput<Payload>>;
/**
* Handle a parsed schedule payload.
*/
handle(args: ScheduleHandleArgs<ScheduleDef<Name, Payload, Ctx>, Ctx>): MaybePromise<void>;
}
/**
* Options for one manual schedule run.
*/
export interface ScheduleRunOptions<Payload = unknown> {
/**
* Payload supplied by the provider or manual runner.
*/
payload?: Payload;
/**
* Optional provider run ID.
*/
id?: string;
/**
* One-based provider attempt number for this run, when available.
*/
attempt?: number;
/**
* Time the provider planned the run.
*/
scheduledAt?: ScheduleDateInput;
/**
* Time the runner triggered the execution.
*/
triggeredAt?: ScheduleDateInput;
/**
* Optional provider or app source label.
*/
source?: string;
}
/**
* Arguments for `runSchedule(...)`.
*/
export type ScheduleRunArgs<Ctx, Payload = unknown> = ScheduleRunOptions<Payload> & {
/** Handler context or factory resolved inside the schedule span. */
ctx: Ctx | (() => MaybePromise<Ctx>);
/** Runtime tracing port used before a lazy context factory runs. */
tracing?: TracingPort;
};
/**
* Arguments passed to schedule lifecycle hooks.
*/
export interface ScheduleLifecycleArgs<S extends ScheduleDef = ScheduleDef> {
/**
* Schedule definition being run.
*/
schedule: S;
/**
* Parsed schedule payload.
*/
payload: InferSchedulePayload<S>;
/**
* Run metadata.
*/
run: ScheduleRunContext;
}
/**
* Arguments passed to a schedule error hook.
*/
export interface ScheduleErrorArgs<S extends ScheduleDef = ScheduleDef> {
/**
* Schedule definition being run.
*/
schedule: S;
/**
* Parsed payload when validation or payload creation completed.
*/
payload?: InferSchedulePayload<S>;
/**
* Run metadata.
*/
run: ScheduleRunContext;
/**
* Error thrown by payload creation, validation, or the handler.
*/
error: unknown;
}
/**
* Schedule lifecycle hook names.
*/
export type ScheduleHookName = "start" | "success" | "error";
/**
* Devtools event recorded by the inline schedule runner for each run.
*/
export interface ScheduleDevtoolsEvent {
/**
* Devtools event type.
*/
type: "schedule";
/**
* Watcher category used by devtools.
*/
watcher: "schedules";
/**
* Stable schedule name.
*/
scheduleName: string;
/**
* Schedule run lifecycle status.
*/
status: "started" | "completed" | "failed";
/**
* Cron expression for the schedule.
*/
cron: string;
/**
* IANA timezone for the schedule, when declared.
*/
timezone?: string;
/**
* Request correlation ID, when the trigger ran inside a request.
*/
requestId?: string;
/**
* Trace identifier for distributed tracing integrations.
*/
traceId?: string;
/**
* Structured run details such as `source`, `scheduledAt`, and `error`.
*/
details?: Record<string, unknown>;
}
/**
* Correlation fields attached to schedule instrumentation events.
*/
export interface ScheduleInstrumentationContext {
/**
* Request correlation ID for the triggering invocation.
*/
requestId?: string;
/**
* Trace identifier for the triggering invocation.
*/
traceId?: string;
}
/**
* Arguments passed when a schedule lifecycle hook itself fails.
*/
export interface ScheduleHookErrorArgs<S extends ScheduleDef = ScheduleDef> {
/**
* Schedule definition being run.
*/
schedule: S;
/**
* Parsed payload when available.
*/
payload?: InferSchedulePayload<S>;
/**
* Run metadata.
*/
run: ScheduleRunContext;
/**
* Lifecycle hook that failed.
*/
hook: ScheduleHookName;
/**
* Hook error.
*/
error: unknown;
/**
* Original schedule error when the failing hook is `onError`.
*/
scheduleError?: unknown;
}
/**
* Options for the inline schedule runner.
*/
export interface InlineScheduleRunnerOptions<Ctx> {
/**
* Static schedule context or factory evaluated for each run.
*/
ctx?: Ctx | (() => MaybePromise<Ctx>);
/** Runtime tracing port used before a lazy context factory runs. */
tracing?: TracingPort;
/**
* Clock used when run timestamps are not provided.
*/
now?: () => Date;
/**
* Provider instrumentation target that receives `schedule` events for each
* run. Pass `ctx.ports`, `ctx.ports.instrumentation`, or
* `ctx.ports.devtools` directly.
*
* The runner records `started`, `completed`, and `failed` events. Recording
* failures are isolated from schedule execution.
*/
instrumentation?: ProviderInstrumentationTarget;
/**
* Correlation fields attached to recorded schedule events.
*/
instrumentationContext?: ScheduleInstrumentationContext;
/**
* Called after payload validation and before the schedule handler.
*/
onStart?<S extends ScheduleDef<string, StandardSchema, Ctx>>(args: ScheduleLifecycleArgs<S>): MaybePromise<void>;
/**
* Called after the schedule handler completes.
*/
onSuccess?<S extends ScheduleDef<string, StandardSchema, Ctx>>(args: ScheduleLifecycleArgs<S>): MaybePromise<void>;
/**
* Called when payload creation, validation, or the handler fails.
*/
onError?<S extends ScheduleDef<string, StandardSchema, Ctx>>(args: ScheduleErrorArgs<S>): MaybePromise<void>;
/**
* Called when a lifecycle hook throws.
*/
onHookError?<S extends ScheduleDef<string, StandardSchema, Ctx>>(args: ScheduleHookErrorArgs<S>): MaybePromise<void>;
}
/**
* Port shape for running schedules.
*/
export interface ScheduleRunnerPort<Ctx = unknown> {
/**
* Run a schedule with optional provider metadata and payload.
*/
run<S extends ScheduleDef<string, StandardSchema, Ctx>>(schedule: S, options?: ScheduleRunOptions<InferSchedulePayload<S>>): Promise<void>;
}
/**
* Local/test schedule runner that executes handlers inline.
*/
export interface InlineScheduleRunner<Ctx = unknown> extends ScheduleRunnerPort<Ctx> {
}
/**
* Context-bound schedule helper factory.
*/
export interface Schedules<Ctx> {
/**
* Define a schedule with the bound context type.
*/
defineSchedule<Name extends string, Payload extends StandardSchema>(name: Name, options: DefineScheduleOptions<Name, Payload, Ctx>): ScheduleDef<Name, Payload, Ctx>;
}
/**
* Error thrown when schedule payload validation fails.
*/
export declare class ScheduleValidationError extends Error {
/**
* Raw Standard Schema validation issues.
*/
readonly issues: readonly StandardSchemaV1.Issue[];
constructor(args: {
name: string;
issues: readonly StandardSchemaV1.Issue[];
});
}
/**
* Error thrown when schedule run metadata cannot be normalized.
*/
export declare class ScheduleRunContextError extends Error {
constructor(message: string);
}
/**
* Validate and parse a schedule payload with the schedule's Standard Schema.
*/
export declare function parseSchedulePayload<S extends SchedulePayloadDef>(schedule: S, payload: unknown): Promise<InferSchedulePayload<S>>;
/**
* Run one schedule directly with an explicit context.
*/
export declare function runSchedule<Ctx, S extends ScheduleDef<string, StandardSchema, Ctx>>(schedule: S, args: ScheduleRunArgs<Ctx, InferSchedulePayload<S>>): Promise<void>;
/**
* Create a local/test schedule runner that executes handlers inline.
*/
export declare function createInlineScheduleRunner<Ctx>(options?: InlineScheduleRunnerOptions<Ctx>): InlineScheduleRunner<Ctx>;
/**
* Create schedule helper methods bound to an application context type.
*
* Call it once in `lib/schedules.ts`:
*
* ```ts
* export const { defineSchedule } = createSchedules<AppContext>();
* ```
*
* Cron and timezone are metadata for schedule providers. The inline runner only
* runs schedules when its `run(...)` method is called.
*/
export declare function createSchedules<Ctx>(): Schedules<Ctx>;
//# sourceMappingURL=index.d.ts.map