Files
web/packages/sdk-react/mod.ts
Dan Ditomaso 4b146c4d4f feat(sdk,web): drafts persisted in SDK chat slice (SQLite-backed)
Moves per-conversation draft text out of the legacy Zustand messageStore
into the SDK chat slice so drafts share the same persistence + signal
machinery as messages. MessageInput now binds directly to the SDK; the
legacy `useMessages().getDraft/setDraft/clearDraft` API is no longer
called from the input.

packages/sdk
- New DraftRepository port + InMemoryDraftRepository default.
- ChatClient.drafts namespace: get(key) returns a ReadonlySignal<string>;
  set/clear keyed by ConversationKey.
- ChatClient.send auto-clears the draft for the resolved conversation on
  success (parity with prior Zustand clearDraft-on-send behavior).
- Lazy hydrate from the DraftRepository on first read of a conversation.
- 3 new tests in ChatClient.drafts.test.ts.

packages/sdk-react
- New useDraft(conversation) hook returning { text, setText, clear }.

packages/sdk-storage-sqlocal
- New `drafts` table (device_id + conversation_key composite PK, text,
  updated_at). Drizzle schema in src/schema/drafts.ts.
- Migration v2 in src/schema/migrations.ts creates the table on first
  open of an existing v1 DB.
- SqlocalDraftRepository implementing DraftRepository: load/save/clear/
  loadAll, scoped by device_id, upsert on conflict, delete on empty save.
- 6 new tests covering save/load round-trip, empty-string deletion,
  upsert, multi-device isolation, loadAll.

packages/web
- useConnections wires the SqlocalDraftRepository alongside the existing
  SqlocalMessageRepository per registered MeshClient.
- MessageInput accepts `conversation: ConversationKey` instead of the
  prior `to: Types.Destination` — fixes the legacy bug where every
  broadcast channel shared a single draft slot.
- MessagesPage passes the appropriate ConversationKey for direct/
  broadcast chats.
- MessageInput.test.tsx rewritten to mock useDraft from sdk-react.

Test counts: sdk 39 (+3), sdk-storage-sqlocal 18 (+6), web 294 unchanged.
Production Vite build clean.
2026-04-24 22:10:32 -04:00

36 lines
2.1 KiB
TypeScript

export { MeshProvider } from "./src/provider/MeshProvider.tsx";
export type { MeshProviderProps } from "./src/provider/MeshProvider.tsx";
export { MeshContext } from "./src/provider/MeshContext.ts";
export { MeshRegistryProvider } from "./src/provider/MeshRegistryProvider.tsx";
export type { MeshRegistryProviderProps } from "./src/provider/MeshRegistryProvider.tsx";
export { MeshRegistryContext } from "./src/provider/MeshRegistryContext.ts";
export { useClient } from "./src/adapters/useClient.ts";
export { useClientById } from "./src/adapters/useClientById.ts";
export { useActiveClient } from "./src/adapters/useActiveClient.ts";
export { useMeshRegistry, useOptionalMeshRegistry } from "./src/adapters/useMeshRegistry.ts";
export { useSignal } from "./src/adapters/useSignal.ts";
export { useSignalValue } from "./src/adapters/useSignalValue.ts";
export { useMeshDevice } from "./src/hooks/useMeshDevice.ts";
export type { UseMeshDeviceResult } from "./src/hooks/useMeshDevice.ts";
export { useConnection } from "./src/hooks/useConnection.ts";
export type { UseConnectionResult } from "./src/hooks/useConnection.ts";
export { useChat } from "./src/hooks/useChat.ts";
export type { UseChatResult } from "./src/hooks/useChat.ts";
export { useDirectChat } from "./src/hooks/useDirectChat.ts";
export type { UseDirectChatResult } from "./src/hooks/useDirectChat.ts";
export { useDraft } from "./src/hooks/useDraft.ts";
export type { UseDraftResult } from "./src/hooks/useDraft.ts";
export { useNodes } from "./src/hooks/useNodes.ts";
export { useNode } from "./src/hooks/useNode.ts";
export { useChannels, useChannel } from "./src/hooks/useChannels.ts";
export { useConfig, useModuleConfig } from "./src/hooks/useConfig.ts";
export { useTelemetry } from "./src/hooks/useTelemetry.ts";
export type { UseTelemetryResult } from "./src/hooks/useTelemetry.ts";
export { usePosition } from "./src/hooks/usePosition.ts";
export { useTraceroute } from "./src/hooks/useTraceroute.ts";
export { useFileTransfer } from "./src/hooks/useFileTransfer.ts";
export { useFavoriteNode } from "./src/hooks/useFavoriteNode.ts";
export { useIgnoreNode } from "./src/hooks/useIgnoreNode.ts";