feat: define MessagingAdapter contract
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
import type {
|
||||||
|
Attachment,
|
||||||
|
Conversation,
|
||||||
|
Membership,
|
||||||
|
Message,
|
||||||
|
MessageEvent,
|
||||||
|
SendOpts,
|
||||||
|
Unsubscribe,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The one seam of this SDK. Hosts implement this; the SDK renders it.
|
||||||
|
*
|
||||||
|
* Lifted from lynkeduppro-crm's MessengerData/ThreadData, which already survived
|
||||||
|
* two implementations (live data-door + mock) — the minimum real evidence that a
|
||||||
|
* seam is genuine rather than imagined.
|
||||||
|
*
|
||||||
|
* Optional methods degrade gracefully: the UI hides the reaction picker when
|
||||||
|
* `react` is absent, and the attach button when `upload` is absent. That is how one
|
||||||
|
* component set serves both a full CRM messenger and a stripped-down widget with no
|
||||||
|
* `mode` prop.
|
||||||
|
*/
|
||||||
|
export interface MessagingAdapter {
|
||||||
|
listConversations(): Promise<Conversation[]>;
|
||||||
|
|
||||||
|
openThread(p: { participantIds: string[]; membership?: Membership; subject?: string }): Promise<{ threadId: string }>;
|
||||||
|
|
||||||
|
history(threadId: string): Promise<Message[]>;
|
||||||
|
|
||||||
|
send(threadId: string, content: string, opts?: SendOpts): Promise<Message>;
|
||||||
|
|
||||||
|
/** Returns an unsubscribe fn. Implementations MUST be idempotent on repeat unsubscribe. */
|
||||||
|
subscribe(threadId: string, cb: (e: MessageEvent) => void): Unsubscribe;
|
||||||
|
|
||||||
|
sendTyping(threadId: string): void;
|
||||||
|
|
||||||
|
markRead(threadId: string, messageId: string): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current user's actor id, or null if not yet known.
|
||||||
|
*
|
||||||
|
* MUST NOT be inferred from message history. The CRM's bug was exactly that:
|
||||||
|
* scanning for a sent message meant every message read as not-yours until you
|
||||||
|
* had spoken. Adapters derive this from auth/session.
|
||||||
|
*/
|
||||||
|
currentActorId(): string | null;
|
||||||
|
|
||||||
|
/** Absent => the UI hides reactions entirely. */
|
||||||
|
react?(threadId: string, messageId: string, emoji: string): Promise<void>;
|
||||||
|
|
||||||
|
/** Absent => the UI hides attachments. Storage/auth/limits are the host's concern. */
|
||||||
|
upload?(file: File): Promise<Attachment>;
|
||||||
|
|
||||||
|
/** Absent => treated as always connected (e.g. a pure-REST adapter). */
|
||||||
|
isConnected?(): boolean;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user