@beignet/core
Version:
Core framework primitives for Beignet
200 lines • 6.37 kB
TypeScript
import type { StandardSchemaV1 } from "@standard-schema/spec";
import { type TraceCarrier, 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>;
/**
* Minimal event definition shape accepted by event bus helpers.
*/
export interface EventPayloadDef<Name extends string = string, Payload extends StandardSchema = StandardSchema> {
/**
* Stable event name.
*/
readonly name: Name;
/**
* Standard Schema payload validator.
*/
readonly payload: Payload;
/**
* Optional human-readable description for docs and tooling.
*/
readonly description?: string;
}
/**
* Event definition created by `defineEvent(...)`.
*/
export interface EventDef<Name extends string = string, Payload extends StandardSchema = StandardSchema> extends EventPayloadDef<Name, Payload> {
/**
* Discriminator for event definitions.
*/
readonly kind: "event";
}
/**
* Infer the parsed payload type for an event definition.
*/
export type InferEventPayload<E extends EventPayloadDef> = E["payload"] extends StandardSchemaV1<unknown, infer Output> ? Output : never;
/** Metadata propagated with an event delivery. */
export interface EventPublishOptions {
/** Versioned trace context captured by the event producer. */
trace?: TraceCarrier;
}
/**
* Options for `defineEvent(...)`.
*/
export interface DefineEventOptions<Payload extends StandardSchema> {
/**
* Standard Schema payload validator.
*/
payload: Payload;
/**
* Optional human-readable description for docs and tooling.
*/
description?: string;
}
/**
* Arguments passed to a listener handler.
*/
export interface ListenerHandleArgs<E extends EventDef, Ctx> {
/**
* Event definition being handled.
*/
event: E;
/**
* Parsed event payload.
*/
payload: InferEventPayload<E>;
/**
* Listener context.
*/
ctx: Ctx;
}
/**
* Listener definition created by `defineListener(...)`.
*/
export interface ListenerDef<E extends EventDef = EventDef, Ctx = unknown, Name extends string = string> {
/**
* Discriminator for listener definitions.
*/
readonly kind: "listener";
/**
* Stable listener name.
*/
readonly name: Name;
/**
* Event this listener handles.
*/
readonly event: E;
/**
* Handle a parsed event payload.
*/
handle(args: ListenerHandleArgs<E, Ctx>): MaybePromise<void>;
}
/**
* Options for `defineListener(...)`.
*/
export interface DefineListenerOptions<E extends EventDef, Ctx> {
/**
* Event this listener handles.
*/
event: E;
/**
* Handle a parsed event payload.
*/
handle(args: ListenerHandleArgs<E, Ctx>): MaybePromise<void>;
}
/**
* Event bus shape required by Beignet listener registration helpers.
*/
export interface EventBusLike {
/**
* Publish an event payload.
*/
publish<E extends EventPayloadDef>(event: E, payload: InferEventPayload<E>, options?: EventPublishOptions): MaybePromise<void>;
/**
* Subscribe to an event and return an unsubscribe function.
*/
subscribe<E extends EventPayloadDef>(event: E, handler: (payload: InferEventPayload<E>, options?: EventPublishOptions) => MaybePromise<void>): () => void;
}
/**
* Options for `registerListeners(...)`.
*/
export interface RegisterListenersOptions<Ctx> {
/**
* Static listener context or factory evaluated for each delivered event.
*/
ctx?: Ctx | (() => MaybePromise<Ctx>);
/**
* Runtime tracing port used to start the listener span before a lazy context
* factory runs.
*/
tracing?: TracingPort;
/**
* Called when a listener fails. When omitted, listener errors are rethrown to
* the event bus subscription callback.
*/
onError?: (error: unknown, listener: ListenerDef<EventDef, Ctx>) => void;
}
/**
* Context-bound listener helper factory.
*/
export interface Listeners<Ctx> {
/**
* Define a listener with the bound context type.
*/
defineListener<Name extends string, E extends EventDef>(name: Name, options: DefineListenerOptions<E, Ctx>): ListenerDef<E, Ctx, Name>;
}
/**
* Error thrown when event payload validation fails.
*/
export declare class EventValidationError extends Error {
/**
* Raw Standard Schema validation issues.
*/
readonly issues: readonly StandardSchemaV1.Issue[];
constructor(args: {
name: string;
issues: readonly StandardSchemaV1.Issue[];
});
}
/**
* Define a typed event.
*
* Event payloads are validated before publishing through `publishEvent(...)`
* and before registered listeners run.
*/
export declare function defineEvent<Name extends string, Payload extends StandardSchema>(name: Name, options: DefineEventOptions<Payload>): EventDef<Name, Payload>;
/**
* Validate and parse an event payload with the event's Standard Schema.
*/
export declare function parseEventPayload<E extends EventPayloadDef>(event: E, payload: unknown): Promise<InferEventPayload<E>>;
/**
* Validate an event payload and publish it through an event bus.
*/
export declare function publishEvent<E extends EventPayloadDef>(eventBus: EventBusLike, event: E, payload: InferEventPayload<E>, options?: EventPublishOptions): Promise<void>;
/**
* Register listeners against an event bus and return an unsubscribe function.
*
* Payloads are validated before listener handlers run. Listener context is
* resolved per delivery when `options.ctx` is a factory.
*/
export declare function registerListeners<Ctx>(eventBus: EventBusLike, listeners: readonly ListenerDef<EventDef, Ctx>[], options?: RegisterListenersOptions<Ctx>): () => void;
/**
* Create listener helper methods bound to an application context type.
*
* Call it once in `lib/listeners.ts`:
*
* ```ts
* export const { defineListener } = createListeners<AppContext>();
* ```
*/
export declare function createListeners<Ctx>(): Listeners<Ctx>;
//# sourceMappingURL=index.d.ts.map