@ai-matrx/messaging 0.12.4 → 0.13.0
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 +32 -0
- package/dist/index.cjs +27 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +44 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +34 -1
- package/dist/react.d.ts +34 -1
- package/dist/react.js +44 -4
- package/dist/react.js.map +1 -1
- package/package.json +5 -5
package/dist/react.d.cts
CHANGED
|
@@ -943,6 +943,24 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
|
|
|
943
943
|
* place here.
|
|
944
944
|
*/
|
|
945
945
|
|
|
946
|
+
/**
|
|
947
|
+
* Why a conversation could not be read — held PER conversation so a screen can
|
|
948
|
+
* tell "still loading" from "this will never load".
|
|
949
|
+
*
|
|
950
|
+
* Without it a refused read left the thread absent forever (an endless
|
|
951
|
+
* spinner), and a zero-row read of a conversation the caller cannot see
|
|
952
|
+
* rendered "No messages yet" — a confident lie about a conversation they may
|
|
953
|
+
* not even be allowed to know exists.
|
|
954
|
+
*/
|
|
955
|
+
interface ConversationReadFailure {
|
|
956
|
+
readonly error: MessagingError;
|
|
957
|
+
/**
|
|
958
|
+
* True when the conversation does not exist or this user may not read it
|
|
959
|
+
* (`not-found` / `forbidden`) — an ACCESS question the host answers with its
|
|
960
|
+
* access surface, never a retryable fault.
|
|
961
|
+
*/
|
|
962
|
+
readonly unavailable: boolean;
|
|
963
|
+
}
|
|
946
964
|
interface ConversationThread {
|
|
947
965
|
readonly conversationId: ConversationId;
|
|
948
966
|
readonly messages: readonly Message[];
|
|
@@ -984,6 +1002,8 @@ interface MessagingSnapshot {
|
|
|
984
1002
|
readonly count: number;
|
|
985
1003
|
readonly exact: boolean;
|
|
986
1004
|
} | null;
|
|
1005
|
+
/** Conversations whose last open failed, keyed by id. Cleared on the next open. */
|
|
1006
|
+
readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
|
|
987
1007
|
}
|
|
988
1008
|
interface MessagingStore {
|
|
989
1009
|
snapshot(): MessagingSnapshot;
|
|
@@ -1003,6 +1023,8 @@ interface MessagingStore {
|
|
|
1003
1023
|
upsertConversation(item: ConversationSummary): void;
|
|
1004
1024
|
removeConversation(id: ConversationId): void;
|
|
1005
1025
|
setActiveConversation(id: ConversationId | null): void;
|
|
1026
|
+
/** Record (or clear, with `null`) why a conversation could not be read. */
|
|
1027
|
+
setConversationReadFailure(id: ConversationId, failure: ConversationReadFailure | null): void;
|
|
1006
1028
|
setThread(id: ConversationId, messages: readonly Message[], args?: {
|
|
1007
1029
|
hasMoreOlder?: boolean;
|
|
1008
1030
|
}): void;
|
|
@@ -1362,7 +1384,18 @@ interface UseConversationResult {
|
|
|
1362
1384
|
thread: ConversationThread | null;
|
|
1363
1385
|
messages: readonly Message[];
|
|
1364
1386
|
participants: readonly UserSummary[];
|
|
1387
|
+
/** True only while the first read is in flight — false once it failed. */
|
|
1365
1388
|
isLoading: boolean;
|
|
1389
|
+
/**
|
|
1390
|
+
* Why the conversation could not be read, or `null`. `error.cause` is the
|
|
1391
|
+
* raw database error, for hosts that classify access failures themselves.
|
|
1392
|
+
*/
|
|
1393
|
+
error: MessagingError | null;
|
|
1394
|
+
/**
|
|
1395
|
+
* True when the conversation does not exist or this user may not read it.
|
|
1396
|
+
* Render the host's access surface — never "No messages yet".
|
|
1397
|
+
*/
|
|
1398
|
+
unavailable: boolean;
|
|
1366
1399
|
hasMoreOlder: boolean;
|
|
1367
1400
|
loadOlder: () => void;
|
|
1368
1401
|
pending: readonly OutboxEntry[];
|
|
@@ -1805,4 +1838,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1805
1838
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1806
1839
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1807
1840
|
|
|
1808
|
-
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 ComposerInputRenderProps, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, 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, 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 };
|
|
1841
|
+
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 ComposerInputRenderProps, type Conversation, 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, 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 };
|
package/dist/react.d.ts
CHANGED
|
@@ -943,6 +943,24 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
|
|
|
943
943
|
* place here.
|
|
944
944
|
*/
|
|
945
945
|
|
|
946
|
+
/**
|
|
947
|
+
* Why a conversation could not be read — held PER conversation so a screen can
|
|
948
|
+
* tell "still loading" from "this will never load".
|
|
949
|
+
*
|
|
950
|
+
* Without it a refused read left the thread absent forever (an endless
|
|
951
|
+
* spinner), and a zero-row read of a conversation the caller cannot see
|
|
952
|
+
* rendered "No messages yet" — a confident lie about a conversation they may
|
|
953
|
+
* not even be allowed to know exists.
|
|
954
|
+
*/
|
|
955
|
+
interface ConversationReadFailure {
|
|
956
|
+
readonly error: MessagingError;
|
|
957
|
+
/**
|
|
958
|
+
* True when the conversation does not exist or this user may not read it
|
|
959
|
+
* (`not-found` / `forbidden`) — an ACCESS question the host answers with its
|
|
960
|
+
* access surface, never a retryable fault.
|
|
961
|
+
*/
|
|
962
|
+
readonly unavailable: boolean;
|
|
963
|
+
}
|
|
946
964
|
interface ConversationThread {
|
|
947
965
|
readonly conversationId: ConversationId;
|
|
948
966
|
readonly messages: readonly Message[];
|
|
@@ -984,6 +1002,8 @@ interface MessagingSnapshot {
|
|
|
984
1002
|
readonly count: number;
|
|
985
1003
|
readonly exact: boolean;
|
|
986
1004
|
} | null;
|
|
1005
|
+
/** Conversations whose last open failed, keyed by id. Cleared on the next open. */
|
|
1006
|
+
readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
|
|
987
1007
|
}
|
|
988
1008
|
interface MessagingStore {
|
|
989
1009
|
snapshot(): MessagingSnapshot;
|
|
@@ -1003,6 +1023,8 @@ interface MessagingStore {
|
|
|
1003
1023
|
upsertConversation(item: ConversationSummary): void;
|
|
1004
1024
|
removeConversation(id: ConversationId): void;
|
|
1005
1025
|
setActiveConversation(id: ConversationId | null): void;
|
|
1026
|
+
/** Record (or clear, with `null`) why a conversation could not be read. */
|
|
1027
|
+
setConversationReadFailure(id: ConversationId, failure: ConversationReadFailure | null): void;
|
|
1006
1028
|
setThread(id: ConversationId, messages: readonly Message[], args?: {
|
|
1007
1029
|
hasMoreOlder?: boolean;
|
|
1008
1030
|
}): void;
|
|
@@ -1362,7 +1384,18 @@ interface UseConversationResult {
|
|
|
1362
1384
|
thread: ConversationThread | null;
|
|
1363
1385
|
messages: readonly Message[];
|
|
1364
1386
|
participants: readonly UserSummary[];
|
|
1387
|
+
/** True only while the first read is in flight — false once it failed. */
|
|
1365
1388
|
isLoading: boolean;
|
|
1389
|
+
/**
|
|
1390
|
+
* Why the conversation could not be read, or `null`. `error.cause` is the
|
|
1391
|
+
* raw database error, for hosts that classify access failures themselves.
|
|
1392
|
+
*/
|
|
1393
|
+
error: MessagingError | null;
|
|
1394
|
+
/**
|
|
1395
|
+
* True when the conversation does not exist or this user may not read it.
|
|
1396
|
+
* Render the host's access surface — never "No messages yet".
|
|
1397
|
+
*/
|
|
1398
|
+
unavailable: boolean;
|
|
1366
1399
|
hasMoreOlder: boolean;
|
|
1367
1400
|
loadOlder: () => void;
|
|
1368
1401
|
pending: readonly OutboxEntry[];
|
|
@@ -1805,4 +1838,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1805
1838
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1806
1839
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1807
1840
|
|
|
1808
|
-
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 ComposerInputRenderProps, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, 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, 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 };
|
|
1841
|
+
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 ComposerInputRenderProps, type Conversation, 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, 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 };
|
package/dist/react.js
CHANGED
|
@@ -875,6 +875,7 @@ function createMessagingStore() {
|
|
|
875
875
|
let archivedCount = null;
|
|
876
876
|
let threads = /* @__PURE__ */ new Map();
|
|
877
877
|
let activeConversationId = null;
|
|
878
|
+
let conversationReadFailures = /* @__PURE__ */ new Map();
|
|
878
879
|
const listeners = /* @__PURE__ */ new Set();
|
|
879
880
|
let cached = null;
|
|
880
881
|
function snapshot() {
|
|
@@ -887,7 +888,8 @@ function createMessagingStore() {
|
|
|
887
888
|
activeConversationId,
|
|
888
889
|
totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
|
|
889
890
|
archiveFilter,
|
|
890
|
-
archivedCount
|
|
891
|
+
archivedCount,
|
|
892
|
+
conversationReadFailures
|
|
891
893
|
};
|
|
892
894
|
return cached;
|
|
893
895
|
}
|
|
@@ -971,6 +973,14 @@ function createMessagingStore() {
|
|
|
971
973
|
conversations = normalizeConversations(conversations);
|
|
972
974
|
emit();
|
|
973
975
|
},
|
|
976
|
+
setConversationReadFailure(id, failure) {
|
|
977
|
+
if (failure === null && !conversationReadFailures.has(id)) return;
|
|
978
|
+
const next = new Map(conversationReadFailures);
|
|
979
|
+
if (failure === null) next.delete(id);
|
|
980
|
+
else next.set(id, failure);
|
|
981
|
+
conversationReadFailures = next;
|
|
982
|
+
emit();
|
|
983
|
+
},
|
|
974
984
|
setThread(id, messages, args = {}) {
|
|
975
985
|
writeThread({
|
|
976
986
|
conversationId: id,
|
|
@@ -1276,11 +1286,26 @@ function createMessagingEngine(options) {
|
|
|
1276
1286
|
},
|
|
1277
1287
|
async openConversation(id) {
|
|
1278
1288
|
store.setActiveConversation(id);
|
|
1289
|
+
store.setConversationReadFailure(id, null);
|
|
1279
1290
|
try {
|
|
1280
1291
|
const page = await repository.listMessages(id, { limit: messagePageSize });
|
|
1292
|
+
if (page.items.length === 0) {
|
|
1293
|
+
await repository.getConversation(id);
|
|
1294
|
+
}
|
|
1281
1295
|
store.setThread(id, page.items, { hasMoreOlder: page.hasMore });
|
|
1282
1296
|
} catch (error) {
|
|
1283
|
-
|
|
1297
|
+
const normalized = normalizeMessagingError(error, "openConversation");
|
|
1298
|
+
const unavailable = normalized.code === "not-found" || normalized.code === "forbidden";
|
|
1299
|
+
store.setConversationReadFailure(id, { error: normalized, unavailable });
|
|
1300
|
+
if (unavailable) {
|
|
1301
|
+
report({
|
|
1302
|
+
level: "warn",
|
|
1303
|
+
message: normalized.message,
|
|
1304
|
+
remedy: normalized.remedy
|
|
1305
|
+
});
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
reportError(normalized, "openConversation");
|
|
1284
1309
|
}
|
|
1285
1310
|
if (openChannels.has(id) || disposed) return;
|
|
1286
1311
|
const handle = manager.open({
|
|
@@ -2393,6 +2418,7 @@ function useConversation(id) {
|
|
|
2393
2418
|
}, []);
|
|
2394
2419
|
const thread = id === null ? null : snapshot?.threads.get(id) ?? null;
|
|
2395
2420
|
const summary = id === null ? null : snapshot?.conversations.find((item) => item.conversation.id === id) ?? null;
|
|
2421
|
+
const failure = id === null ? null : snapshot?.conversationReadFailures.get(id) ?? null;
|
|
2396
2422
|
const pending = useMemo2(() => {
|
|
2397
2423
|
void outboxTick;
|
|
2398
2424
|
return id === null ? [] : host?.engine.outbox.pendingFor(id) ?? [];
|
|
@@ -2402,7 +2428,9 @@ function useConversation(id) {
|
|
|
2402
2428
|
thread,
|
|
2403
2429
|
messages: thread?.messages ?? [],
|
|
2404
2430
|
participants: summary?.participants ?? [],
|
|
2405
|
-
isLoading: id !== null && thread === null,
|
|
2431
|
+
isLoading: id !== null && thread === null && failure === null,
|
|
2432
|
+
error: failure?.error ?? null,
|
|
2433
|
+
unavailable: failure?.unavailable ?? false,
|
|
2406
2434
|
hasMoreOlder: thread?.hasMoreOlder ?? false,
|
|
2407
2435
|
loadOlder: () => {
|
|
2408
2436
|
if (id !== null) void host?.engine.loadOlderMessages(id);
|
|
@@ -3189,7 +3217,19 @@ function ConversationView(props) {
|
|
|
3189
3217
|
}
|
|
3190
3218
|
)
|
|
3191
3219
|
] }) : null,
|
|
3192
|
-
/* @__PURE__ */ jsx4("div", { className: "mx-msg__scroll", ref: scrollRef, children: conversation.isLoading ? /* @__PURE__ */ jsx4(ConversationSkeleton, { rows: 4 }) :
|
|
3220
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-msg__scroll", ref: scrollRef, children: conversation.isLoading ? /* @__PURE__ */ jsx4(ConversationSkeleton, { rows: 4 }) : conversation.unavailable ? /* @__PURE__ */ jsx4(
|
|
3221
|
+
EmptyState,
|
|
3222
|
+
{
|
|
3223
|
+
title: "Conversation unavailable",
|
|
3224
|
+
body: "It doesn't exist, or you aren't a member of it."
|
|
3225
|
+
}
|
|
3226
|
+
) : conversation.error !== null && messages.length === 0 ? /* @__PURE__ */ jsx4(
|
|
3227
|
+
EmptyState,
|
|
3228
|
+
{
|
|
3229
|
+
title: "Couldn't load this conversation",
|
|
3230
|
+
body: "Check your connection, then open it again."
|
|
3231
|
+
}
|
|
3232
|
+
) : messages.length === 0 ? /* @__PURE__ */ jsx4(EmptyState, { title: "No messages yet", body: "Say something to get started." }) : /* @__PURE__ */ jsxs2("div", { className: "mx-msg__messages", children: [
|
|
3193
3233
|
conversation.hasMoreOlder ? /* @__PURE__ */ jsx4(
|
|
3194
3234
|
"button",
|
|
3195
3235
|
{
|