@antzsoft/chat-core 1.3.6 → 1.3.8

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 CHANGED
@@ -2656,6 +2656,7 @@ Returned by `messagesApi.getReceipts()`. Use as the initial load for a "Read by
2656
2656
  ```typescript
2657
2657
  interface MessageReceiptEntry {
2658
2658
  userId: string;
2659
+ externalId?: string; // external system user ID (non-builtin modes)
2659
2660
  displayName: string;
2660
2661
  avatarUrl?: string;
2661
2662
  }
@@ -2685,6 +2686,7 @@ Returned by `messagesApi.getReactions()`. Use as the data source for a reactions
2685
2686
  ```typescript
2686
2687
  interface ReactionUser {
2687
2688
  userId: string;
2689
+ externalId?: string; // external system user ID (non-builtin modes)
2688
2690
  displayName: string;
2689
2691
  avatarUrl?: string;
2690
2692
  }
@@ -2801,6 +2803,7 @@ interface MessageConfig {
2801
2803
  ```typescript
2802
2804
  interface Participant {
2803
2805
  userId: string;
2806
+ externalId?: string; // external system user ID (non-builtin modes); mirrored on user.externalId
2804
2807
  role: 'admin' | 'member';
2805
2808
  joinedAt: string;
2806
2809
  isActive?: boolean;
@@ -2893,6 +2896,7 @@ interface ReactionUpdatedEvent {
2893
2896
  interface TypingIndicatorEvent {
2894
2897
  conversationId: string;
2895
2898
  userId: string;
2899
+ externalId?: string; // external system user ID (non-builtin modes); absent in builtin mode
2896
2900
  username: string;
2897
2901
  displayName: string;
2898
2902
  avatarUrl?: string;
@@ -3056,6 +3060,34 @@ document.querySelectorAll('[data-conv-id]').forEach((el) => {
3056
3060
 
3057
3061
  ## Changelog
3058
3062
 
3063
+ ### v1.3.8
3064
+
3065
+ - **`externalId` now surfaced on every embedded user shape, not just the standalone user profile.** Previously `externalId` (the user's ID in your external system, non-builtin modes) was only present on `User` returned from `usersApi.list/getById/updateProfile`. Every *denormalized* place a user appeared — conversation participants, message sender, reaction users, and read/delivery receipts — dropped it, forcing a separate `usersApi.getById()` call to map a chat user back to your own system. Those shapes now carry `externalId`:
3066
+
3067
+ - **`Participant`** — new top-level `externalId?` field, also mirrored onto `Participant.user.externalId`. (`conversationsApi` + conversation socket events.)
3068
+ - **`Message.sender`** — now includes `externalId` (it is a `User`, so the field was always in the type; the server now populates it on the embed).
3069
+ - **`ReactionUser`** (`messagesApi.getReactions`) — new `externalId?`.
3070
+ - **`MessageReceiptEntry`** (`messagesApi.getReceipts`) — new `externalId?`.
3071
+ - **`TypingIndicatorEvent`** (socket) — new `externalId?`. Present in non-builtin modes; **absent in builtin mode**, where no external identity exists.
3072
+
3073
+ **Backward compatible, additive-only.** Every field is optional (`externalId?`). An older SDK against this server simply ignores the extra field; this SDK against an older server sees `externalId` as `undefined`. Note `externalId` (a string, the chat user's external identity) is distinct from the pre-existing `Participant`-level `externalUserId` (a number) — both are sent; do not confuse them. Requires server v-with-this-change or newer to be populated; safe to upgrade regardless. **No integration changes required** — read `externalId` where you previously had to look it up separately.
3074
+
3075
+ ### v1.3.7
3076
+
3077
+ - **Docs only — no code changes.** Brought the docs fully up to date: added the missing
3078
+ release notes to `docs/integration-guide.html` (its "What's New" section had stopped at
3079
+ v1.3.4) so both the README changelog and the HTML integration guide now cover v1.3.5,
3080
+ v1.3.6, and this v1.3.7 entry. No SDK behaviour changed in this version; upgrading from
3081
+ 1.3.6 is a no-op at runtime.
3082
+
3083
+ ### v1.3.6
3084
+
3085
+ - **Fix: `reconnectSocket` now PRESERVES the transit session instead of recreating it** — follow-up to the 1.3.5 reconnect fix. 1.3.5 fixed `"Transit encryption required"` by disconnecting and re-running the full `connectSocket()` handshake, but that also cleared the cached transit session (the `'disconnect'` handler calls `clearTransitSession()`) and established a brand-new one with a new session key. Server-broadcast events (e.g. `user_online`) are encrypted with the session the server still holds, so a fresh client key could not decrypt them → continuous `"Transit decryption failed for event: user_online"`.
3086
+
3087
+ `reconnectSocket` is a token-only refresh — the transit session is still valid on the server (stored in Redis by `sessionId`, re-linked to the new socket on reconnect). So it now carries the existing `transitSessionId` forward in the handshake auth and reconnects the **same** socket **without** disconnecting, keeping the client's session key intact. The server re-links the same session (`getBySessionId` + `linkSocket`), so both sides keep the same key and decryption continues to work. Falls back to the full `connectSocket()` flow only when there is no valid cached session to preserve.
3088
+
3089
+ Net: keeps 1.3.5's "no more `Transit encryption required` on reconnect" while removing the `user_online` decryption-failure regression. **No integration changes required.**
3090
+
3059
3091
  ### v1.3.5
3060
3092
 
3061
3093
  - **Fix: `reconnectSocket()` no longer drops the transit-encryption handshake** — when transit encryption is enabled, `reconnectSocket()` now delegates to the full `connectSocket()` flow instead of doing a bare `_socket.auth` swap. `reconnectSocket()` predates transit encryption and was never migrated: it overwrote `_socket.auth` with only `{ token, userId, tenantId }`, dropping the `transitSessionId` / `transitEphemeralPub` fields that `connectSocket()` sets during the handshake. Combined with the `'disconnect'` handler clearing the cached transit session, a reconnect after the socket had disconnected (e.g. app returning to foreground on iOS/Android, where backgrounding fully disconnects) went out with no transit auth and no cached session → the server rejected the handshake with **"Transit encryption required: missing transitEphemeralPub/transitAlgo in handshake auth"**. It was intermittent — fast devices whose cached transit session survived the reconnect were unaffected.
package/dist/index.cjs CHANGED
@@ -1105,11 +1105,13 @@ function normalizeParticipant(p) {
1105
1105
  const hasUserDetails = p.displayName || p.username || p.avatarUrl;
1106
1106
  return {
1107
1107
  userId: p.userId,
1108
+ externalId: p.externalId ?? p.user?.externalId,
1108
1109
  role: p.role,
1109
1110
  joinedAt: p.joinedAt,
1110
1111
  isActive: p.isActive,
1111
1112
  user: hasUserDetails ? {
1112
1113
  id: p.userId,
1114
+ externalId: p.externalId,
1113
1115
  tenantId: "",
1114
1116
  email: "",
1115
1117
  username: p.username ?? "",