feat: add MessagingProvider and useAdapter
This commit is contained in:
@@ -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 <span>{adapter.currentActorId()}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('MessagingProvider', () => {
|
||||||
|
it('supplies the injected adapter to descendants', () => {
|
||||||
|
render(
|
||||||
|
<MessagingProvider adapter={new MockAdapter()}>
|
||||||
|
<ShowActor />
|
||||||
|
</MessagingProvider>,
|
||||||
|
);
|
||||||
|
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(<ShowActor />)).toThrow(/useAdapter must be used within a <MessagingProvider>/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createContext, useContext, type ReactNode } from 'react';
|
||||||
|
import type { MessagingAdapter } from './adapter';
|
||||||
|
|
||||||
|
const AdapterContext = createContext<MessagingAdapter | null>(null);
|
||||||
|
|
||||||
|
export function MessagingProvider({
|
||||||
|
adapter,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
adapter: MessagingAdapter;
|
||||||
|
children: ReactNode;
|
||||||
|
}) {
|
||||||
|
return <AdapterContext.Provider value={adapter}>{children}</AdapterContext.Provider>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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 <MessagingProvider>');
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user