@ai-matrx/messaging 0.15.14 → 0.15.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.cjs +446 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -50
- package/dist/index.d.ts +90 -50
- package/dist/index.js +446 -101
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +447 -103
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +90 -50
- package/dist/react.d.ts +90 -50
- package/dist/react.js +447 -103
- package/dist/react.js.map +1 -1
- package/package.json +4 -4
package/dist/react.d.cts
CHANGED
|
@@ -449,6 +449,49 @@ interface MessagingAi {
|
|
|
449
449
|
declare function unreadCutoff(messages: readonly Message[], unreadCount: number): string | null;
|
|
450
450
|
declare function createMessagingAi(options: MessagingAiOptions): MessagingAi;
|
|
451
451
|
|
|
452
|
+
/**
|
|
453
|
+
* ONE error classification for the whole package (C22).
|
|
454
|
+
*
|
|
455
|
+
* The banned alternative is the host catching a PostgREST error and deciding
|
|
456
|
+
* for itself whether it was an auth blip, a permission denial, or a real bug —
|
|
457
|
+
* which is how the same three-branch `if` ends up copy-pasted into every
|
|
458
|
+
* consumer and drifts. Everything this package throws is a `MessagingError`
|
|
459
|
+
* with a stable `code`, and the two that hosts genuinely treat differently
|
|
460
|
+
* (`session-unavailable`, `forbidden`) say so in the type.
|
|
461
|
+
*
|
|
462
|
+
* The incident behind `session-unavailable`: a DM reader mounted before the
|
|
463
|
+
* access token existed, every RPC came back `42501`, and the app captured 909
|
|
464
|
+
* errors in 0.6 seconds. A missing session is a NORMAL lifecycle moment — it
|
|
465
|
+
* warns and retries; it is never a red error.
|
|
466
|
+
*/
|
|
467
|
+
type MessagingErrorCode = "session-unavailable" | "contention" | "forbidden" | "not-found" | "conflict" | "transport" | "invalid-response" | "write-not-applied" | "misconfigured"
|
|
468
|
+
/** A NEW conversation needs an organization to land in and none is selected. */
|
|
469
|
+
| "organization-required" | "unknown";
|
|
470
|
+
declare class MessagingError extends Error {
|
|
471
|
+
readonly code: MessagingErrorCode;
|
|
472
|
+
/** The remedy. Nothing fails silently, and nothing fails without saying what to do. */
|
|
473
|
+
readonly remedy: string;
|
|
474
|
+
readonly cause?: unknown;
|
|
475
|
+
constructor(code: MessagingErrorCode, message: string, remedy: string, cause?: unknown);
|
|
476
|
+
/** True when re-running the same call is the fix. */
|
|
477
|
+
get isRetryable(): boolean;
|
|
478
|
+
}
|
|
479
|
+
interface PostgrestErrorLike {
|
|
480
|
+
message: string;
|
|
481
|
+
code?: string | undefined;
|
|
482
|
+
details?: string | null | undefined;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* THE ONE PLACE a raw PostgREST/transport error becomes a typed one. Called at
|
|
486
|
+
* every boundary in `repository.ts`; nothing else in the package inspects a raw
|
|
487
|
+
* error, and no consumer should ever have to.
|
|
488
|
+
*/
|
|
489
|
+
declare function normalizeMessagingError(error: PostgrestErrorLike | Error | unknown, operation: string): MessagingError;
|
|
490
|
+
/** A response whose SHAPE is wrong — the ingress boundary, not the wire. */
|
|
491
|
+
declare function invalidResponse(operation: string, detail: string): MessagingError;
|
|
492
|
+
/** A mutation that PostgREST accepted syntactically but applied to no row. */
|
|
493
|
+
declare function writeNotApplied(operation: string, detail: string): MessagingError;
|
|
494
|
+
|
|
452
495
|
/**
|
|
453
496
|
* THE OUTBOX — a message you typed is NEVER lost (R2, table-stakes law).
|
|
454
497
|
*
|
|
@@ -537,47 +580,6 @@ interface Outbox {
|
|
|
537
580
|
}
|
|
538
581
|
declare function createOutbox(options: OutboxOptions): Outbox;
|
|
539
582
|
|
|
540
|
-
/**
|
|
541
|
-
* ONE error classification for the whole package (C22).
|
|
542
|
-
*
|
|
543
|
-
* The banned alternative is the host catching a PostgREST error and deciding
|
|
544
|
-
* for itself whether it was an auth blip, a permission denial, or a real bug —
|
|
545
|
-
* which is how the same three-branch `if` ends up copy-pasted into every
|
|
546
|
-
* consumer and drifts. Everything this package throws is a `MessagingError`
|
|
547
|
-
* with a stable `code`, and the two that hosts genuinely treat differently
|
|
548
|
-
* (`session-unavailable`, `forbidden`) say so in the type.
|
|
549
|
-
*
|
|
550
|
-
* The incident behind `session-unavailable`: a DM reader mounted before the
|
|
551
|
-
* access token existed, every RPC came back `42501`, and the app captured 909
|
|
552
|
-
* errors in 0.6 seconds. A missing session is a NORMAL lifecycle moment — it
|
|
553
|
-
* warns and retries; it is never a red error.
|
|
554
|
-
*/
|
|
555
|
-
type MessagingErrorCode = "session-unavailable" | "contention" | "forbidden" | "not-found" | "conflict" | "transport" | "invalid-response" | "misconfigured"
|
|
556
|
-
/** A NEW conversation needs an organization to land in and none is selected. */
|
|
557
|
-
| "organization-required" | "unknown";
|
|
558
|
-
declare class MessagingError extends Error {
|
|
559
|
-
readonly code: MessagingErrorCode;
|
|
560
|
-
/** The remedy. Nothing fails silently, and nothing fails without saying what to do. */
|
|
561
|
-
readonly remedy: string;
|
|
562
|
-
readonly cause?: unknown;
|
|
563
|
-
constructor(code: MessagingErrorCode, message: string, remedy: string, cause?: unknown);
|
|
564
|
-
/** True when re-running the same call is the fix. */
|
|
565
|
-
get isRetryable(): boolean;
|
|
566
|
-
}
|
|
567
|
-
interface PostgrestErrorLike {
|
|
568
|
-
message: string;
|
|
569
|
-
code?: string | undefined;
|
|
570
|
-
details?: string | null | undefined;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* THE ONE PLACE a raw PostgREST/transport error becomes a typed one. Called at
|
|
574
|
-
* every boundary in `repository.ts`; nothing else in the package inspects a raw
|
|
575
|
-
* error, and no consumer should ever have to.
|
|
576
|
-
*/
|
|
577
|
-
declare function normalizeMessagingError(error: PostgrestErrorLike | Error | unknown, operation: string): MessagingError;
|
|
578
|
-
/** A response whose SHAPE is wrong — the ingress boundary, not the wire. */
|
|
579
|
-
declare function invalidResponse(operation: string, detail: string): MessagingError;
|
|
580
|
-
|
|
581
583
|
/**
|
|
582
584
|
* THE STRUCTURAL SUPABASE SHAPE.
|
|
583
585
|
*
|
|
@@ -609,6 +611,7 @@ interface PostgrestLikeResponse<T> {
|
|
|
609
611
|
code?: string;
|
|
610
612
|
details?: string | null;
|
|
611
613
|
} | null;
|
|
614
|
+
count?: number | null;
|
|
612
615
|
}
|
|
613
616
|
interface PostgrestFilterLike<TRow> extends PromiseLike<PostgrestLikeResponse<TRow[]>> {
|
|
614
617
|
eq(column: string, value: unknown): PostgrestFilterLike<TRow>;
|
|
@@ -622,12 +625,17 @@ interface PostgrestFilterLike<TRow> extends PromiseLike<PostgrestLikeResponse<TR
|
|
|
622
625
|
ascending?: boolean;
|
|
623
626
|
}): PostgrestFilterLike<TRow>;
|
|
624
627
|
limit(count: number): PostgrestFilterLike<TRow>;
|
|
625
|
-
|
|
628
|
+
range(from: number, to: number): PostgrestFilterLike<TRow>;
|
|
629
|
+
select(columns?: string, options?: {
|
|
630
|
+
count?: "exact";
|
|
631
|
+
}): PostgrestFilterLike<TRow>;
|
|
626
632
|
single(): PromiseLike<PostgrestLikeResponse<TRow>>;
|
|
627
633
|
maybeSingle(): PromiseLike<PostgrestLikeResponse<TRow>>;
|
|
628
634
|
}
|
|
629
635
|
interface PostgrestTableLike<TRow> {
|
|
630
|
-
select(columns?: string
|
|
636
|
+
select(columns?: string, options?: {
|
|
637
|
+
count?: "exact";
|
|
638
|
+
}): PostgrestFilterLike<TRow>;
|
|
631
639
|
insert(values: unknown): PostgrestFilterLike<TRow>;
|
|
632
640
|
update(values: unknown): PostgrestFilterLike<TRow>;
|
|
633
641
|
upsert(values: unknown, options?: {
|
|
@@ -920,6 +928,11 @@ interface MessagingRepository {
|
|
|
920
928
|
exact: boolean;
|
|
921
929
|
}>;
|
|
922
930
|
getConversation(id: ConversationId): Promise<Conversation>;
|
|
931
|
+
/**
|
|
932
|
+
* One conversation's complete inbox/header row, independent of inbox paging.
|
|
933
|
+
* Deep links use this door when their conversation is not in the loaded page.
|
|
934
|
+
*/
|
|
935
|
+
getConversationSummary(id: ConversationId): Promise<ConversationSummary>;
|
|
923
936
|
listMessages(conversationId: ConversationId, args?: {
|
|
924
937
|
limit?: number;
|
|
925
938
|
cursor?: MessageCursor | null;
|
|
@@ -934,7 +947,8 @@ interface MessagingRepository {
|
|
|
934
947
|
insertMessage(draft: DraftMessage, clientMessageId: ClientMessageId): Promise<Message>;
|
|
935
948
|
editMessage(id: MessageId, content: string): Promise<Message>;
|
|
936
949
|
deleteMessage(id: MessageId, forEveryone: boolean): Promise<void>;
|
|
937
|
-
|
|
950
|
+
/** Persists the cutoff, then returns the server's remaining unread count. */
|
|
951
|
+
markRead(conversationId: ConversationId, at: string): Promise<number>;
|
|
938
952
|
setConversationFlags(conversationId: ConversationId, flags: {
|
|
939
953
|
isMuted?: boolean;
|
|
940
954
|
isArchived?: boolean;
|
|
@@ -975,10 +989,10 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
|
|
|
975
989
|
* 4. **Order is `created_at` then `id`.** The unique tiebreaker is not
|
|
976
990
|
* decoration: two messages in the same millisecond otherwise swap places on
|
|
977
991
|
* every re-render.
|
|
978
|
-
* 5. **
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
992
|
+
* 5. **Navigation is not a read receipt.** Active-conversation state never
|
|
993
|
+
* clears unread counts. Only a confirmed participant write may do that, and
|
|
994
|
+
* overlapping confirmations apply monotonically so one baseline is never
|
|
995
|
+
* subtracted twice.
|
|
982
996
|
*/
|
|
983
997
|
|
|
984
998
|
/**
|
|
@@ -1008,6 +1022,12 @@ interface ConversationThread {
|
|
|
1008
1022
|
}
|
|
1009
1023
|
interface MessagingSnapshot {
|
|
1010
1024
|
readonly conversations: readonly ConversationSummary[];
|
|
1025
|
+
/**
|
|
1026
|
+
* Summaries known by id, including a directly opened conversation outside
|
|
1027
|
+
* the current filtered inbox page. Header lookup uses this map; inbox
|
|
1028
|
+
* rendering continues to use `conversations` exactly as returned by its page.
|
|
1029
|
+
*/
|
|
1030
|
+
readonly conversationSummaries: ReadonlyMap<ConversationId, ConversationSummary>;
|
|
1011
1031
|
readonly hasMoreConversations: boolean;
|
|
1012
1032
|
/**
|
|
1013
1033
|
* True once the inbox has actually been READ at least once.
|
|
@@ -1066,6 +1086,7 @@ interface MessagingStore {
|
|
|
1066
1086
|
} | null): void;
|
|
1067
1087
|
appendConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
1068
1088
|
upsertConversation(item: ConversationSummary): void;
|
|
1089
|
+
setConversationSummary(item: ConversationSummary): void;
|
|
1069
1090
|
removeConversation(id: ConversationId): void;
|
|
1070
1091
|
setActiveConversation(id: ConversationId | null): void;
|
|
1071
1092
|
/** Record (or clear, with `null`) why a conversation could not be read. */
|
|
@@ -1073,12 +1094,19 @@ interface MessagingStore {
|
|
|
1073
1094
|
setThread(id: ConversationId, messages: readonly Message[], args?: {
|
|
1074
1095
|
hasMoreOlder?: boolean;
|
|
1075
1096
|
}): void;
|
|
1097
|
+
clearThread(id: ConversationId): void;
|
|
1076
1098
|
prependOlder(id: ConversationId, messages: readonly Message[], hasMoreOlder: boolean): void;
|
|
1077
1099
|
/** The one door every incoming message uses. Returns what actually happened. */
|
|
1078
1100
|
ingest(message: Message): "added" | "merged" | "dropped-stale" | "dropped-duplicate";
|
|
1079
1101
|
ingestMany(messages: readonly Message[]): void;
|
|
1080
1102
|
removeMessage(conversationId: ConversationId, messageId: MessageId): void;
|
|
1081
|
-
|
|
1103
|
+
captureConversationRead(id: ConversationId, at: string): ConversationReadCutoff;
|
|
1104
|
+
/**
|
|
1105
|
+
* Apply a confirmed read through the exact cutoff persisted by the repository.
|
|
1106
|
+
* `unreadCount` is the portion visible when that write began; arrivals after
|
|
1107
|
+
* `at` remain unread when the confirmation comes back.
|
|
1108
|
+
*/
|
|
1109
|
+
markConversationRead(id: ConversationId, cutoff: ConversationReadCutoff, canonicalUnreadCount?: number): void;
|
|
1082
1110
|
/**
|
|
1083
1111
|
* Move a conversation's preview + sort position to reflect a message, with NO
|
|
1084
1112
|
* refetch. Sending a message must not cost a conversation-list RPC — at a
|
|
@@ -1090,6 +1118,12 @@ interface MessagingStore {
|
|
|
1090
1118
|
}): void;
|
|
1091
1119
|
setUnreadCount(id: ConversationId, count: number): void;
|
|
1092
1120
|
}
|
|
1121
|
+
interface ConversationReadCutoff {
|
|
1122
|
+
readonly at: string;
|
|
1123
|
+
readonly unreadCount: number;
|
|
1124
|
+
/** Per-conversation unread-state revision observed when this read began. */
|
|
1125
|
+
readonly revision: number;
|
|
1126
|
+
}
|
|
1093
1127
|
declare function createMessagingStore(): MessagingStore;
|
|
1094
1128
|
/**
|
|
1095
1129
|
* The optimistic row a composer shows the instant Enter is pressed. It carries
|
|
@@ -1129,6 +1163,12 @@ interface EngineDiagnostic {
|
|
|
1129
1163
|
readonly level: "info" | "warn" | "error";
|
|
1130
1164
|
readonly message: string;
|
|
1131
1165
|
readonly remedy?: string | undefined;
|
|
1166
|
+
/** Stable machine-readable metadata for host diagnostic adapters. */
|
|
1167
|
+
readonly code?: MessagingErrorCode | undefined;
|
|
1168
|
+
readonly operation?: string | undefined;
|
|
1169
|
+
readonly isRetryable?: boolean | undefined;
|
|
1170
|
+
readonly error?: MessagingError | undefined;
|
|
1171
|
+
readonly conversationId?: ConversationId | undefined;
|
|
1132
1172
|
}
|
|
1133
1173
|
interface MessagingEngineOptions {
|
|
1134
1174
|
repository: MessagingRepository;
|
|
@@ -1877,4 +1917,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1877
1917
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1878
1918
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1879
1919
|
|
|
1880
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerAttachment, type ComposerInputRenderProps, type Conversation, type ConversationAiContext, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationReadFailure, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, SERVER_SESSION_IDENTITY, type SchemaLike, SearchIcon, SendIcon, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
|
1920
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerAttachment, type ComposerInputRenderProps, type Conversation, type ConversationAiContext, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationReadCutoff, type ConversationReadFailure, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, SERVER_SESSION_IDENTITY, type SchemaLike, SearchIcon, SendIcon, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists, writeNotApplied };
|
package/dist/react.d.ts
CHANGED
|
@@ -449,6 +449,49 @@ interface MessagingAi {
|
|
|
449
449
|
declare function unreadCutoff(messages: readonly Message[], unreadCount: number): string | null;
|
|
450
450
|
declare function createMessagingAi(options: MessagingAiOptions): MessagingAi;
|
|
451
451
|
|
|
452
|
+
/**
|
|
453
|
+
* ONE error classification for the whole package (C22).
|
|
454
|
+
*
|
|
455
|
+
* The banned alternative is the host catching a PostgREST error and deciding
|
|
456
|
+
* for itself whether it was an auth blip, a permission denial, or a real bug —
|
|
457
|
+
* which is how the same three-branch `if` ends up copy-pasted into every
|
|
458
|
+
* consumer and drifts. Everything this package throws is a `MessagingError`
|
|
459
|
+
* with a stable `code`, and the two that hosts genuinely treat differently
|
|
460
|
+
* (`session-unavailable`, `forbidden`) say so in the type.
|
|
461
|
+
*
|
|
462
|
+
* The incident behind `session-unavailable`: a DM reader mounted before the
|
|
463
|
+
* access token existed, every RPC came back `42501`, and the app captured 909
|
|
464
|
+
* errors in 0.6 seconds. A missing session is a NORMAL lifecycle moment — it
|
|
465
|
+
* warns and retries; it is never a red error.
|
|
466
|
+
*/
|
|
467
|
+
type MessagingErrorCode = "session-unavailable" | "contention" | "forbidden" | "not-found" | "conflict" | "transport" | "invalid-response" | "write-not-applied" | "misconfigured"
|
|
468
|
+
/** A NEW conversation needs an organization to land in and none is selected. */
|
|
469
|
+
| "organization-required" | "unknown";
|
|
470
|
+
declare class MessagingError extends Error {
|
|
471
|
+
readonly code: MessagingErrorCode;
|
|
472
|
+
/** The remedy. Nothing fails silently, and nothing fails without saying what to do. */
|
|
473
|
+
readonly remedy: string;
|
|
474
|
+
readonly cause?: unknown;
|
|
475
|
+
constructor(code: MessagingErrorCode, message: string, remedy: string, cause?: unknown);
|
|
476
|
+
/** True when re-running the same call is the fix. */
|
|
477
|
+
get isRetryable(): boolean;
|
|
478
|
+
}
|
|
479
|
+
interface PostgrestErrorLike {
|
|
480
|
+
message: string;
|
|
481
|
+
code?: string | undefined;
|
|
482
|
+
details?: string | null | undefined;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* THE ONE PLACE a raw PostgREST/transport error becomes a typed one. Called at
|
|
486
|
+
* every boundary in `repository.ts`; nothing else in the package inspects a raw
|
|
487
|
+
* error, and no consumer should ever have to.
|
|
488
|
+
*/
|
|
489
|
+
declare function normalizeMessagingError(error: PostgrestErrorLike | Error | unknown, operation: string): MessagingError;
|
|
490
|
+
/** A response whose SHAPE is wrong — the ingress boundary, not the wire. */
|
|
491
|
+
declare function invalidResponse(operation: string, detail: string): MessagingError;
|
|
492
|
+
/** A mutation that PostgREST accepted syntactically but applied to no row. */
|
|
493
|
+
declare function writeNotApplied(operation: string, detail: string): MessagingError;
|
|
494
|
+
|
|
452
495
|
/**
|
|
453
496
|
* THE OUTBOX — a message you typed is NEVER lost (R2, table-stakes law).
|
|
454
497
|
*
|
|
@@ -537,47 +580,6 @@ interface Outbox {
|
|
|
537
580
|
}
|
|
538
581
|
declare function createOutbox(options: OutboxOptions): Outbox;
|
|
539
582
|
|
|
540
|
-
/**
|
|
541
|
-
* ONE error classification for the whole package (C22).
|
|
542
|
-
*
|
|
543
|
-
* The banned alternative is the host catching a PostgREST error and deciding
|
|
544
|
-
* for itself whether it was an auth blip, a permission denial, or a real bug —
|
|
545
|
-
* which is how the same three-branch `if` ends up copy-pasted into every
|
|
546
|
-
* consumer and drifts. Everything this package throws is a `MessagingError`
|
|
547
|
-
* with a stable `code`, and the two that hosts genuinely treat differently
|
|
548
|
-
* (`session-unavailable`, `forbidden`) say so in the type.
|
|
549
|
-
*
|
|
550
|
-
* The incident behind `session-unavailable`: a DM reader mounted before the
|
|
551
|
-
* access token existed, every RPC came back `42501`, and the app captured 909
|
|
552
|
-
* errors in 0.6 seconds. A missing session is a NORMAL lifecycle moment — it
|
|
553
|
-
* warns and retries; it is never a red error.
|
|
554
|
-
*/
|
|
555
|
-
type MessagingErrorCode = "session-unavailable" | "contention" | "forbidden" | "not-found" | "conflict" | "transport" | "invalid-response" | "misconfigured"
|
|
556
|
-
/** A NEW conversation needs an organization to land in and none is selected. */
|
|
557
|
-
| "organization-required" | "unknown";
|
|
558
|
-
declare class MessagingError extends Error {
|
|
559
|
-
readonly code: MessagingErrorCode;
|
|
560
|
-
/** The remedy. Nothing fails silently, and nothing fails without saying what to do. */
|
|
561
|
-
readonly remedy: string;
|
|
562
|
-
readonly cause?: unknown;
|
|
563
|
-
constructor(code: MessagingErrorCode, message: string, remedy: string, cause?: unknown);
|
|
564
|
-
/** True when re-running the same call is the fix. */
|
|
565
|
-
get isRetryable(): boolean;
|
|
566
|
-
}
|
|
567
|
-
interface PostgrestErrorLike {
|
|
568
|
-
message: string;
|
|
569
|
-
code?: string | undefined;
|
|
570
|
-
details?: string | null | undefined;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* THE ONE PLACE a raw PostgREST/transport error becomes a typed one. Called at
|
|
574
|
-
* every boundary in `repository.ts`; nothing else in the package inspects a raw
|
|
575
|
-
* error, and no consumer should ever have to.
|
|
576
|
-
*/
|
|
577
|
-
declare function normalizeMessagingError(error: PostgrestErrorLike | Error | unknown, operation: string): MessagingError;
|
|
578
|
-
/** A response whose SHAPE is wrong — the ingress boundary, not the wire. */
|
|
579
|
-
declare function invalidResponse(operation: string, detail: string): MessagingError;
|
|
580
|
-
|
|
581
583
|
/**
|
|
582
584
|
* THE STRUCTURAL SUPABASE SHAPE.
|
|
583
585
|
*
|
|
@@ -609,6 +611,7 @@ interface PostgrestLikeResponse<T> {
|
|
|
609
611
|
code?: string;
|
|
610
612
|
details?: string | null;
|
|
611
613
|
} | null;
|
|
614
|
+
count?: number | null;
|
|
612
615
|
}
|
|
613
616
|
interface PostgrestFilterLike<TRow> extends PromiseLike<PostgrestLikeResponse<TRow[]>> {
|
|
614
617
|
eq(column: string, value: unknown): PostgrestFilterLike<TRow>;
|
|
@@ -622,12 +625,17 @@ interface PostgrestFilterLike<TRow> extends PromiseLike<PostgrestLikeResponse<TR
|
|
|
622
625
|
ascending?: boolean;
|
|
623
626
|
}): PostgrestFilterLike<TRow>;
|
|
624
627
|
limit(count: number): PostgrestFilterLike<TRow>;
|
|
625
|
-
|
|
628
|
+
range(from: number, to: number): PostgrestFilterLike<TRow>;
|
|
629
|
+
select(columns?: string, options?: {
|
|
630
|
+
count?: "exact";
|
|
631
|
+
}): PostgrestFilterLike<TRow>;
|
|
626
632
|
single(): PromiseLike<PostgrestLikeResponse<TRow>>;
|
|
627
633
|
maybeSingle(): PromiseLike<PostgrestLikeResponse<TRow>>;
|
|
628
634
|
}
|
|
629
635
|
interface PostgrestTableLike<TRow> {
|
|
630
|
-
select(columns?: string
|
|
636
|
+
select(columns?: string, options?: {
|
|
637
|
+
count?: "exact";
|
|
638
|
+
}): PostgrestFilterLike<TRow>;
|
|
631
639
|
insert(values: unknown): PostgrestFilterLike<TRow>;
|
|
632
640
|
update(values: unknown): PostgrestFilterLike<TRow>;
|
|
633
641
|
upsert(values: unknown, options?: {
|
|
@@ -920,6 +928,11 @@ interface MessagingRepository {
|
|
|
920
928
|
exact: boolean;
|
|
921
929
|
}>;
|
|
922
930
|
getConversation(id: ConversationId): Promise<Conversation>;
|
|
931
|
+
/**
|
|
932
|
+
* One conversation's complete inbox/header row, independent of inbox paging.
|
|
933
|
+
* Deep links use this door when their conversation is not in the loaded page.
|
|
934
|
+
*/
|
|
935
|
+
getConversationSummary(id: ConversationId): Promise<ConversationSummary>;
|
|
923
936
|
listMessages(conversationId: ConversationId, args?: {
|
|
924
937
|
limit?: number;
|
|
925
938
|
cursor?: MessageCursor | null;
|
|
@@ -934,7 +947,8 @@ interface MessagingRepository {
|
|
|
934
947
|
insertMessage(draft: DraftMessage, clientMessageId: ClientMessageId): Promise<Message>;
|
|
935
948
|
editMessage(id: MessageId, content: string): Promise<Message>;
|
|
936
949
|
deleteMessage(id: MessageId, forEveryone: boolean): Promise<void>;
|
|
937
|
-
|
|
950
|
+
/** Persists the cutoff, then returns the server's remaining unread count. */
|
|
951
|
+
markRead(conversationId: ConversationId, at: string): Promise<number>;
|
|
938
952
|
setConversationFlags(conversationId: ConversationId, flags: {
|
|
939
953
|
isMuted?: boolean;
|
|
940
954
|
isArchived?: boolean;
|
|
@@ -975,10 +989,10 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
|
|
|
975
989
|
* 4. **Order is `created_at` then `id`.** The unique tiebreaker is not
|
|
976
990
|
* decoration: two messages in the same millisecond otherwise swap places on
|
|
977
991
|
* every re-render.
|
|
978
|
-
* 5. **
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
992
|
+
* 5. **Navigation is not a read receipt.** Active-conversation state never
|
|
993
|
+
* clears unread counts. Only a confirmed participant write may do that, and
|
|
994
|
+
* overlapping confirmations apply monotonically so one baseline is never
|
|
995
|
+
* subtracted twice.
|
|
982
996
|
*/
|
|
983
997
|
|
|
984
998
|
/**
|
|
@@ -1008,6 +1022,12 @@ interface ConversationThread {
|
|
|
1008
1022
|
}
|
|
1009
1023
|
interface MessagingSnapshot {
|
|
1010
1024
|
readonly conversations: readonly ConversationSummary[];
|
|
1025
|
+
/**
|
|
1026
|
+
* Summaries known by id, including a directly opened conversation outside
|
|
1027
|
+
* the current filtered inbox page. Header lookup uses this map; inbox
|
|
1028
|
+
* rendering continues to use `conversations` exactly as returned by its page.
|
|
1029
|
+
*/
|
|
1030
|
+
readonly conversationSummaries: ReadonlyMap<ConversationId, ConversationSummary>;
|
|
1011
1031
|
readonly hasMoreConversations: boolean;
|
|
1012
1032
|
/**
|
|
1013
1033
|
* True once the inbox has actually been READ at least once.
|
|
@@ -1066,6 +1086,7 @@ interface MessagingStore {
|
|
|
1066
1086
|
} | null): void;
|
|
1067
1087
|
appendConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
1068
1088
|
upsertConversation(item: ConversationSummary): void;
|
|
1089
|
+
setConversationSummary(item: ConversationSummary): void;
|
|
1069
1090
|
removeConversation(id: ConversationId): void;
|
|
1070
1091
|
setActiveConversation(id: ConversationId | null): void;
|
|
1071
1092
|
/** Record (or clear, with `null`) why a conversation could not be read. */
|
|
@@ -1073,12 +1094,19 @@ interface MessagingStore {
|
|
|
1073
1094
|
setThread(id: ConversationId, messages: readonly Message[], args?: {
|
|
1074
1095
|
hasMoreOlder?: boolean;
|
|
1075
1096
|
}): void;
|
|
1097
|
+
clearThread(id: ConversationId): void;
|
|
1076
1098
|
prependOlder(id: ConversationId, messages: readonly Message[], hasMoreOlder: boolean): void;
|
|
1077
1099
|
/** The one door every incoming message uses. Returns what actually happened. */
|
|
1078
1100
|
ingest(message: Message): "added" | "merged" | "dropped-stale" | "dropped-duplicate";
|
|
1079
1101
|
ingestMany(messages: readonly Message[]): void;
|
|
1080
1102
|
removeMessage(conversationId: ConversationId, messageId: MessageId): void;
|
|
1081
|
-
|
|
1103
|
+
captureConversationRead(id: ConversationId, at: string): ConversationReadCutoff;
|
|
1104
|
+
/**
|
|
1105
|
+
* Apply a confirmed read through the exact cutoff persisted by the repository.
|
|
1106
|
+
* `unreadCount` is the portion visible when that write began; arrivals after
|
|
1107
|
+
* `at` remain unread when the confirmation comes back.
|
|
1108
|
+
*/
|
|
1109
|
+
markConversationRead(id: ConversationId, cutoff: ConversationReadCutoff, canonicalUnreadCount?: number): void;
|
|
1082
1110
|
/**
|
|
1083
1111
|
* Move a conversation's preview + sort position to reflect a message, with NO
|
|
1084
1112
|
* refetch. Sending a message must not cost a conversation-list RPC — at a
|
|
@@ -1090,6 +1118,12 @@ interface MessagingStore {
|
|
|
1090
1118
|
}): void;
|
|
1091
1119
|
setUnreadCount(id: ConversationId, count: number): void;
|
|
1092
1120
|
}
|
|
1121
|
+
interface ConversationReadCutoff {
|
|
1122
|
+
readonly at: string;
|
|
1123
|
+
readonly unreadCount: number;
|
|
1124
|
+
/** Per-conversation unread-state revision observed when this read began. */
|
|
1125
|
+
readonly revision: number;
|
|
1126
|
+
}
|
|
1093
1127
|
declare function createMessagingStore(): MessagingStore;
|
|
1094
1128
|
/**
|
|
1095
1129
|
* The optimistic row a composer shows the instant Enter is pressed. It carries
|
|
@@ -1129,6 +1163,12 @@ interface EngineDiagnostic {
|
|
|
1129
1163
|
readonly level: "info" | "warn" | "error";
|
|
1130
1164
|
readonly message: string;
|
|
1131
1165
|
readonly remedy?: string | undefined;
|
|
1166
|
+
/** Stable machine-readable metadata for host diagnostic adapters. */
|
|
1167
|
+
readonly code?: MessagingErrorCode | undefined;
|
|
1168
|
+
readonly operation?: string | undefined;
|
|
1169
|
+
readonly isRetryable?: boolean | undefined;
|
|
1170
|
+
readonly error?: MessagingError | undefined;
|
|
1171
|
+
readonly conversationId?: ConversationId | undefined;
|
|
1132
1172
|
}
|
|
1133
1173
|
interface MessagingEngineOptions {
|
|
1134
1174
|
repository: MessagingRepository;
|
|
@@ -1877,4 +1917,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1877
1917
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1878
1918
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1879
1919
|
|
|
1880
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerAttachment, type ComposerInputRenderProps, type Conversation, type ConversationAiContext, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationReadFailure, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, SERVER_SESSION_IDENTITY, type SchemaLike, SearchIcon, SendIcon, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
|
1920
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerAttachment, type ComposerInputRenderProps, type Conversation, type ConversationAiContext, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationReadCutoff, type ConversationReadFailure, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, SERVER_SESSION_IDENTITY, type SchemaLike, SearchIcon, SendIcon, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists, writeNotApplied };
|