diff --git a/packages/vitnode/src/api/adapters/events/local.ts b/packages/vitnode/src/api/adapters/events/local.ts index aed210a5e..eee22385b 100644 --- a/packages/vitnode/src/api/adapters/events/local.ts +++ b/packages/vitnode/src/api/adapters/events/local.ts @@ -2,9 +2,9 @@ import type { Context } from "hono"; import type { EnvVitNode } from "@/api/middlewares/global.middleware"; import type { + AnyEventEnvelope, EventEmitResult, - EventEnvelope, - EventsApiPlugin, + EventsAdapter, } from "@/api/models/events"; /** @@ -14,12 +14,12 @@ import type { * on the instance that emitted the event - swap the adapter for a broker to * fan out across instances. */ -export const LocalEventsAdapter = (): EventsApiPlugin => ({ +export const LocalEventsAdapter = (): EventsAdapter => ({ name: "local", publish: async ( c: Context, - envelope: EventEnvelope, + envelope: AnyEventEnvelope, ): Promise => { const listeners = c .get("core") diff --git a/packages/vitnode/src/api/models/events.ts b/packages/vitnode/src/api/models/events.ts index 39eb12873..07e42f5db 100644 --- a/packages/vitnode/src/api/models/events.ts +++ b/packages/vitnode/src/api/models/events.ts @@ -71,6 +71,11 @@ export interface EventEnvelope { pluginId: string; } +/** A discriminated union of every registered event envelope. */ +export type AnyEventEnvelope = { + [K in VitNodeEventName]: EventEnvelope; +}[VitNodeEventName]; + export interface EventEmitFailure { error: string; /** Listener `name` as declared in `buildEventListener`. */ @@ -88,10 +93,11 @@ export interface EventEmitResult { /** * `delivered` - listeners ran in-process before `emit()` resolved (the * bundled Local adapter). `queued` - the envelope was handed to a broker and - * delivery happens out-of-band; `delivered`/`failures` say nothing about the - * eventual listener runs. + * delivery happens out-of-band. `failed` - the adapter could not publish the + * event. For queued and failed events, `delivered`/`failures` do not describe + * eventual listener execution. */ - status: "delivered" | "queued"; + status: "delivered" | "failed" | "queued"; } /** @@ -99,11 +105,17 @@ export interface EventEmitResult { * to the listeners registered in `c.get("core").events.listeners`; a broker * adapter publishes the envelope and returns `status: "queued"`. */ -export interface EventsApiPlugin { +export interface EventsAdapter { name: string; - publish: (c: Context, envelope: EventEnvelope) => Promise; + publish: ( + c: Context, + envelope: AnyEventEnvelope, + ) => Promise; } +/** @deprecated Use `EventsAdapter` instead. */ +export type EventsApiPlugin = EventsAdapter; + export class EventsModel { constructor(c: Context) { this.c = c; @@ -111,7 +123,7 @@ export class EventsModel { protected readonly c: Context; - private adapter(): EventsApiPlugin { + private adapter(): EventsAdapter { return this.c.get("core").events.adapter; } @@ -143,7 +155,7 @@ export class EventsModel { const adapter = this.adapter(); try { - return await adapter.publish(this.c, envelope); + return await adapter.publish(this.c, envelope as AnyEventEnvelope); } catch (err) { const error = err instanceof Error ? err.message : String(err); await this.c @@ -154,7 +166,7 @@ export class EventsModel { return { eventId: envelope.eventId, - status: "delivered", + status: "failed", delivered: 0, failures: [ {