@antzsoft/chat-core 1.1.2 → 1.1.3
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 +69 -5
- package/dist/index.cjs +88 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +88 -25
- package/dist/index.js.map +1 -1
- package/docs/integration-guide.html +191 -13
- package/package.json +1 -1
|
@@ -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.1.
|
|
158
|
+
<li><a href="#whats-new">v1.1.3 Release Notes</a></li>
|
|
159
159
|
</ul>
|
|
160
160
|
|
|
161
161
|
<div class="section-label">Getting Started</div>
|
|
@@ -242,11 +242,11 @@ section.sec>h2:hover{color:#fff}
|
|
|
242
242
|
<h2>What's New</h2>
|
|
243
243
|
<p style="color:var(--muted);font-size:13px;margin-bottom:20px">Version history and release notes. Click a version to expand.</p>
|
|
244
244
|
|
|
245
|
-
<!-- ── v1.1.
|
|
246
|
-
<div class="wn-version open" id="wn-
|
|
247
|
-
<div class="wn-header" onclick="toggleVersion('wn-
|
|
245
|
+
<!-- ── v1.1.3 (current) ── -->
|
|
246
|
+
<div class="wn-version open" id="wn-113">
|
|
247
|
+
<div class="wn-header" onclick="toggleVersion('wn-113')">
|
|
248
248
|
<div class="wn-title">
|
|
249
|
-
<span class="wn-ver">v1.1.
|
|
249
|
+
<span class="wn-ver">v1.1.3</span>
|
|
250
250
|
<span class="wn-badge current">Current</span>
|
|
251
251
|
<span class="wn-date">May 2026</span>
|
|
252
252
|
</div>
|
|
@@ -254,6 +254,139 @@ section.sec>h2:hover{color:#fff}
|
|
|
254
254
|
</div>
|
|
255
255
|
<div class="wn-body">
|
|
256
256
|
|
|
257
|
+
<div class="wn-item" id="wn-113-1">
|
|
258
|
+
<div class="wn-item-header" onclick="toggleItem('wn-113-1')">
|
|
259
|
+
<span class="wn-tag new">New</span>
|
|
260
|
+
<span class="wn-item-title">usersApi.updateProfile() — self-user profile update</span>
|
|
261
|
+
<span class="wn-chevron-sm">▾</span>
|
|
262
|
+
</div>
|
|
263
|
+
<div class="wn-item-body">
|
|
264
|
+
<p>The self user can now update their own profile (name, email, phone) instantly without waiting for the 2-hour background sync cycle.</p>
|
|
265
|
+
<pre><code><span class="kw">await</span> usersApi.<span class="fn">updateProfile</span>({ firstName: <span class="str">'Jane'</span>, lastName: <span class="str">'Smith'</span>, email: <span class="str">'jane@example.com'</span> });</code></pre>
|
|
266
|
+
<p><strong>Admin-updated fields (firstName, lastName) via external identity provider:</strong> the chat module will reflect those changes either on the next 2-hour sync or the next time the app initialises the chat client. Webhook-based instant sync will be introduced in a future release.</p>
|
|
267
|
+
<p class="wn-ref">→ <a href="#users-api">Users API</a> for the full reference</p>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<div class="wn-item" id="wn-113-2">
|
|
272
|
+
<div class="wn-item-header" onclick="toggleItem('wn-113-2')">
|
|
273
|
+
<span class="wn-tag new">New</span>
|
|
274
|
+
<span class="wn-item-title">Group icon — remove support</span>
|
|
275
|
+
<span class="wn-chevron-sm">▾</span>
|
|
276
|
+
</div>
|
|
277
|
+
<div class="wn-item-body">
|
|
278
|
+
<p>Admins can now remove a group icon in addition to setting or replacing one. Tapping the new <strong>✕</strong> button (top-right of the group avatar in Group Info) clears the icon immediately — the asset is deleted from storage and the conversation reverts to its initials avatar.</p>
|
|
279
|
+
<pre><code><span class="cm">// Remove icon — admin only</span>
|
|
280
|
+
<span class="kw">const</span> updated = <span class="kw">await</span> conversationsApi.<span class="fn">removeIcon</span>(groupId);
|
|
281
|
+
<span class="cm">// updated.iconUrl === undefined</span></code></pre>
|
|
282
|
+
<p>Like upload, remove is admin-only; non-admins receive <code>403 Forbidden</code>. No icon is ever left orphaned in storage.</p>
|
|
283
|
+
<p class="wn-ref">→ <a href="#step-convs">Step 6 — Conversations</a> (group icon section) for the full pipeline</p>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
|
|
287
|
+
<div class="wn-item" id="wn-113-3">
|
|
288
|
+
<div class="wn-item-header" onclick="toggleItem('wn-113-3')">
|
|
289
|
+
<span class="wn-tag new">New</span>
|
|
290
|
+
<span class="wn-item-title">Leave / Delete / Exit — WhatsApp-style behavior</span>
|
|
291
|
+
<span class="wn-chevron-sm">▾</span>
|
|
292
|
+
</div>
|
|
293
|
+
<div class="wn-item-body">
|
|
294
|
+
<p><code>leave(id)</code> exits a group but keeps it in the list (read-only). <code>leave(id, true)</code> exits and removes it atomically. <code>delete(id)</code> hides any conversation from the caller's list — no longer admin-only, works for DMs ("Delete Chat") and already-exited groups ("Delete Group"). When the last admin exits, the server auto-promotes the longest-standing member instead of returning <code>400</code>.</p>
|
|
295
|
+
<p class="wn-ref">→ <a href="#step-convs">Step 6 — Conversations</a> for code examples</p>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<div class="wn-item" id="wn-113-4">
|
|
300
|
+
<div class="wn-item-header" onclick="toggleItem('wn-113-4')">
|
|
301
|
+
<span class="wn-tag new">New</span>
|
|
302
|
+
<span class="wn-item-title">Message visibility windows — gap messages hidden after re-add</span>
|
|
303
|
+
<span class="wn-chevron-sm">▾</span>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="wn-item-body">
|
|
306
|
+
<p>Messages sent while a user was not a member (gap periods) are now always hidden. Re-adding after a plain exit preserves prior history; re-adding after "Exit and Delete" shows only messages from the re-add point. DM "Delete Chat" also resets the window — when the other party messages again, only new messages are visible. No client changes required.</p>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<div class="wn-item" id="wn-113-5">
|
|
311
|
+
<div class="wn-item-header" onclick="toggleItem('wn-113-5')">
|
|
312
|
+
<span class="wn-tag new">New</span>
|
|
313
|
+
<span class="wn-item-title">useConversations() — leaveGroup, leaveAndDeleteGroup, deleteConversation</span>
|
|
314
|
+
<span class="wn-chevron-sm">▾</span>
|
|
315
|
+
</div>
|
|
316
|
+
<div class="wn-item-body">
|
|
317
|
+
<p>Three new mutations added to <code>useConversations()</code> in both web and RN SDKs: <code>leaveGroup</code>, <code>leaveAndDeleteGroup</code>, and <code>deleteConversation</code> (RN) / <code>deleteGroup</code> (web). Cache is updated optimistically — no manual invalidation needed.</p>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
</div>
|
|
322
|
+
</div><!-- /.wn-version -->
|
|
323
|
+
|
|
324
|
+
<!-- ── v1.1.2 ── -->
|
|
325
|
+
<div class="wn-version" id="wn-112">
|
|
326
|
+
<div class="wn-header" onclick="toggleVersion('wn-112')">
|
|
327
|
+
<div class="wn-title">
|
|
328
|
+
<span class="wn-ver">v1.1.2</span>
|
|
329
|
+
<span class="wn-date">May 2026</span>
|
|
330
|
+
</div>
|
|
331
|
+
<span class="wn-chevron">▾</span>
|
|
332
|
+
</div>
|
|
333
|
+
<div class="wn-body">
|
|
334
|
+
|
|
335
|
+
<div class="wn-item" id="wn-112-0a">
|
|
336
|
+
<div class="wn-item-header" onclick="toggleItem('wn-112-0a')">
|
|
337
|
+
<span class="wn-tag new">New</span>
|
|
338
|
+
<span class="wn-item-title">usersApi.updateProfile() — immediate profile update</span>
|
|
339
|
+
<span class="wn-chevron-sm">▾</span>
|
|
340
|
+
</div>
|
|
341
|
+
<div class="wn-item-body">
|
|
342
|
+
<p>A new <code>usersApi.updateProfile(payload)</code> method lets the host app push profile field changes to the chat server immediately — without waiting for the next background sync cycle.</p>
|
|
343
|
+
<p>This is especially useful in <strong>non-builtin (external/SSO) modes</strong>: when the user updates their name or email in the main identity provider, the host app can call <code>updateProfile()</code> so the chat UI reflects the change right away rather than waiting up to 2 hours for the next cron sync.</p>
|
|
344
|
+
<pre><code><span class="kw">import</span> { usersApi } <span class="kw">from</span> <span class="str">'@antzsoft/chat-core'</span>;
|
|
345
|
+
|
|
346
|
+
<span class="kw">await</span> usersApi.<span class="fn">updateProfile</span>({
|
|
347
|
+
firstName: <span class="str">'Jane'</span>,
|
|
348
|
+
lastName: <span class="str">'Smith'</span>,
|
|
349
|
+
email: <span class="str">'jane@example.com'</span>,
|
|
350
|
+
displayName: <span class="str">'Jane S.'</span>, <span class="cm">// optional</span>
|
|
351
|
+
phone: <span class="str">'+919900000000'</span>,
|
|
352
|
+
});</code></pre>
|
|
353
|
+
<table>
|
|
354
|
+
<tr><th>Field</th><th>Builtin</th><th>Non-builtin</th></tr>
|
|
355
|
+
<tr><td><code>firstName</code>, <code>lastName</code>, <code>email</code></td><td>Written directly</td><td>Written immediately; may be overwritten on next sync if user-service returns different values</td></tr>
|
|
356
|
+
<tr><td><code>displayName</code>, <code>phone</code></td><td>Written directly</td><td>Written immediately</td></tr>
|
|
357
|
+
<tr><td><code>username</code>, <code>status</code></td><td colspan="2">Not allowed</td></tr>
|
|
358
|
+
</table>
|
|
359
|
+
<p><strong>Uniqueness:</strong> <code>email</code> and <code>phone</code> must each be unique within the tenant. A <code>409 Conflict</code> is returned if another user already holds the same value.</p>
|
|
360
|
+
<p class="wn-ref">→ <a href="#users-api">Users API</a> for the full reference</p>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
|
|
364
|
+
<div class="wn-item" id="wn-112-0b">
|
|
365
|
+
<div class="wn-item-header" onclick="toggleItem('wn-112-0b')">
|
|
366
|
+
<span class="wn-tag new">New</span>
|
|
367
|
+
<span class="wn-item-title">On-connect per-user profile sync</span>
|
|
368
|
+
<span class="wn-chevron-sm">▾</span>
|
|
369
|
+
</div>
|
|
370
|
+
<div class="wn-item-body">
|
|
371
|
+
<p>In non-builtin modes, <code>AntzChatClient.connect()</code> now triggers a fire-and-forget background sync of the current user's profile from the upstream user-service if the shadow record hasn't been synced in the last 6 hours.</p>
|
|
372
|
+
<p>Previously only the 2-hour bulk cron kept shadow records up to date. Now profile fields (<code>firstName</code>, <code>lastName</code>, <code>displayName</code>, <code>email</code>, <code>username</code>, <code>phone</code>, <code>status</code>) are refreshed on every fresh SDK initialisation, providing near-immediate consistency for users who reconnect after a period of inactivity.</p>
|
|
373
|
+
<p><strong>No client action required.</strong> This is handled automatically inside <code>connect()</code>.</p>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
<div class="wn-item" id="wn-112-0c">
|
|
378
|
+
<div class="wn-item-header" onclick="toggleItem('wn-112-0c')">
|
|
379
|
+
<span class="wn-tag new">New</span>
|
|
380
|
+
<span class="wn-item-title">Phone number uniqueness enforced per tenant</span>
|
|
381
|
+
<span class="wn-chevron-sm">▾</span>
|
|
382
|
+
</div>
|
|
383
|
+
<div class="wn-item-body">
|
|
384
|
+
<p><code>phone</code> is now unique within a tenant — the same phone number cannot be registered to two different users under the same tenant. A <code>409 Conflict</code> is returned on registration or profile update if the number is already in use.</p>
|
|
385
|
+
<p>Same-phone across different tenants is still allowed (a user can have the same phone in tenant A and tenant B).</p>
|
|
386
|
+
<p><strong>No client action required</strong> for existing data. New uniqueness is enforced at write time only.</p>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
257
390
|
<div class="wn-item" id="wn-112-1">
|
|
258
391
|
<div class="wn-item-header" onclick="toggleItem('wn-112-1')">
|
|
259
392
|
<span class="wn-tag new">New</span>
|
|
@@ -942,17 +1075,21 @@ section.sec>h2:hover{color:#fff}
|
|
|
942
1075
|
<div class="wn-item" id="wn-106-7">
|
|
943
1076
|
<div class="wn-item-header" onclick="toggleItem('wn-106-7')">
|
|
944
1077
|
<span class="wn-tag new">New</span>
|
|
945
|
-
<span class="wn-item-title">Group icon — create &
|
|
1078
|
+
<span class="wn-item-title">Group icon — create, update & remove</span>
|
|
946
1079
|
<span class="wn-chevron-sm">▾</span>
|
|
947
1080
|
</div>
|
|
948
1081
|
<div class="wn-item-body">
|
|
949
|
-
<p>Group conversations now support a custom icon. Admins can set or
|
|
1082
|
+
<p>Group conversations now support a custom icon. Admins can set, replace, or remove it at any time. The icon is stored server-side and a fresh signed URL is returned on every conversation response.</p>
|
|
950
1083
|
<pre><code><span class="cm">// Upload icon — admin only</span>
|
|
951
1084
|
<span class="kw">const</span> updated = <span class="kw">await</span> client.<span class="fn">uploadIcon</span>(groupId, {
|
|
952
1085
|
<span class="at">uri</span>: file.uri, <span class="at">name</span>: <span class="str">'icon.jpg'</span>, <span class="at">type</span>: <span class="str">'image/jpeg'</span>, <span class="at">size</span>: file.size,
|
|
953
1086
|
});
|
|
954
|
-
<span class="cm">// updated.iconUrl → fresh signed URL</span
|
|
955
|
-
|
|
1087
|
+
<span class="cm">// updated.iconUrl → fresh signed URL</span>
|
|
1088
|
+
|
|
1089
|
+
<span class="cm">// Remove icon — admin only</span>
|
|
1090
|
+
<span class="kw">const</span> noIcon = <span class="kw">await</span> conversationsApi.<span class="fn">removeIcon</span>(groupId);
|
|
1091
|
+
<span class="cm">// noIcon.iconUrl === undefined</span></code></pre>
|
|
1092
|
+
<p>Non-admins receive <code>403 Forbidden</code> on both operations. The URL is never stored in the DB — regenerated from <code>iconMeta.storageKey</code> on every response. Replacing or removing an icon automatically deletes the previous asset from storage.</p>
|
|
956
1093
|
<p class="wn-ref">→ <a href="#step-convs">Step 6 — Conversations</a> (group icon section) for the full upload pipeline</p>
|
|
957
1094
|
</div>
|
|
958
1095
|
</div>
|
|
@@ -1697,6 +1834,17 @@ chatClient.<span class="fn">disconnect</span>();
|
|
|
1697
1834
|
<span class="cm">// Search users by name / username / email</span>
|
|
1698
1835
|
<span class="kw">const</span> { data: results } = <span class="kw">await</span> usersApi.<span class="fn">list</span>({ <span class="at">query</span>: <span class="str">'john'</span> });
|
|
1699
1836
|
|
|
1837
|
+
<span class="cm">// Update current user's profile — works in both builtin and non-builtin modes.</span>
|
|
1838
|
+
<span class="cm">// In non-builtin modes use this to push a change immediately without waiting</span>
|
|
1839
|
+
<span class="cm">// for the next 2-hour background sync from the upstream user-service.</span>
|
|
1840
|
+
<span class="kw">await</span> usersApi.<span class="fn">updateProfile</span>({
|
|
1841
|
+
firstName: <span class="str">'Jane'</span>,
|
|
1842
|
+
lastName: <span class="str">'Smith'</span>,
|
|
1843
|
+
email: <span class="str">'jane@example.com'</span>, <span class="cm">// 409 if taken by another user in this tenant</span>
|
|
1844
|
+
displayName: <span class="str">'Jane S.'</span>,
|
|
1845
|
+
phone: <span class="str">'+919900000000'</span>, <span class="cm">// 409 if taken by another user in this tenant</span>
|
|
1846
|
+
});
|
|
1847
|
+
|
|
1700
1848
|
<span class="cm">// Create DM — returns existing if already exists</span>
|
|
1701
1849
|
<span class="kw">const</span> dm = <span class="kw">await</span> conversationsApi.<span class="fn">createDirect</span>({ <span class="at">userId</span>: <span class="str">'target-user-id'</span> });
|
|
1702
1850
|
|
|
@@ -1735,8 +1883,15 @@ chatClient.<span class="fn">disconnect</span>();
|
|
|
1735
1883
|
<span class="cm">// - iconMeta = { storageKey, provider, bucket, mimeType, size } embedded in conversation doc</span>
|
|
1736
1884
|
<span class="cm">// - Non-admins get 403 Forbidden at server level</span>
|
|
1737
1885
|
|
|
1886
|
+
<span class="cm">// Remove the group icon (admin only)</span>
|
|
1887
|
+
<span class="cm">// Deletes asset from storage + clears iconMeta. Returns conversation with iconUrl: undefined.</span>
|
|
1888
|
+
<span class="kw">const</span> noIcon = <span class="kw">await</span> conversationsApi.<span class="fn">removeIcon</span>(group.id);
|
|
1889
|
+
<span class="cm">// → DELETE /conversations/:id/icon</span>
|
|
1890
|
+
<span class="cm">// Server: validateAdmin() → deleteByKey(iconMeta.storageKey) → $unset iconMeta</span>
|
|
1891
|
+
<span class="cm">// noIcon.iconUrl === undefined</span>
|
|
1892
|
+
|
|
1738
1893
|
<span class="cm">// Web/RN SDK components (GroupInfoPanel, NewChatModal, ChatHeader) handle this automatically.</span>
|
|
1739
|
-
<span class="cm">// Camera button shown only to admins. No code needed in your app.</span>
|
|
1894
|
+
<span class="cm">// Camera button + remove (✕) button shown only to admins. No code needed in your app.</span>
|
|
1740
1895
|
|
|
1741
1896
|
<span class="cm">// Participants</span>
|
|
1742
1897
|
<span class="kw">const</span> members = <span class="kw">await</span> conversationsApi.<span class="fn">getMembers</span>(conversationId);
|
|
@@ -1745,11 +1900,34 @@ chatClient.<span class="fn">disconnect</span>();
|
|
|
1745
1900
|
<span class="kw">await</span> conversationsApi.<span class="fn">removeParticipant</span>(conversationId, <span class="str">'user-2'</span>);
|
|
1746
1901
|
<span class="kw">await</span> conversationsApi.<span class="fn">updateParticipantRole</span>(conversationId, <span class="str">'user-1'</span>, <span class="str">'admin'</span>);
|
|
1747
1902
|
|
|
1748
|
-
<span class="cm">// Pin · Mute
|
|
1903
|
+
<span class="cm">// Pin · Mute</span>
|
|
1749
1904
|
<span class="kw">await</span> conversationsApi.<span class="fn">pin</span>(conversationId); <span class="cm">// 400 if already at 5 pinned</span>
|
|
1750
1905
|
<span class="kw">await</span> conversationsApi.<span class="fn">mute</span>(conversationId, <span class="str">'2025-12-31T23:59:59Z'</span>); <span class="cm">// omit date = indefinite</span>
|
|
1751
|
-
|
|
1752
|
-
<span class="
|
|
1906
|
+
|
|
1907
|
+
<span class="cm">// ── 1:1 Chat ──────────────────────────────────────────────────────────────────</span>
|
|
1908
|
+
<span class="cm">// "Delete Chat" — hides from caller's list only. Other participant unaffected.</span>
|
|
1909
|
+
<span class="cm">// If the other person messages again the chat reappears, showing only new messages.</span>
|
|
1910
|
+
<span class="kw">await</span> conversationsApi.<span class="fn">delete</span>(dmConversationId);
|
|
1911
|
+
|
|
1912
|
+
<span class="cm">// ── Group Chat ─────────────────────────────────────────────────────────────────</span>
|
|
1913
|
+
<span class="cm">// "Exit Group" — leave but keep in list (read-only). Auto-promotes if last admin.</span>
|
|
1914
|
+
<span class="kw">await</span> conversationsApi.<span class="fn">leave</span>(groupId);
|
|
1915
|
+
|
|
1916
|
+
<span class="cm">// "Exit and Delete" — leave + remove from list atomically.</span>
|
|
1917
|
+
<span class="kw">await</span> conversationsApi.<span class="fn">leave</span>(groupId, <span class="kw">true</span>);
|
|
1918
|
+
|
|
1919
|
+
<span class="cm">// "Delete Group" — hide an already-exited group from the list. Any participant.</span>
|
|
1920
|
+
<span class="kw">await</span> conversationsApi.<span class="fn">delete</span>(groupId);</code></pre>
|
|
1921
|
+
|
|
1922
|
+
<div class="callout info">
|
|
1923
|
+
<strong>Leave / Delete semantics</strong>
|
|
1924
|
+
<ul style="margin:8px 0 0;padding-left:20px;line-height:1.7">
|
|
1925
|
+
<li><strong>Exit Group</strong> — <code>leave(id)</code>. Caller becomes inactive, stays in list read-only. If the caller is the only admin, the server auto-promotes the longest-standing active member before completing the exit.</li>
|
|
1926
|
+
<li><strong>Exit and Delete</strong> — <code>leave(id, true)</code>. Atomic: exit + hide from list in one server write. No race window.</li>
|
|
1927
|
+
<li><strong>Delete Group</strong> (after exit) — <code>delete(id)</code>. Caller must already be inactive. Hides from their list only. Any participant, no admin role required.</li>
|
|
1928
|
+
<li><strong>Delete Chat</strong> (1:1) — <code>delete(id)</code>. Hides from caller's list. DMs have no admin concept. When the other participant messages again, the chat reappears for the caller with only new messages visible.</li>
|
|
1929
|
+
</ul>
|
|
1930
|
+
</div>
|
|
1753
1931
|
|
|
1754
1932
|
<div class="callout info">
|
|
1755
1933
|
<strong>Pin limit — max 5</strong> — The server enforces a maximum of 5 pinned conversations per user. Attempting to pin a 6th returns <code>400 Bad Request</code>. Gate your UI before calling the API:
|
package/package.json
CHANGED