import type { EventPayloadDef, EventPublishOptions, EventSubscription, InferEventPayload as InferContractEventPayload, StandardSchema, } from "../events/index.js"; export type { EventSubscription } from "../events/index.js"; import type { JobDef as ContractJobDef, InferJobPayload as InferContractJobPayload, JobDispatchOptions, } from "../jobs/index.js"; /** * Represents a defined Domain Event with name and payload schema. * This is a minimal structural interface that ports need - event * declarations from `defineEvent` in @beignet/core/events satisfy it. */ export interface DomainEventDef< Name extends string = string, Payload extends StandardSchema = StandardSchema, > extends EventPayloadDef {} /** * Infer the payload type from a DomainEventDef. */ export type InferEventPayload = InferContractEventPayload; /** * Represents a job definition with a typed payload schema. * * Job dispatchers use Beignet's first-class job definitions. Inline * dispatchers can run the handler directly; * durable dispatchers can ignore it and enqueue the job name plus parsed * payload. */ export type JobDef< Name extends string = string, Payload extends StandardSchema = StandardSchema, Ctx = unknown, > = ContractJobDef; /** * Infer the payload type from a JobDef. */ export type InferJobPayload = InferContractJobPayload; /** * An EventBus port for publishing and subscribing to domain events. * * This interface defines a framework-agnostic contract for event-driven * communication within your application. Implementations must prepare * producer payloads with `prepareEventPayloadForTransport(...)` from * `@beignet/core/events` so direct publication and provider swaps preserve the * same canonical JSON semantics. * * @example * ```ts * import { createMemoryEventBus } from "@beignet/provider-event-bus-memory"; * * const eventBus = createMemoryEventBus(); * * // Subscribe to an event * const subscription = eventBus.subscribe(UserRegistered, (payload) => { * console.log(`User registered: ${payload.email}`); * }); * await subscription.ready; * * // Publish an event * await eventBus.publish(UserRegistered, { userId: "123", email: "test@example.com" }); * * // Unsubscribe when done * await subscription.unsubscribe(); * ``` */ export interface EventBusPort { /** * Publish a domain event with a typed payload. */ publish( event: E, payload: InferEventPayload, options?: EventPublishOptions, ): Promise | void; /** * Subscribe to a domain event. Returns initial readiness and cleanup. */ subscribe( event: E, handler: ( payload: InferEventPayload, options?: EventPublishOptions, ) => Promise | void, ): EventSubscription; } /** * A port for dispatching explicit background jobs. * * Jobs represent work to do, not facts that happened. Implementations may run * inline in tests, enqueue into a durable worker, or call an external job * system. */ export interface JobDispatcherPort { dispatch( job: J, payload: InferJobPayload, options?: JobDispatchOptions, ): Promise | void; }