From 256a5dcea0271d9f1edb7cfc382a23ecd16bd034 Mon Sep 17 00:00:00 2001 From: maaz519 Date: Sat, 18 Jul 2026 00:57:39 +0530 Subject: [PATCH] feat: add MessagingProvider and useAdapter --- .../iios-messaging-ui/src/provider.test.tsx | 25 +++++++++++++++++++ packages/iios-messaging-ui/src/provider.tsx | 22 ++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 packages/iios-messaging-ui/src/provider.test.tsx create mode 100644 packages/iios-messaging-ui/src/provider.tsx diff --git a/packages/iios-messaging-ui/src/provider.test.tsx b/packages/iios-messaging-ui/src/provider.test.tsx new file mode 100644 index 0000000..7054c46 --- /dev/null +++ b/packages/iios-messaging-ui/src/provider.test.tsx @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import { MessagingProvider, useAdapter } from './provider'; +import { MockAdapter } from './adapters/mock'; + +function ShowActor() { + const adapter = useAdapter(); + return {adapter.currentActorId()}; +} + +describe('MessagingProvider', () => { + it('supplies the injected adapter to descendants', () => { + render( + + + , + ); + expect(screen.getByText('me')).toBeDefined(); + }); + + it('throws a helpful error when a hook is used outside the provider', () => { + // React logs the error boundary trace; that noise is expected. + expect(() => render()).toThrow(/useAdapter must be used within a /); + }); +}); diff --git a/packages/iios-messaging-ui/src/provider.tsx b/packages/iios-messaging-ui/src/provider.tsx new file mode 100644 index 0000000..748c00f --- /dev/null +++ b/packages/iios-messaging-ui/src/provider.tsx @@ -0,0 +1,22 @@ +import { createContext, useContext, type ReactNode } from 'react'; +import type { MessagingAdapter } from './adapter'; + +const AdapterContext = createContext(null); + +export function MessagingProvider({ + adapter, + children, +}: { + adapter: MessagingAdapter; + children: ReactNode; +}) { + return {children}; +} + +/** Access the host-injected adapter. Throws outside a provider — a missing provider is + * a wiring bug, and failing loudly beats a confusing null-deref three layers down. */ +export function useAdapter(): MessagingAdapter { + const adapter = useContext(AdapterContext); + if (!adapter) throw new Error('useAdapter must be used within a '); + return adapter; +}