feat(core-shared): bind-protocols (event bus / realtime / realtime registry)

This commit is contained in:
2026-05-09 12:35:48 +02:00
parent 54958170ab
commit b5a9d1fe9d
2 changed files with 63 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
import { describe, it, expectTypeOf } from "vitest";
import type {
EventBusProtocol,
RealtimeBroadcasterProtocol,
RealtimeRegistryProtocol,
} from "./bind-protocols";
describe("EventBusProtocol", () => {
it("requires publish(event, payload) and subscribe(event, consumer, handler)", () => {
type Bus = EventBusProtocol;
expectTypeOf<Bus["publish"]>().toBeFunction();
expectTypeOf<Bus["subscribe"]>().toBeFunction();
});
});
describe("RealtimeBroadcasterProtocol", () => {
it("requires broadcast(channel, payload)", () => {
type Rt = RealtimeBroadcasterProtocol;
expectTypeOf<Rt["broadcast"]>().toBeFunction();
});
});
describe("RealtimeRegistryProtocol", () => {
it("requires register, registerChannel, listChannels", () => {
type Reg = RealtimeRegistryProtocol;
expectTypeOf<Reg["register"]>().toBeFunction();
expectTypeOf<Reg["registerChannel"]>().toBeFunction();
expectTypeOf<Reg["listChannels"]>().toBeFunction();
});
});

View File

@@ -0,0 +1,33 @@
/**
* Minimal protocol surfaces used by feature binders to interact with optional
* cross-cutting infrastructure (event bus, realtime broadcaster, realtime
* handler registry). Lives in `core-shared` so `BindContext` can reference
* these unconditionally — features depend on `core-shared`, never on the
* optional packages directly.
*
* The optional packages' full interfaces (`IEventBus`, `IRealtimeBroadcaster`,
* `IRealtimeHandlerRegistry`) `extends` these — typechecks fail if a refactor
* narrows the protocol surface in a way the full interface would lose.
*/
export type EventBusProtocol = {
publish<T>(event: { name: string }, payload: T): Promise<void>;
subscribe<T>(
event: { name: string },
consumer: string,
handler: (payload: T) => Promise<void>,
): void;
};
export type RealtimeBroadcasterProtocol = {
broadcast<T>(
channel: { name: string; key?: unknown },
payload: T,
): Promise<void>;
};
export type RealtimeRegistryProtocol = {
register(entry: { descriptor: unknown; handler: unknown }): void;
registerChannel(descriptor: unknown): void;
listChannels(): unknown[];
};