@beignet/core
Version:
Core framework primitives for Beignet
108 lines (100 loc) • 2.97 kB
text/typescript
import type {
EventPayloadDef,
EventPublishOptions,
InferEventPayload as InferContractEventPayload,
StandardSchema,
} 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<Name, Payload> {}
/**
* Infer the payload type from a DomainEventDef.
*/
export type InferEventPayload<E extends DomainEventDef> =
InferContractEventPayload<E>;
/**
* 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<Name, Payload, Ctx>;
/**
* Infer the payload type from a JobDef.
*/
export type InferJobPayload<J extends JobDef> = InferContractJobPayload<J>;
/**
* An EventBus port for publishing and subscribing to domain events.
*
* This interface defines a framework-agnostic contract for event-driven
* communication within your application.
*
* @example
* ```ts
* import { createMemoryEventBus } from "@beignet/provider-event-bus-memory";
*
* const eventBus = createMemoryEventBus();
*
* // Subscribe to an event
* const unsubscribe = eventBus.subscribe(UserRegistered, (payload) => {
* console.log(`User registered: ${payload.email}`);
* });
*
* // Publish an event
* await eventBus.publish(UserRegistered, { userId: "123", email: "test@example.com" });
*
* // Unsubscribe when done
* unsubscribe();
* ```
*/
export interface EventBusPort {
/**
* Publish a domain event with a typed payload.
*/
publish<E extends DomainEventDef>(
event: E,
payload: InferEventPayload<E>,
options?: EventPublishOptions,
): Promise<void> | void;
/**
* Subscribe to a domain event. Returns an unsubscribe function.
*/
subscribe<E extends DomainEventDef>(
event: E,
handler: (
payload: InferEventPayload<E>,
options?: EventPublishOptions,
) => Promise<void> | void,
): () => void;
}
/**
* 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<J extends JobDef>(
job: J,
payload: InferJobPayload<J>,
options?: JobDispatchOptions,
): Promise<void> | void;
}