@antzsoft/chat-core 1.3.3 → 1.3.4
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/README.md +24 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{storage-DdHsneZR.d.cts → storage-DJh54pps.d.cts} +7 -0
- package/dist/{storage-DdHsneZR.d.ts → storage-DJh54pps.d.ts} +7 -0
- package/docs/integration-guide.html +63 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1746,6 +1746,7 @@ interface CrossConversationSyncResponse {
|
|
|
1746
1746
|
deliveredReceipts: SyncDeliveredReceipt[]; // delivery receipts since `since`
|
|
1747
1747
|
reactions: SyncReactions; // v1.3.1+ — full current state for messages with reaction activity
|
|
1748
1748
|
stars: SyncStarEntry[]; // v1.3.1+ — star/unstar records since `since`
|
|
1749
|
+
deletedConversationIds: string[]; // v1.3.4+ — conversations the user deleted from their list since `since`
|
|
1749
1750
|
}
|
|
1750
1751
|
|
|
1751
1752
|
interface SyncDeletedForMe {
|
|
@@ -1861,6 +1862,7 @@ The built-in `SyncService.syncConversation()` in the RN app uses the backward di
|
|
|
1861
1862
|
| `participantChanges` | ✅ | ✅ | Role changes, mute/unmute, removals (`isActive: false`) |
|
|
1862
1863
|
| `readReceipts` | ✅ | ✅ | Read receipts — merge into `msg.readBy[]`, recompute status |
|
|
1863
1864
|
| `deliveredReceipts` | ✅ | ✅ | Delivery receipts — merge into `msg.deliveredTo[]`, recompute status |
|
|
1865
|
+
| `deletedConversationIds` | ✅ v1.3.4 | — | Conversations this user deleted from their list — remove from local DB. Cursor-safe: won't reappear on next `pull()` |
|
|
1864
1866
|
|
|
1865
1867
|
#### Stale handling
|
|
1866
1868
|
|
|
@@ -3054,6 +3056,28 @@ document.querySelectorAll('[data-conv-id]').forEach((el) => {
|
|
|
3054
3056
|
|
|
3055
3057
|
## Changelog
|
|
3056
3058
|
|
|
3059
|
+
### v1.3.4
|
|
3060
|
+
|
|
3061
|
+
- **New: `deletedConversationIds` in `CrossConversationSyncResponse`** — `syncApi.pull(since)` now returns `deletedConversationIds: string[]`. Contains the IDs of conversations this user explicitly deleted from their list (via the delete-conversation action) since the `since` cursor. The client should remove these from local SQLite and the UI conversation list.
|
|
3062
|
+
|
|
3063
|
+
```typescript
|
|
3064
|
+
const result = await syncApi.pull(lastSyncedAt);
|
|
3065
|
+
|
|
3066
|
+
// Remove conversations the user deleted from their list
|
|
3067
|
+
for (const convId of result.deletedConversationIds) {
|
|
3068
|
+
await db.conversations.delete(convId);
|
|
3069
|
+
}
|
|
3070
|
+
```
|
|
3071
|
+
|
|
3072
|
+
**Scoped to the requesting user only** — if another user deletes their copy of a shared DM, it does not appear in your `deletedConversationIds`. **Cursor-safe** — once the client saves the returned `syncedAt` as the new cursor, the same IDs will not reappear on the next `pull()` call. On the server side, this is detected via `participant.isHidden = true AND updatedAt > since` — the same flag set by `DELETE /conversations/:id`.
|
|
3073
|
+
|
|
3074
|
+
- **Fix: Sync access guard parity with message listing API** — All three sync paths now enforce the same access rules as `GET /messages`:
|
|
3075
|
+
- **`membershipPeriods` windows** — users who deleted and were re-added only see messages from their active membership periods; a deleted conversation with no periods returns no messages.
|
|
3076
|
+
- **`status` filter** — active messages and deleted-for-everyone tombstones (so clients can render "This message was deleted") are included; `failed`-status messages are excluded.
|
|
3077
|
+
- **`isHidden` group check** — hidden group participants (exit+delete) receive `403 Forbidden` on per-conversation sync, matching message listing behaviour. Hidden DM participants are still allowed.
|
|
3078
|
+
- **Removed-member read access** — removed members (`isActive: false`) can still call per-conversation sync to retrieve history, matching the message listing API's `validateConversationAccess` which does not require `isActive: true` for reads.
|
|
3079
|
+
- **No integration changes required.** These are server-side enforcement fixes — the response shape is unchanged, only the set of messages returned is now correctly filtered.
|
|
3080
|
+
|
|
3057
3081
|
### v1.3.3
|
|
3058
3082
|
|
|
3059
3083
|
- **New: `metadata` and `sender` fields in all sync message responses** — Messages returned by all three sync paths (`crossConversationSync`, `conversationSync`, `conversationSyncBySeq`) now include `metadata` (system message metadata — `actorUserId`, `targetUserId`, `action`) and `sender` (displayName, avatarUrl snapshot at send time). Both fields were already optional on the core SDK `Message` type so no SDK type changes were required. Previously absent from sync responses, meaning system message text could not be rendered and sender avatars were blank after an offline sync. The server batch-fetches sender profiles in a single `findByIds` call per sync request — one extra DB round trip per sync, not one per message. **No integration changes required.**
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, C as CrossConversationSyncResponse, c as ConversationSyncResponse, d as AppConfig, S as SendMessagePayload, e as CursorPaginatedResponse, M as Message, f as MessageReactionsResponse, P as PaginatedResponse, g as MessageReceiptsResponse, h as ConversationListParams, i as Conversation, j as Participant, k as ConversationUnreadCount, l as UnreadSummary, m as UserPreferences, n as ResolvedConfig, o as PersistStorage, p as PresignedUrlRequest, q as PresignedUrlResponse, F as FileResponse, r as CompletedPart, s as FileType, t as AntzChatConfig, u as UploadableFile, B as BatchUploadResult } from './storage-
|
|
2
|
-
export { v as Attachment, w as CompressedFile, x as CompressionAlgorithm, y as CompressionConfig, z as ConversationType, D as ConversationUpdatedEvent, E as FileSizeLimits, G as LastReaction, H as MessageAckEvent, I as MessageContent, J as MessageDeletedEvent, K as MessageDeletedForMeEvent, N as MessageDeliveredEvent, O as MessageMetadata, Q as MessageReaction, T as MessageReceiptEntry, V as MessageReplyReference, W as MessageStarUpdatedEvent, X as MessageUpdatedEvent, Y as MessagesDeliveredEvent, Z as MultipartPartUrl, _ as MultipartUploadInfo, $ as NewMessageEvent, a0 as OptimisticAttachment, a1 as PlatformCompressFn, a2 as PlatformUploadFn, a3 as PlatformUploadPartFn, a4 as QuietHours, a5 as ReactionGroup, a6 as ReactionUpdatedEvent, a7 as ReactionUser, a8 as ReadReceiptEvent, a9 as ReplyAttachmentSnapshot, aa as ResolvedFileSizeLimits, ab as SendMessageAttachment, ac as SyncDeletedForMe, ad as SyncDeliveredReceipt, ae as SyncParticipantChange, af as SyncReactionEntry, ag as SyncReactions, ah as SyncReadReceipt, ai as SyncStarEntry, aj as SystemMessageMetadata, ak as TypingIndicatorEvent, al as UploadConfig, am as UploadProgress, an as UserStatusEvent, ao as resolveConfig, ap as storageApi, aq as uploadBatch } from './storage-
|
|
1
|
+
import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, C as CrossConversationSyncResponse, c as ConversationSyncResponse, d as AppConfig, S as SendMessagePayload, e as CursorPaginatedResponse, M as Message, f as MessageReactionsResponse, P as PaginatedResponse, g as MessageReceiptsResponse, h as ConversationListParams, i as Conversation, j as Participant, k as ConversationUnreadCount, l as UnreadSummary, m as UserPreferences, n as ResolvedConfig, o as PersistStorage, p as PresignedUrlRequest, q as PresignedUrlResponse, F as FileResponse, r as CompletedPart, s as FileType, t as AntzChatConfig, u as UploadableFile, B as BatchUploadResult } from './storage-DJh54pps.cjs';
|
|
2
|
+
export { v as Attachment, w as CompressedFile, x as CompressionAlgorithm, y as CompressionConfig, z as ConversationType, D as ConversationUpdatedEvent, E as FileSizeLimits, G as LastReaction, H as MessageAckEvent, I as MessageContent, J as MessageDeletedEvent, K as MessageDeletedForMeEvent, N as MessageDeliveredEvent, O as MessageMetadata, Q as MessageReaction, T as MessageReceiptEntry, V as MessageReplyReference, W as MessageStarUpdatedEvent, X as MessageUpdatedEvent, Y as MessagesDeliveredEvent, Z as MultipartPartUrl, _ as MultipartUploadInfo, $ as NewMessageEvent, a0 as OptimisticAttachment, a1 as PlatformCompressFn, a2 as PlatformUploadFn, a3 as PlatformUploadPartFn, a4 as QuietHours, a5 as ReactionGroup, a6 as ReactionUpdatedEvent, a7 as ReactionUser, a8 as ReadReceiptEvent, a9 as ReplyAttachmentSnapshot, aa as ResolvedFileSizeLimits, ab as SendMessageAttachment, ac as SyncDeletedForMe, ad as SyncDeliveredReceipt, ae as SyncParticipantChange, af as SyncReactionEntry, ag as SyncReactions, ah as SyncReadReceipt, ai as SyncStarEntry, aj as SystemMessageMetadata, ak as TypingIndicatorEvent, al as UploadConfig, am as UploadProgress, an as UserStatusEvent, ao as resolveConfig, ap as storageApi, aq as uploadBatch } from './storage-DJh54pps.cjs';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
4
|
import { Socket } from 'socket.io-client';
|
|
5
5
|
import * as zustand_middleware from 'zustand/middleware';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, C as CrossConversationSyncResponse, c as ConversationSyncResponse, d as AppConfig, S as SendMessagePayload, e as CursorPaginatedResponse, M as Message, f as MessageReactionsResponse, P as PaginatedResponse, g as MessageReceiptsResponse, h as ConversationListParams, i as Conversation, j as Participant, k as ConversationUnreadCount, l as UnreadSummary, m as UserPreferences, n as ResolvedConfig, o as PersistStorage, p as PresignedUrlRequest, q as PresignedUrlResponse, F as FileResponse, r as CompletedPart, s as FileType, t as AntzChatConfig, u as UploadableFile, B as BatchUploadResult } from './storage-
|
|
2
|
-
export { v as Attachment, w as CompressedFile, x as CompressionAlgorithm, y as CompressionConfig, z as ConversationType, D as ConversationUpdatedEvent, E as FileSizeLimits, G as LastReaction, H as MessageAckEvent, I as MessageContent, J as MessageDeletedEvent, K as MessageDeletedForMeEvent, N as MessageDeliveredEvent, O as MessageMetadata, Q as MessageReaction, T as MessageReceiptEntry, V as MessageReplyReference, W as MessageStarUpdatedEvent, X as MessageUpdatedEvent, Y as MessagesDeliveredEvent, Z as MultipartPartUrl, _ as MultipartUploadInfo, $ as NewMessageEvent, a0 as OptimisticAttachment, a1 as PlatformCompressFn, a2 as PlatformUploadFn, a3 as PlatformUploadPartFn, a4 as QuietHours, a5 as ReactionGroup, a6 as ReactionUpdatedEvent, a7 as ReactionUser, a8 as ReadReceiptEvent, a9 as ReplyAttachmentSnapshot, aa as ResolvedFileSizeLimits, ab as SendMessageAttachment, ac as SyncDeletedForMe, ad as SyncDeliveredReceipt, ae as SyncParticipantChange, af as SyncReactionEntry, ag as SyncReactions, ah as SyncReadReceipt, ai as SyncStarEntry, aj as SystemMessageMetadata, ak as TypingIndicatorEvent, al as UploadConfig, am as UploadProgress, an as UserStatusEvent, ao as resolveConfig, ap as storageApi, aq as uploadBatch } from './storage-
|
|
1
|
+
import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, C as CrossConversationSyncResponse, c as ConversationSyncResponse, d as AppConfig, S as SendMessagePayload, e as CursorPaginatedResponse, M as Message, f as MessageReactionsResponse, P as PaginatedResponse, g as MessageReceiptsResponse, h as ConversationListParams, i as Conversation, j as Participant, k as ConversationUnreadCount, l as UnreadSummary, m as UserPreferences, n as ResolvedConfig, o as PersistStorage, p as PresignedUrlRequest, q as PresignedUrlResponse, F as FileResponse, r as CompletedPart, s as FileType, t as AntzChatConfig, u as UploadableFile, B as BatchUploadResult } from './storage-DJh54pps.js';
|
|
2
|
+
export { v as Attachment, w as CompressedFile, x as CompressionAlgorithm, y as CompressionConfig, z as ConversationType, D as ConversationUpdatedEvent, E as FileSizeLimits, G as LastReaction, H as MessageAckEvent, I as MessageContent, J as MessageDeletedEvent, K as MessageDeletedForMeEvent, N as MessageDeliveredEvent, O as MessageMetadata, Q as MessageReaction, T as MessageReceiptEntry, V as MessageReplyReference, W as MessageStarUpdatedEvent, X as MessageUpdatedEvent, Y as MessagesDeliveredEvent, Z as MultipartPartUrl, _ as MultipartUploadInfo, $ as NewMessageEvent, a0 as OptimisticAttachment, a1 as PlatformCompressFn, a2 as PlatformUploadFn, a3 as PlatformUploadPartFn, a4 as QuietHours, a5 as ReactionGroup, a6 as ReactionUpdatedEvent, a7 as ReactionUser, a8 as ReadReceiptEvent, a9 as ReplyAttachmentSnapshot, aa as ResolvedFileSizeLimits, ab as SendMessageAttachment, ac as SyncDeletedForMe, ad as SyncDeliveredReceipt, ae as SyncParticipantChange, af as SyncReactionEntry, ag as SyncReactions, ah as SyncReadReceipt, ai as SyncStarEntry, aj as SystemMessageMetadata, ak as TypingIndicatorEvent, al as UploadConfig, am as UploadProgress, an as UserStatusEvent, ao as resolveConfig, ap as storageApi, aq as uploadBatch } from './storage-DJh54pps.js';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
4
|
import { Socket } from 'socket.io-client';
|
|
5
5
|
import * as zustand_middleware from 'zustand/middleware';
|
package/dist/internal.d.cts
CHANGED
package/dist/internal.d.ts
CHANGED
|
@@ -484,6 +484,13 @@ interface CrossConversationSyncResponse {
|
|
|
484
484
|
participantChanges: SyncParticipantChange[];
|
|
485
485
|
readReceipts: SyncReadReceipt[];
|
|
486
486
|
deliveredReceipts: SyncDeliveredReceipt[];
|
|
487
|
+
/**
|
|
488
|
+
* Conversation IDs the client should remove from its local list.
|
|
489
|
+
* Set when the user explicitly deleted their own copy of a conversation
|
|
490
|
+
* (DM or group) via the delete action. Scoped to this user only — other
|
|
491
|
+
* participants are not affected.
|
|
492
|
+
*/
|
|
493
|
+
deletedConversationIds: string[];
|
|
487
494
|
}
|
|
488
495
|
interface ConversationSyncResponse {
|
|
489
496
|
syncedAt: string;
|
|
@@ -484,6 +484,13 @@ interface CrossConversationSyncResponse {
|
|
|
484
484
|
participantChanges: SyncParticipantChange[];
|
|
485
485
|
readReceipts: SyncReadReceipt[];
|
|
486
486
|
deliveredReceipts: SyncDeliveredReceipt[];
|
|
487
|
+
/**
|
|
488
|
+
* Conversation IDs the client should remove from its local list.
|
|
489
|
+
* Set when the user explicitly deleted their own copy of a conversation
|
|
490
|
+
* (DM or group) via the delete action. Scoped to this user only — other
|
|
491
|
+
* participants are not affected.
|
|
492
|
+
*/
|
|
493
|
+
deletedConversationIds: string[];
|
|
487
494
|
}
|
|
488
495
|
interface ConversationSyncResponse {
|
|
489
496
|
syncedAt: string;
|
|
@@ -155,7 +155,7 @@ section.sec>h2:hover{color:#fff}
|
|
|
155
155
|
|
|
156
156
|
<div class="section-label">What's New</div>
|
|
157
157
|
<ul>
|
|
158
|
-
<li><a href="#whats-new">v1.3.
|
|
158
|
+
<li><a href="#whats-new">v1.3.4 Release Notes</a></li>
|
|
159
159
|
</ul>
|
|
160
160
|
|
|
161
161
|
<div class="section-label">Getting Started</div>
|
|
@@ -250,12 +250,72 @@ section.sec>h2:hover{color:#fff}
|
|
|
250
250
|
<h2>What's New</h2>
|
|
251
251
|
<p style="color:var(--muted);font-size:13px;margin-bottom:20px">Version history and release notes. Click a version to expand.</p>
|
|
252
252
|
|
|
253
|
-
<!-- ── v1.3.
|
|
253
|
+
<!-- ── v1.3.4 (current) ── -->
|
|
254
|
+
<div class="wn-version open" id="wn-134">
|
|
255
|
+
<div class="wn-header" onclick="toggleVersion('wn-134')">
|
|
256
|
+
<div class="wn-title">
|
|
257
|
+
<span class="wn-ver">v1.3.4</span>
|
|
258
|
+
<span class="wn-badge current">Current</span>
|
|
259
|
+
<span class="wn-date">July 2026</span>
|
|
260
|
+
</div>
|
|
261
|
+
<span class="wn-chevron">▲</span>
|
|
262
|
+
</div>
|
|
263
|
+
<div class="wn-body">
|
|
264
|
+
|
|
265
|
+
<div class="wn-item" id="wn-134-deleted-conv-ids">
|
|
266
|
+
<div class="wn-item-header" onclick="toggleItem('wn-134-deleted-conv-ids')">
|
|
267
|
+
<span class="wn-tag new">New</span>
|
|
268
|
+
<span class="wn-item-title"><code>deletedConversationIds</code> in <code>CrossConversationSyncResponse</code></span>
|
|
269
|
+
<span class="wn-chevron-sm">▾</span>
|
|
270
|
+
</div>
|
|
271
|
+
<div class="wn-item-body">
|
|
272
|
+
<p><code>syncApi.pull(since)</code> now returns <code>deletedConversationIds: string[]</code> — IDs of conversations this user explicitly deleted from their list (via the delete-conversation action) since the <code>since</code> cursor. The client should remove these from local storage and the UI conversation list.</p>
|
|
273
|
+
<table>
|
|
274
|
+
<thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead>
|
|
275
|
+
<tbody>
|
|
276
|
+
<tr><td><code>deletedConversationIds</code></td><td><code>string[]</code></td><td>Conversation IDs to remove from local list. Empty array when none were deleted in the sync window.</td></tr>
|
|
277
|
+
</tbody>
|
|
278
|
+
</table>
|
|
279
|
+
<pre><code><span class="kw">const</span> result = <span class="kw">await</span> syncApi.<span class="fn">pull</span>(lastSyncedAt);
|
|
280
|
+
|
|
281
|
+
<span class="cm">// Remove conversations the user deleted from their list</span>
|
|
282
|
+
<span class="kw">for</span> (<span class="kw">const</span> convId <span class="kw">of</span> result.deletedConversationIds) {
|
|
283
|
+
<span class="kw">await</span> db.conversations.<span class="fn">delete</span>(convId);
|
|
284
|
+
}</code></pre>
|
|
285
|
+
<p><strong>Scoped to the requesting user only</strong> — if another user deletes their copy of a shared DM, it does not appear in your <code>deletedConversationIds</code>. <strong>Cursor-safe</strong> — once the client saves the returned <code>syncedAt</code> as the new cursor, the same IDs will not reappear on the next <code>pull()</code>. No acknowledged-receipt tracking needed.</p>
|
|
286
|
+
<p><strong>No integration changes required</strong> beyond consuming the new field. The field is always present (empty array when nothing was deleted).</p>
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
<div class="wn-item" id="wn-134-sync-guards">
|
|
291
|
+
<div class="wn-item-header" onclick="toggleItem('wn-134-sync-guards')">
|
|
292
|
+
<span class="wn-tag fix">Fix</span>
|
|
293
|
+
<span class="wn-item-title">Sync access guard parity with message listing API</span>
|
|
294
|
+
<span class="wn-chevron-sm">▾</span>
|
|
295
|
+
</div>
|
|
296
|
+
<div class="wn-item-body">
|
|
297
|
+
<p>All three sync paths now enforce the same access rules as <code>GET /messages</code>. Previously sync could return messages that message listing would not show.</p>
|
|
298
|
+
<table>
|
|
299
|
+
<thead><tr><th>Guard</th><th>Before</th><th>After</th></tr></thead>
|
|
300
|
+
<tbody>
|
|
301
|
+
<tr><td><code>membershipPeriods</code> windows</td><td>Not enforced — all messages returned regardless of when user was a member</td><td>Messages outside the user's active membership windows are excluded. Re-added users only see messages from their active periods.</td></tr>
|
|
302
|
+
<tr><td><code>status</code> filter</td><td>Only <code>deletedFor</code> checked — <code>failed</code>-status messages leaked through</td><td>Only <code>active</code> and <code>deleted</code> (tombstone) messages returned, matching message listing</td></tr>
|
|
303
|
+
<tr><td><code>isHidden</code> group check</td><td>Not checked — hidden group members could still sync</td><td>Hidden group participants (exit+delete) receive <code>403</code>. Hidden DM participants still allowed (consistent with message listing).</td></tr>
|
|
304
|
+
<tr><td>Removed-member read access</td><td><code>isActive: true</code> required — removed members blocked from syncing history</td><td>Removed members can sync read-only history, matching message listing <code>validateConversationAccess</code></td></tr>
|
|
305
|
+
</tbody>
|
|
306
|
+
</table>
|
|
307
|
+
<p><strong>No integration changes required.</strong> Response shape is unchanged — only the correctness of the returned message set improves.</p>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
</div>
|
|
312
|
+
</div><!-- /.wn-version -->
|
|
313
|
+
|
|
314
|
+
<!-- ── v1.3.3 ── -->
|
|
254
315
|
<div class="wn-version open" id="wn-133">
|
|
255
316
|
<div class="wn-header" onclick="toggleVersion('wn-133')">
|
|
256
317
|
<div class="wn-title">
|
|
257
318
|
<span class="wn-ver">v1.3.3</span>
|
|
258
|
-
<span class="wn-badge current">Current</span>
|
|
259
319
|
<span class="wn-date">June 2026</span>
|
|
260
320
|
</div>
|
|
261
321
|
<span class="wn-chevron">▲</span>
|
package/package.json
CHANGED