@ai-matrx/messaging 0.12.5 → 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 +26 -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 +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog — `@ai-matrx/messaging`
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **A conversation that cannot be read now says so.** Opening a conversation the
|
|
8
|
+
caller may not read (a refused message read) used to leave the thread absent
|
|
9
|
+
forever — an endless spinner — and a zero-row read of a conversation that does
|
|
10
|
+
not exist or is hidden by RLS rendered "No messages yet". The engine now
|
|
11
|
+
records a per-conversation read failure in the store
|
|
12
|
+
(`snapshot.conversationReadFailures`, type `ConversationReadFailure`); on a
|
|
13
|
+
zero-row read it asks the conversation row itself (`getConversation(id)`)
|
|
14
|
+
before calling the thread empty, and opens no realtime channel for a
|
|
15
|
+
conversation the user cannot read.
|
|
16
|
+
- `useConversation(id)` gains `error: MessagingError | null` and
|
|
17
|
+
`unavailable: boolean` (additive). `isLoading` is now false once the read has
|
|
18
|
+
failed. `<ConversationView>` renders "Conversation unavailable" /
|
|
19
|
+
"Couldn't load this conversation" instead of the spinner or the empty state.
|
|
20
|
+
|
|
21
|
+
### Consumer action
|
|
22
|
+
|
|
23
|
+
- Hosts with an access surface: when `useConversation(id).unavailable` is true,
|
|
24
|
+
render it instead of the thread. `error.cause` is the raw database error
|
|
25
|
+
(`42501`, `PGRST116`) for hosts that classify access failures themselves
|
|
26
|
+
(matrx-frontend: `<AccessGate token="dm_conversation" id error={error.cause} />`).
|
|
27
|
+
- No action otherwise — existing fields are unchanged.
|
|
28
|
+
|
|
3
29
|
## 0.12.5
|
|
4
30
|
|
|
5
31
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
package/dist/index.cjs
CHANGED
|
@@ -1044,6 +1044,7 @@ function createMessagingStore() {
|
|
|
1044
1044
|
let archivedCount = null;
|
|
1045
1045
|
let threads = /* @__PURE__ */ new Map();
|
|
1046
1046
|
let activeConversationId = null;
|
|
1047
|
+
let conversationReadFailures = /* @__PURE__ */ new Map();
|
|
1047
1048
|
const listeners = /* @__PURE__ */ new Set();
|
|
1048
1049
|
let cached = null;
|
|
1049
1050
|
function snapshot() {
|
|
@@ -1056,7 +1057,8 @@ function createMessagingStore() {
|
|
|
1056
1057
|
activeConversationId,
|
|
1057
1058
|
totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
|
|
1058
1059
|
archiveFilter,
|
|
1059
|
-
archivedCount
|
|
1060
|
+
archivedCount,
|
|
1061
|
+
conversationReadFailures
|
|
1060
1062
|
};
|
|
1061
1063
|
return cached;
|
|
1062
1064
|
}
|
|
@@ -1140,6 +1142,14 @@ function createMessagingStore() {
|
|
|
1140
1142
|
conversations = normalizeConversations(conversations);
|
|
1141
1143
|
emit();
|
|
1142
1144
|
},
|
|
1145
|
+
setConversationReadFailure(id, failure) {
|
|
1146
|
+
if (failure === null && !conversationReadFailures.has(id)) return;
|
|
1147
|
+
const next = new Map(conversationReadFailures);
|
|
1148
|
+
if (failure === null) next.delete(id);
|
|
1149
|
+
else next.set(id, failure);
|
|
1150
|
+
conversationReadFailures = next;
|
|
1151
|
+
emit();
|
|
1152
|
+
},
|
|
1143
1153
|
setThread(id, messages, args = {}) {
|
|
1144
1154
|
writeThread({
|
|
1145
1155
|
conversationId: id,
|
|
@@ -1445,11 +1455,26 @@ function createMessagingEngine(options) {
|
|
|
1445
1455
|
},
|
|
1446
1456
|
async openConversation(id) {
|
|
1447
1457
|
store.setActiveConversation(id);
|
|
1458
|
+
store.setConversationReadFailure(id, null);
|
|
1448
1459
|
try {
|
|
1449
1460
|
const page = await repository.listMessages(id, { limit: messagePageSize });
|
|
1461
|
+
if (page.items.length === 0) {
|
|
1462
|
+
await repository.getConversation(id);
|
|
1463
|
+
}
|
|
1450
1464
|
store.setThread(id, page.items, { hasMoreOlder: page.hasMore });
|
|
1451
1465
|
} catch (error) {
|
|
1452
|
-
|
|
1466
|
+
const normalized = normalizeMessagingError(error, "openConversation");
|
|
1467
|
+
const unavailable = normalized.code === "not-found" || normalized.code === "forbidden";
|
|
1468
|
+
store.setConversationReadFailure(id, { error: normalized, unavailable });
|
|
1469
|
+
if (unavailable) {
|
|
1470
|
+
report({
|
|
1471
|
+
level: "warn",
|
|
1472
|
+
message: normalized.message,
|
|
1473
|
+
remedy: normalized.remedy
|
|
1474
|
+
});
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
reportError(normalized, "openConversation");
|
|
1453
1478
|
}
|
|
1454
1479
|
if (openChannels.has(id) || disposed) return;
|
|
1455
1480
|
const handle = manager.open({
|