From b7c337fbd899eca06969cd715de4340d853615fa Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Tue, 4 Aug 2026 16:17:23 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20dispatch:=20add=20middleware-extens?= =?UTF-8?q?ible=20host=20events?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/src/dispatch.test.ts | 18 ++++++++++++++++++ packages/ui/src/dispatch.ts | 16 ++++++++++++++++ packages/ui/src/index.ts | 1 + 3 files changed, 35 insertions(+) create mode 100644 packages/ui/src/dispatch.test.ts create mode 100644 packages/ui/src/dispatch.ts diff --git a/packages/ui/src/dispatch.test.ts b/packages/ui/src/dispatch.test.ts new file mode 100644 index 0000000..fe1a927 --- /dev/null +++ b/packages/ui/src/dispatch.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, test } from 'vitest'; +import { DispatchApi } from './dispatch.ts'; +import { createHost } from './host.ts'; + +describe('dispatch', () => { + test('propagates errors thrown by decorators installed on the host', () => { + const host = createHost(); + const reason = new Error('dispatch failed'); + const dispatch = DispatchApi.init(host.root); + DispatchApi.decorate(host.root, () => ({ + dispatch() { + throw reason; + }, + })); + + expect(() => dispatch.dispatch({})).toThrow(reason); + }); +}); diff --git a/packages/ui/src/dispatch.ts b/packages/ui/src/dispatch.ts new file mode 100644 index 0000000..93e6acb --- /dev/null +++ b/packages/ui/src/dispatch.ts @@ -0,0 +1,16 @@ +import { Api } from './core/api.ts'; + +export class DispatchApi extends Api { + dispatch(_event: unknown): Result { + return { ok: true }; + } +} + +export type Result = + | typeof Ok + | { + ok: false; + reason: unknown; + }; + +const Ok = { ok: true } as const; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 9c0703a..4925bd6 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,4 +1,5 @@ export { rgba } from '@bomb.sh/tty'; +export { DispatchApi } from './dispatch.ts'; export { box, type BoxProps } from './components/box.ts'; export { text, type TextProps } from './components/text.ts'; export { LayoutApi } from './layout.ts';