@manonero/chat-client-sdk 1.0.0-beta.3 → 1.0.0-beta.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.
Files changed (51) hide show
  1. package/README.md +196 -27
  2. package/dist/ChatClient.d.ts +67 -8
  3. package/dist/ChatClient.d.ts.map +1 -1
  4. package/dist/ChatClient.js +82 -9
  5. package/dist/ChatClient.js.map +1 -1
  6. package/dist/http/ConversationApi.d.ts +18 -1
  7. package/dist/http/ConversationApi.d.ts.map +1 -1
  8. package/dist/http/ConversationApi.js +23 -0
  9. package/dist/http/ConversationApi.js.map +1 -1
  10. package/dist/http/HttpClient.d.ts +18 -1
  11. package/dist/http/HttpClient.d.ts.map +1 -1
  12. package/dist/http/HttpClient.js +64 -13
  13. package/dist/http/HttpClient.js.map +1 -1
  14. package/dist/http/MessageApi.d.ts.map +1 -1
  15. package/dist/http/MessageApi.js +13 -2
  16. package/dist/http/MessageApi.js.map +1 -1
  17. package/dist/http/ProxyApi.d.ts +6 -5
  18. package/dist/http/ProxyApi.d.ts.map +1 -1
  19. package/dist/http/ProxyApi.js +15 -11
  20. package/dist/http/ProxyApi.js.map +1 -1
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/realtime/ChatHubClient.d.ts +58 -1
  26. package/dist/realtime/ChatHubClient.d.ts.map +1 -1
  27. package/dist/realtime/ChatHubClient.js +202 -15
  28. package/dist/realtime/ChatHubClient.js.map +1 -1
  29. package/dist/realtime/NotificationHubClient.d.ts +40 -0
  30. package/dist/realtime/NotificationHubClient.d.ts.map +1 -1
  31. package/dist/realtime/NotificationHubClient.js +131 -29
  32. package/dist/realtime/NotificationHubClient.js.map +1 -1
  33. package/dist/realtime/ReconnectionManager.d.ts +2 -1
  34. package/dist/realtime/ReconnectionManager.d.ts.map +1 -1
  35. package/dist/realtime/ReconnectionManager.js +13 -3
  36. package/dist/realtime/ReconnectionManager.js.map +1 -1
  37. package/dist/types/block.d.ts +17 -2
  38. package/dist/types/block.d.ts.map +1 -1
  39. package/dist/types/block.js +30 -0
  40. package/dist/types/block.js.map +1 -1
  41. package/dist/types/chat-events.d.ts +23 -3
  42. package/dist/types/chat-events.d.ts.map +1 -1
  43. package/dist/types/conversation.d.ts +52 -3
  44. package/dist/types/conversation.d.ts.map +1 -1
  45. package/dist/types/message.d.ts +5 -6
  46. package/dist/types/message.d.ts.map +1 -1
  47. package/dist/types/notification-events.d.ts +10 -7
  48. package/dist/types/notification-events.d.ts.map +1 -1
  49. package/dist/types/signalr.d.ts +2 -1
  50. package/dist/types/signalr.d.ts.map +1 -1
  51. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // index.ts — Public SDK API — re-exports everything
2
- // Block type guards
3
- export { isTextBlock, isImageBlock, isVideoBlock, isAudioBlock, isFileBlock, isLinkPreviewBlock, isEmbedBlock, isLocationBlock, isContactBlock, isChoiceBlock, isCardBlock, isCarouselBlock, isDividerBlock, isCustomBlock, } from './types/block.js';
2
+ // Block type guards + serialization helpers
3
+ export { isTextBlock, isImageBlock, isVideoBlock, isAudioBlock, isFileBlock, isLinkPreviewBlock, isEmbedBlock, isLocationBlock, isContactBlock, isChoiceBlock, isCardBlock, isCarouselBlock, isDividerBlock, isCustomBlock, withTypeFirst, normalizeBlocksForSend, } from './types/block.js';
4
4
  // Errors
5
5
  export { ChatApiError } from './errors/ChatApiError.js';
6
6
  // HTTP client
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAyEpD,oBAAoB;AACpB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,kBAAkB,CAAC;AA8D1B,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,4BAA4B;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,4BAA4B;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG5D,oCAAoC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,kCAAkC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAGxE,yCAAyC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD;AA6EpD,4CAA4C;AAC5C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAgE1B,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,4BAA4B;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,4BAA4B;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG5D,oCAAoC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,kCAAkC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAGxE,yCAAyC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { HubConnectionState, LogLevel } from '@microsoft/signalr';
2
2
  import type { Unsubscribe } from '../utils/TypedEventEmitter.js';
3
- import type { ChatMessageDto, MessageUpdatedDto, MessageDeletedDto, ReactionAddedDto, ReactionRemovedDto, TypingDto, ReadReceiptUpdatedDto, StreamStartedDto, StreamStatusUpdatedDto, StreamChunkReceivedDto, StreamCompletedDto, StreamAbortedDto } from '../types/chat-events.js';
3
+ import type { ChatMessageDto, MessageUpdatedDto, MessageDeletedDto, MessageThumbnailsReadyDto, ReactionAddedDto, ReactionRemovedDto, TypingDto, ReadReceiptUpdatedDto, StreamStartedDto, StreamStatusUpdatedDto, StreamChunkReceivedDto, StreamCompletedDto, StreamAbortedDto } from '../types/chat-events.js';
4
4
  import type { ChatSendMessageRequest, ChatEditMessageRequest, ChatDeleteMessageRequest, ChatRecoverMessageRequest, ChatAddReactionRequest, ChatRemoveReactionRequest, SendMessageAck, EditMessageAck, DeleteMessageAck, RecoverMessageAck, ReactionAck, MarkAsReadAck, HubErrorDto } from '../types/signalr.js';
5
5
  export interface ChatHubEventMap {
6
6
  messageReceived: ChatMessageDto;
@@ -8,6 +8,8 @@ export interface ChatHubEventMap {
8
8
  messageDeleted: MessageDeletedDto;
9
9
  /** Payload is full ChatMessageDto — same shape as messageReceived */
10
10
  messageRecovered: ChatMessageDto;
11
+ /** Server has finished generating thumbnails for media blocks — patch by blockIndex */
12
+ messageThumbnailsReady: MessageThumbnailsReadyDto;
11
13
  reactionAdded: ReactionAddedDto;
12
14
  reactionRemoved: ReactionRemovedDto;
13
15
  typingStarted: TypingDto;
@@ -44,29 +46,69 @@ export declare class ChatHubClient {
44
46
  private readonly options;
45
47
  private connection;
46
48
  private readonly emitter;
49
+ /** In-flight connect Promise, used to dedupe concurrent connect() calls. */
50
+ private connectingPromise;
51
+ /**
52
+ * True after a user-initiated disconnect() until the next connect() begins.
53
+ * ReconnectionManager uses this to skip auto-reconnect when the close was
54
+ * intentional rather than caused by a transport failure.
55
+ */
56
+ private _intentionallyClosed;
47
57
  /** Set of conversationIds that have been joined in the current session */
48
58
  readonly joinedConversations: Set<string>;
59
+ /**
60
+ * Tracks join attempts that resolved successfully but may still be revoked by
61
+ * a follow-up server `Error` event (FORBIDDEN/UNAUTHORIZED). Entries auto-expire
62
+ * after PENDING_JOIN_TTL_MS to bound memory.
63
+ */
64
+ private readonly pendingJoinAttempts;
65
+ private static readonly PENDING_JOIN_TTL_MS;
66
+ /** Server→client method names registered via conn.on() — used for cleanup. */
67
+ private static readonly HUB_EVENT_NAMES;
49
68
  constructor(options: ChatHubClientOptions);
50
69
  get state(): HubConnectionState;
70
+ /**
71
+ * True after a user-initiated disconnect() and until the next connect() starts.
72
+ * ReconnectionManager honors this to avoid reconnecting after an intentional close.
73
+ */
74
+ get intentionallyClosed(): boolean;
51
75
  /** Build a new HubConnection using the latest token from tokenProvider */
52
76
  private buildConnection;
53
77
  /** Attach SignalR server→client event handlers to the connection */
54
78
  private attachHandlers;
55
79
  /**
56
80
  * Connect to ChatHub. If already connected, resolves immediately.
81
+ * Concurrent calls share a single in-flight Promise — building two
82
+ * connections at once would leak handlers.
57
83
  * Builds a fresh connection using the current token.
84
+ *
85
+ * Throws synchronously when no authentication token is available so the
86
+ * caller gets a clear error rather than a malformed Authorization header.
58
87
  */
59
88
  connect(): Promise<void>;
60
89
  /**
61
90
  * Disconnect from ChatHub and clear joined conversation tracking.
91
+ * If a connect is in flight, it is awaited first so we always tear down a
92
+ * fully-formed connection (not a half-built one).
93
+ *
94
+ * Sets `intentionallyClosed` so ReconnectionManager skips its reconnect
95
+ * attempt for the resulting `disconnected` event.
62
96
  */
63
97
  disconnect(): Promise<void>;
98
+ /** Detach all server→client method handlers registered via attachHandlers(). */
99
+ private detachHandlers;
64
100
  private safeStop;
65
101
  /**
66
102
  * Re-join all tracked conversations. Called internally after reconnect.
67
103
  * Called by ReconnectionManager as well.
104
+ *
105
+ * If a rejoin fails with an access-denied style error (e.g. user was kicked
106
+ * between disconnect and reconnect), the conversation is purged from
107
+ * `joinedConversations` so we do not retry it forever on every reconnect.
108
+ * Other errors keep the entry — the next reconnect will try again.
68
109
  */
69
110
  rejoinConversations(): Promise<void>;
111
+ private isAccessDeniedError;
70
112
  private invokeHub;
71
113
  joinConversation(conversationId: string): Promise<void>;
72
114
  leaveConversation(conversationId: string): Promise<void>;
@@ -83,5 +125,20 @@ export declare class ChatHubClient {
83
125
  removeReaction(request: ChatRemoveReactionRequest): Promise<ReactionAck>;
84
126
  on<K extends keyof ChatHubEventMap>(event: K, handler: (payload: ChatHubEventMap[K]) => void): Unsubscribe;
85
127
  off<K extends keyof ChatHubEventMap>(event: K, handler: (payload: ChatHubEventMap[K]) => void): void;
128
+ private markJoinPending;
129
+ private clearPendingJoinAttempts;
130
+ private revertJoin;
131
+ /**
132
+ * If a server-emitted Error indicates a join was rejected, remove the
133
+ * conversation from `joinedConversations` to prevent auto-rejoin on reconnect.
134
+ *
135
+ * Strategy:
136
+ * 1. If `error.details.conversationId` is provided AND matches a pending
137
+ * join attempt → revert that one (most reliable signal).
138
+ * 2. Else, if the message matches the spec's documented FORBIDDEN text
139
+ * ("not a participant") AND there is exactly one pending join → revert it.
140
+ * 3. Otherwise do nothing — we cannot safely correlate the error to a join.
141
+ */
142
+ private handlePotentialJoinFailure;
86
143
  }
87
144
  //# sourceMappingURL=ChatHubClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatHubClient.d.ts","sourceRoot":"","sources":["../../src/realtime/ChatHubClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatHubClient.d.ts","sourceRoot":"","sources":["../../src/realtime/ChatHubClient.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  // realtime/ChatHubClient.ts — Manages ChatHub SignalR connection
2
2
  import { HubConnection, HubConnectionBuilder, HubConnectionState, LogLevel, } from '@microsoft/signalr';
3
3
  import { TypedEventEmitter as EventEmitter } from '../utils/TypedEventEmitter.js';
4
+ import { normalizeBlocksForSend } from '../types/block.js';
4
5
  // ---------------------------------------------------------------------------
5
6
  // ChatHubClient
6
7
  // ---------------------------------------------------------------------------
@@ -16,8 +17,22 @@ import { TypedEventEmitter as EventEmitter } from '../utils/TypedEventEmitter.js
16
17
  export class ChatHubClient {
17
18
  constructor(options) {
18
19
  this.connection = null;
20
+ /** In-flight connect Promise, used to dedupe concurrent connect() calls. */
21
+ this.connectingPromise = null;
22
+ /**
23
+ * True after a user-initiated disconnect() until the next connect() begins.
24
+ * ReconnectionManager uses this to skip auto-reconnect when the close was
25
+ * intentional rather than caused by a transport failure.
26
+ */
27
+ this._intentionallyClosed = false;
19
28
  /** Set of conversationIds that have been joined in the current session */
20
29
  this.joinedConversations = new Set();
30
+ /**
31
+ * Tracks join attempts that resolved successfully but may still be revoked by
32
+ * a follow-up server `Error` event (FORBIDDEN/UNAUTHORIZED). Entries auto-expire
33
+ * after PENDING_JOIN_TTL_MS to bound memory.
34
+ */
35
+ this.pendingJoinAttempts = new Map();
21
36
  this.options = options;
22
37
  this.emitter = new EventEmitter();
23
38
  }
@@ -27,6 +42,13 @@ export class ChatHubClient {
27
42
  get state() {
28
43
  return this.connection?.state ?? HubConnectionState.Disconnected;
29
44
  }
45
+ /**
46
+ * True after a user-initiated disconnect() and until the next connect() starts.
47
+ * ReconnectionManager honors this to avoid reconnecting after an intentional close.
48
+ */
49
+ get intentionallyClosed() {
50
+ return this._intentionallyClosed;
51
+ }
30
52
  // ---------------------------------------------------------------------------
31
53
  // Connection management
32
54
  // ---------------------------------------------------------------------------
@@ -35,7 +57,15 @@ export class ChatHubClient {
35
57
  const { hubUrl, tokenProvider, logLevel = LogLevel.Warning } = this.options;
36
58
  return new HubConnectionBuilder()
37
59
  .withUrl(hubUrl, {
38
- accessTokenFactory: () => tokenProvider() ?? '',
60
+ // Throw rather than return '' so SignalR fails the request loudly with
61
+ // a useful error instead of sending an empty `Authorization: Bearer ` header.
62
+ accessTokenFactory: () => {
63
+ const t = tokenProvider();
64
+ if (!t) {
65
+ throw new Error('ChatHub: no authentication token available');
66
+ }
67
+ return t;
68
+ },
39
69
  })
40
70
  .withAutomaticReconnect()
41
71
  .configureLogging(logLevel)
@@ -48,6 +78,7 @@ export class ChatHubClient {
48
78
  conn.on('MessageUpdated', (dto) => this.emitter.emit('messageUpdated', dto));
49
79
  conn.on('MessageDeleted', (dto) => this.emitter.emit('messageDeleted', dto));
50
80
  conn.on('MessageRecovered', (msg) => this.emitter.emit('messageRecovered', msg));
81
+ conn.on('MessageThumbnailsReady', (dto) => this.emitter.emit('messageThumbnailsReady', dto));
51
82
  // Reaction events
52
83
  conn.on('ReactionAdded', (dto) => this.emitter.emit('reactionAdded', dto));
53
84
  conn.on('ReactionRemoved', (dto) => this.emitter.emit('reactionRemoved', dto));
@@ -62,8 +93,11 @@ export class ChatHubClient {
62
93
  conn.on('StreamChunkReceived', (dto) => this.emitter.emit('streamChunkReceived', dto));
63
94
  conn.on('StreamCompleted', (dto) => this.emitter.emit('streamCompleted', dto));
64
95
  conn.on('StreamAborted', (dto) => this.emitter.emit('streamAborted', dto));
65
- // Hub errors (server→client)
66
- conn.on('Error', (error) => this.emitter.emit('error', error));
96
+ // Hub errors (server→client) — also revert pending joins on FORBIDDEN/UNAUTHORIZED
97
+ conn.on('Error', (error) => {
98
+ this.handlePotentialJoinFailure(error);
99
+ this.emitter.emit('error', error);
100
+ });
67
101
  // Connection lifecycle
68
102
  conn.onreconnecting((err) => this.emitter.emit('reconnecting', err));
69
103
  conn.onreconnected((connectionId) => {
@@ -77,32 +111,84 @@ export class ChatHubClient {
77
111
  }
78
112
  /**
79
113
  * Connect to ChatHub. If already connected, resolves immediately.
114
+ * Concurrent calls share a single in-flight Promise — building two
115
+ * connections at once would leak handlers.
80
116
  * Builds a fresh connection using the current token.
117
+ *
118
+ * Throws synchronously when no authentication token is available so the
119
+ * caller gets a clear error rather than a malformed Authorization header.
81
120
  */
82
121
  async connect() {
83
122
  if (this.connection && this.connection.state === HubConnectionState.Connected) {
84
123
  return;
85
124
  }
86
- // Disconnect existing stale connection cleanly
87
- if (this.connection) {
88
- await this.safeStop();
125
+ if (this.connectingPromise) {
126
+ return this.connectingPromise;
89
127
  }
90
- const conn = this.buildConnection();
91
- this.attachHandlers(conn);
92
- this.connection = conn;
93
- await conn.start();
128
+ if (!this.options.tokenProvider()) {
129
+ throw new Error('ChatHubClient.connect(): no authentication token available. ' +
130
+ 'Provide one via ChatClient.setToken() or the tokenProvider option.');
131
+ }
132
+ // The user is explicitly opening a connection — clear any prior
133
+ // intentional-close flag so ReconnectionManager will manage future drops.
134
+ this._intentionallyClosed = false;
135
+ const promise = (async () => {
136
+ try {
137
+ // Disconnect existing stale connection cleanly
138
+ if (this.connection) {
139
+ await this.safeStop();
140
+ }
141
+ const conn = this.buildConnection();
142
+ this.attachHandlers(conn);
143
+ this.connection = conn;
144
+ await conn.start();
145
+ }
146
+ finally {
147
+ this.connectingPromise = null;
148
+ }
149
+ })();
150
+ this.connectingPromise = promise;
151
+ return promise;
94
152
  }
95
153
  /**
96
154
  * Disconnect from ChatHub and clear joined conversation tracking.
155
+ * If a connect is in flight, it is awaited first so we always tear down a
156
+ * fully-formed connection (not a half-built one).
157
+ *
158
+ * Sets `intentionallyClosed` so ReconnectionManager skips its reconnect
159
+ * attempt for the resulting `disconnected` event.
97
160
  */
98
161
  async disconnect() {
162
+ // Mark intentional BEFORE awaiting the in-flight connect so any
163
+ // disconnected events that fire during teardown are not auto-reconnected.
164
+ this._intentionallyClosed = true;
165
+ if (this.connectingPromise) {
166
+ try {
167
+ await this.connectingPromise;
168
+ }
169
+ catch {
170
+ // The connect failed — there's nothing established to tear down,
171
+ // but still proceed to clear local state below.
172
+ }
173
+ }
99
174
  this.joinedConversations.clear();
175
+ this.clearPendingJoinAttempts();
100
176
  await this.safeStop();
101
177
  this.connection = null;
102
178
  }
179
+ /** Detach all server→client method handlers registered via attachHandlers(). */
180
+ detachHandlers(conn) {
181
+ for (const name of ChatHubClient.HUB_EVENT_NAMES) {
182
+ conn.off(name);
183
+ }
184
+ }
103
185
  async safeStop() {
186
+ if (!this.connection)
187
+ return;
188
+ // Detach handlers first so any late events on this connection are dropped.
189
+ this.detachHandlers(this.connection);
104
190
  try {
105
- await this.connection?.stop();
191
+ await this.connection.stop();
106
192
  }
107
193
  catch {
108
194
  // Ignore errors during stop
@@ -111,6 +197,11 @@ export class ChatHubClient {
111
197
  /**
112
198
  * Re-join all tracked conversations. Called internally after reconnect.
113
199
  * Called by ReconnectionManager as well.
200
+ *
201
+ * If a rejoin fails with an access-denied style error (e.g. user was kicked
202
+ * between disconnect and reconnect), the conversation is purged from
203
+ * `joinedConversations` so we do not retry it forever on every reconnect.
204
+ * Other errors keep the entry — the next reconnect will try again.
114
205
  */
115
206
  async rejoinConversations() {
116
207
  const ids = Array.from(this.joinedConversations);
@@ -118,11 +209,23 @@ export class ChatHubClient {
118
209
  try {
119
210
  await this.invokeHub('JoinConversation', id);
120
211
  }
121
- catch {
122
- // Best-effort
212
+ catch (err) {
213
+ if (this.isAccessDeniedError(err)) {
214
+ this.joinedConversations.delete(id);
215
+ }
216
+ // Other errors: keep tracking so a later reconnect retries.
123
217
  }
124
218
  }
125
219
  }
220
+ isAccessDeniedError(err) {
221
+ if (!(err instanceof Error))
222
+ return false;
223
+ const msg = err.message.toLowerCase();
224
+ return (msg.includes('forbidden') ||
225
+ msg.includes('not a participant') ||
226
+ msg.includes('unauthorized') ||
227
+ msg.includes('access denied'));
228
+ }
126
229
  // ---------------------------------------------------------------------------
127
230
  // Hub Methods (Client → Server)
128
231
  // ---------------------------------------------------------------------------
@@ -135,6 +238,8 @@ export class ChatHubClient {
135
238
  async joinConversation(conversationId) {
136
239
  await this.invokeHub('JoinConversation', conversationId);
137
240
  this.joinedConversations.add(conversationId);
241
+ // Track as pending so a follow-up FORBIDDEN/UNAUTHORIZED Error event can revert it.
242
+ this.markJoinPending(conversationId);
138
243
  }
139
244
  async leaveConversation(conversationId) {
140
245
  await this.invokeHub('LeaveConversation', conversationId);
@@ -150,10 +255,20 @@ export class ChatHubClient {
150
255
  return this.invokeHub('MarkAsRead', conversationId, messageId);
151
256
  }
152
257
  async sendMessage(request) {
153
- return this.invokeHub('SendMessage', request);
258
+ // Spec §6: `$type` must be the first property in each block when sent to
259
+ // the server, otherwise the polymorphic deserializer rejects the payload.
260
+ const normalized = {
261
+ ...request,
262
+ blocks: normalizeBlocksForSend(request.blocks),
263
+ };
264
+ return this.invokeHub('SendMessage', normalized);
154
265
  }
155
266
  async editMessage(request) {
156
- return this.invokeHub('EditMessage', request);
267
+ const normalized = {
268
+ ...request,
269
+ newBlocks: normalizeBlocksForSend(request.newBlocks),
270
+ };
271
+ return this.invokeHub('EditMessage', normalized);
157
272
  }
158
273
  /** Server expects an object { messageId }, not a bare string */
159
274
  async deleteMessage(request) {
@@ -178,5 +293,77 @@ export class ChatHubClient {
178
293
  off(event, handler) {
179
294
  this.emitter.off(event, handler);
180
295
  }
296
+ // ---------------------------------------------------------------------------
297
+ // Pending join cleanup — guards against the spec edge case where the server
298
+ // accepts the JoinConversation invoke but later rejects via an `Error` event
299
+ // (e.g. FORBIDDEN — user is not a participant). Without this, the conversation
300
+ // would stay in `joinedConversations` and be wrongly auto-rejoined on reconnect.
301
+ // ---------------------------------------------------------------------------
302
+ markJoinPending(conversationId) {
303
+ const existing = this.pendingJoinAttempts.get(conversationId);
304
+ if (existing)
305
+ clearTimeout(existing);
306
+ const timer = setTimeout(() => this.pendingJoinAttempts.delete(conversationId), ChatHubClient.PENDING_JOIN_TTL_MS);
307
+ this.pendingJoinAttempts.set(conversationId, timer);
308
+ }
309
+ clearPendingJoinAttempts() {
310
+ for (const timer of this.pendingJoinAttempts.values())
311
+ clearTimeout(timer);
312
+ this.pendingJoinAttempts.clear();
313
+ }
314
+ revertJoin(conversationId) {
315
+ this.joinedConversations.delete(conversationId);
316
+ const timer = this.pendingJoinAttempts.get(conversationId);
317
+ if (timer)
318
+ clearTimeout(timer);
319
+ this.pendingJoinAttempts.delete(conversationId);
320
+ }
321
+ /**
322
+ * If a server-emitted Error indicates a join was rejected, remove the
323
+ * conversation from `joinedConversations` to prevent auto-rejoin on reconnect.
324
+ *
325
+ * Strategy:
326
+ * 1. If `error.details.conversationId` is provided AND matches a pending
327
+ * join attempt → revert that one (most reliable signal).
328
+ * 2. Else, if the message matches the spec's documented FORBIDDEN text
329
+ * ("not a participant") AND there is exactly one pending join → revert it.
330
+ * 3. Otherwise do nothing — we cannot safely correlate the error to a join.
331
+ */
332
+ handlePotentialJoinFailure(error) {
333
+ if (error.code !== 'FORBIDDEN' && error.code !== 'UNAUTHORIZED')
334
+ return;
335
+ const detailsConvId = error.details && typeof error.details === 'object'
336
+ ? error.details.conversationId
337
+ : undefined;
338
+ if (typeof detailsConvId === 'string' && this.pendingJoinAttempts.has(detailsConvId)) {
339
+ this.revertJoin(detailsConvId);
340
+ return;
341
+ }
342
+ if (/not a participant/i.test(error.message) && this.pendingJoinAttempts.size === 1) {
343
+ const onlyId = this.pendingJoinAttempts.keys().next().value;
344
+ if (onlyId)
345
+ this.revertJoin(onlyId);
346
+ }
347
+ }
181
348
  }
349
+ ChatHubClient.PENDING_JOIN_TTL_MS = 2000;
350
+ /** Server→client method names registered via conn.on() — used for cleanup. */
351
+ ChatHubClient.HUB_EVENT_NAMES = [
352
+ 'MessageReceived',
353
+ 'MessageUpdated',
354
+ 'MessageDeleted',
355
+ 'MessageRecovered',
356
+ 'MessageThumbnailsReady',
357
+ 'ReactionAdded',
358
+ 'ReactionRemoved',
359
+ 'TypingStarted',
360
+ 'TypingStopped',
361
+ 'ReadReceiptUpdated',
362
+ 'StreamStarted',
363
+ 'StreamStatusUpdated',
364
+ 'StreamChunkReceived',
365
+ 'StreamCompleted',
366
+ 'StreamAborted',
367
+ 'Error',
368
+ ];
182
369
  //# sourceMappingURL=ChatHubClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatHubClient.js","sourceRoot":"","sources":["../../src/realtime/ChatHubClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatHubClient.js","sourceRoot":"","sources":["../../src/realtime/ChatHubClient.ts"],"names":[],"mappings":"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"}
@@ -43,31 +43,71 @@ export declare class NotificationHubClient {
43
43
  private readonly options;
44
44
  private connection;
45
45
  private readonly emitter;
46
+ /** In-flight connect Promise, used to dedupe concurrent connect() calls. */
47
+ private connectingPromise;
48
+ /**
49
+ * True after a user-initiated disconnect() until the next connect() begins.
50
+ * ReconnectionManager uses this to skip auto-reconnect when the close was
51
+ * intentional rather than caused by a transport failure.
52
+ */
53
+ private _intentionallyClosed;
46
54
  /** Set of participantIds currently subscribed to presence updates */
47
55
  readonly subscribedPresenceIds: Set<string>;
56
+ /** Server-imposed maximum batch size for SubscribeToPresence / UnsubscribeFromPresence. */
57
+ private static readonly PRESENCE_BATCH_SIZE;
58
+ /** Server→client method names registered via conn.on() — used for cleanup. */
59
+ private static readonly HUB_EVENT_NAMES;
48
60
  constructor(options: NotificationHubClientOptions);
49
61
  get state(): HubConnectionState;
62
+ /**
63
+ * True after a user-initiated disconnect() and until the next connect() starts.
64
+ * ReconnectionManager honors this to avoid reconnecting after an intentional close.
65
+ */
66
+ get intentionallyClosed(): boolean;
50
67
  /** Build a new HubConnection using the latest token from tokenProvider */
51
68
  private buildConnection;
52
69
  /** Attach SignalR server→client event handlers to the connection */
53
70
  private attachHandlers;
54
71
  /**
55
72
  * Connect to NotificationHub. If already connected, resolves immediately.
73
+ * Concurrent calls share a single in-flight Promise — building two
74
+ * connections at once would leak handlers.
56
75
  * Connecting automatically marks the user as online on the server.
76
+ *
77
+ * Throws synchronously when no authentication token is available so the
78
+ * caller gets a clear error rather than a malformed Authorization header.
57
79
  */
58
80
  connect(): Promise<void>;
59
81
  /**
60
82
  * Disconnect from NotificationHub. Automatically marks user as offline (server-side).
83
+ * If a connect is in flight, it is awaited first so we always tear down a
84
+ * fully-formed connection (not a half-built one).
85
+ *
86
+ * Sets `intentionallyClosed` so ReconnectionManager skips its reconnect
87
+ * attempt for the resulting `disconnected` event.
61
88
  */
62
89
  disconnect(): Promise<void>;
90
+ /** Detach all server→client method handlers registered via attachHandlers(). */
91
+ private detachHandlers;
63
92
  private safeStop;
64
93
  /**
65
94
  * Re-subscribe to all tracked presence participant IDs.
66
95
  * Called internally after reconnect. Also callable by ReconnectionManager.
96
+ * Best-effort — never throws.
67
97
  */
68
98
  resubscribePresence(): Promise<void>;
69
99
  private invokeHub;
100
+ /**
101
+ * Subscribe to presence updates for the given participants.
102
+ * Auto-batches in chunks of 200 to respect the server limit; if a batch
103
+ * fails partway through, prior batches remain subscribed and the error is
104
+ * propagated to the caller.
105
+ */
70
106
  subscribeToPresence(participantIds: string[]): Promise<void>;
107
+ /**
108
+ * Unsubscribe from presence updates for the given participants.
109
+ * Auto-batches in chunks of 200 to respect the server limit.
110
+ */
71
111
  unsubscribeFromPresence(participantIds: string[]): Promise<void>;
72
112
  on<K extends keyof NotificationHubEventMap>(event: K, handler: (payload: NotificationHubEventMap[K]) => void): Unsubscribe;
73
113
  off<K extends keyof NotificationHubEventMap>(event: K, handler: (payload: NotificationHubEventMap[K]) => void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationHubClient.d.ts","sourceRoot":"","sources":["../../src/realtime/NotificationHubClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,kBAAkB,EAClB,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEpF,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,MAAM,WAAW,uBAAuB;IAEtC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,eAAe,EAAE,kBAAkB,CAAC;IAGpC,sBAAsB,EAAE,yBAAyB,CAAC;IAClD,qBAAqB,EAAE,wBAAwB,CAAC;IAChD,kBAAkB,EAAE,qBAAqB,CAAC;IAG1C,mBAAmB,EAAE,sBAAsB,CAAC;IAC5C,mBAAmB,EAAE,sBAAsB,CAAC;IAC5C,iBAAiB,EAAE,oBAAoB,CAAC;IACxC,eAAe,EAAE,kBAAkB,CAAC;IACpC,kBAAkB,EAAE,qBAAqB,CAAC;IAC1C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,iBAAiB,EAAE,oBAAoB,CAAC;IAGxC,mBAAmB,EAAE,sBAAsB,CAAC;IAC5C,oBAAoB,EAAE,uBAAuB,CAAC;IAG9C,KAAK,EAAE,WAAW,CAAC;IAGnB,YAAY,EAAE,KAAK,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,KAAK,GAAG,SAAS,CAAC;CACjC;AAMD,MAAM,WAAW,4BAA4B;IAC3C,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,aAAa,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACnC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAMD;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IAErE,qEAAqE;IACrE,QAAQ,CAAC,qBAAqB,cAAqB;gBAEvC,OAAO,EAAE,4BAA4B;IASjD,IAAI,KAAK,IAAI,kBAAkB,CAE9B;IAMD,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IAWvB,oEAAoE;IACpE,OAAO,CAAC,cAAc;IAkDtB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAMnB,QAAQ;IAQtB;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;YAiB5B,SAAS;IASjB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5D,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IActE,EAAE,CAAC,CAAC,SAAS,MAAM,uBAAuB,EACxC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAAK,IAAI,GACrD,WAAW;IAId,GAAG,CAAC,CAAC,SAAS,MAAM,uBAAuB,EACzC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAAK,IAAI,GACrD,IAAI;CAGR"}
1
+ {"version":3,"file":"NotificationHubClient.d.ts","sourceRoot":"","sources":["../../src/realtime/NotificationHubClient.ts"],"names":[],"mappings":"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"}