@twilio/conversations 2.0.1-rc.9 → 2.1.0-rc.5

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 (88) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/NOTICE.txt +679 -0
  3. package/builds/browser.js +892 -619
  4. package/builds/browser.js.map +1 -1
  5. package/builds/lib.d.ts +371 -124
  6. package/builds/lib.js +892 -619
  7. package/builds/lib.js.map +1 -1
  8. package/builds/twilio-conversations.js +1067 -939
  9. package/builds/twilio-conversations.min.js +2 -14
  10. package/dist/aggregated-delivery-receipt.js +6 -1
  11. package/dist/aggregated-delivery-receipt.js.map +1 -1
  12. package/dist/client.js +165 -142
  13. package/dist/client.js.map +1 -1
  14. package/dist/command-executor.js +16 -14
  15. package/dist/command-executor.js.map +1 -1
  16. package/dist/configuration.js +14 -10
  17. package/dist/configuration.js.map +1 -1
  18. package/dist/conversation.js +232 -159
  19. package/dist/conversation.js.map +1 -1
  20. package/dist/data/conversations.js +82 -78
  21. package/dist/data/conversations.js.map +1 -1
  22. package/dist/data/messages.js +43 -39
  23. package/dist/data/messages.js.map +1 -1
  24. package/dist/data/participants.js +100 -78
  25. package/dist/data/participants.js.map +1 -1
  26. package/dist/data/users.js +24 -22
  27. package/dist/data/users.js.map +1 -1
  28. package/dist/detailed-delivery-receipt.js +1 -1
  29. package/dist/detailed-delivery-receipt.js.map +1 -1
  30. package/dist/index.js +1 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/interfaces/attributes.js +147 -0
  33. package/dist/interfaces/attributes.js.map +1 -0
  34. package/dist/interfaces/notification-types.js +5 -5
  35. package/dist/interfaces/notification-types.js.map +1 -1
  36. package/dist/logger.js +36 -15
  37. package/dist/logger.js.map +1 -1
  38. package/dist/media.js +21 -9
  39. package/dist/media.js.map +1 -1
  40. package/dist/message-builder.js +56 -3
  41. package/dist/message-builder.js.map +1 -1
  42. package/dist/message.js +158 -78
  43. package/dist/message.js.map +1 -1
  44. package/dist/packages/conversations/package.json.js +1 -1
  45. package/dist/participant.js +101 -50
  46. package/dist/participant.js.map +1 -1
  47. package/dist/push-notification.js.map +1 -1
  48. package/dist/rest-paginator.js +16 -6
  49. package/dist/rest-paginator.js.map +1 -1
  50. package/dist/services/network.js +18 -14
  51. package/dist/services/network.js.map +1 -1
  52. package/dist/services/typing-indicator.js +20 -17
  53. package/dist/services/typing-indicator.js.map +1 -1
  54. package/dist/unsent-message.js.map +1 -1
  55. package/dist/user.js +87 -60
  56. package/dist/user.js.map +1 -1
  57. package/dist/util/deferred.js +3 -1
  58. package/dist/util/deferred.js.map +1 -1
  59. package/dist/util/index.js +6 -6
  60. package/dist/util/index.js.map +1 -1
  61. package/docs/assets/js/search.js +1 -1
  62. package/docs/classes/AggregatedDeliveryReceipt.html +15 -0
  63. package/docs/classes/Client.html +39 -30
  64. package/docs/classes/Conversation.html +52 -30
  65. package/docs/classes/DetailedDeliveryReceipt.html +16 -1
  66. package/docs/classes/Media.html +15 -0
  67. package/docs/classes/Message.html +88 -7
  68. package/docs/classes/MessageBuilder.html +93 -2
  69. package/docs/classes/Participant.html +52 -8
  70. package/docs/classes/PushNotification.html +15 -0
  71. package/docs/classes/RestPaginator.html +15 -0
  72. package/docs/classes/UnsentMessage.html +15 -0
  73. package/docs/classes/User.html +22 -7
  74. package/docs/index.html +37 -3
  75. package/docs/interfaces/ClientOptions.html +15 -0
  76. package/docs/interfaces/ConversationBindings.html +3118 -0
  77. package/docs/interfaces/ConversationEmailBinding.html +3118 -0
  78. package/docs/interfaces/ConversationState.html +15 -0
  79. package/docs/interfaces/CreateConversationOptions.html +16 -1
  80. package/docs/interfaces/LastMessage.html +15 -0
  81. package/docs/interfaces/Paginator.html +15 -0
  82. package/docs/interfaces/ParticipantBindings.html +3118 -0
  83. package/docs/interfaces/ParticipantEmailBinding.html +3118 -0
  84. package/docs/interfaces/PushNotificationData.html +15 -0
  85. package/docs/interfaces/SendEmailOptions.html +15 -0
  86. package/docs/interfaces/SendMediaOptions.html +15 -0
  87. package/docs/modules.html +37 -3
  88. package/package.json +24 -18
@@ -141,7 +141,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
141
141
 
142
142
  var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
143
143
 
144
- const log = logger.Logger.scope('Conversations');
144
+ const log = logger.Logger.scope("Conversations");
145
145
  /**
146
146
  * Represents conversations collection
147
147
  * {@see Conversation}
@@ -158,13 +158,13 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
158
158
  }
159
159
  async addConversation(options) {
160
160
  var _a, _b, _c;
161
- const attributes = typeof (options === null || options === void 0 ? void 0 : options.attributes) !== 'undefined'
162
- ? options.attributes
163
- : {};
164
- const response = await this.services.commandExecutor.mutateResource('post', this.configuration.links.conversations, {
161
+ const attributes = typeof (options === null || options === void 0 ? void 0 : options.attributes) !== "undefined" ? options.attributes : {};
162
+ const response = await this.services.commandExecutor.mutateResource("post", this.configuration.links.conversations, {
165
163
  friendly_name: options.friendlyName,
166
164
  unique_name: options.uniqueName,
167
- attributes: typeof attributes !== 'undefined' ? JSON.stringify(attributes) : undefined
165
+ attributes: typeof attributes !== "undefined"
166
+ ? JSON.stringify(attributes)
167
+ : undefined,
168
168
  });
169
169
  const conversationSid = (_a = response.sid) !== null && _a !== void 0 ? _a : null;
170
170
  const conversationDocument = (_c = (_b = response.sync_objects) === null || _b === void 0 ? void 0 : _b.conversation) !== null && _c !== void 0 ? _c : null;
@@ -176,19 +176,19 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
176
176
  }
177
177
  const conversation$1 = new conversation.Conversation({
178
178
  channel: conversationDocument,
179
- entityName: null,
180
- uniqueName: null,
179
+ entityName: "",
180
+ uniqueName: "",
181
181
  attributes: null,
182
- createdBy: null,
183
- friendlyName: null,
184
- lastConsumedMessageIndex: null,
182
+ createdBy: "",
183
+ friendlyName: "",
184
+ lastConsumedMessageIndex: 0,
185
185
  dateCreated: null,
186
- dateUpdated: null
186
+ dateUpdated: null,
187
187
  }, conversationSid, links, this.configuration, this.services);
188
188
  this.conversations.set(conversation$1.sid, conversation$1);
189
189
  this._registerForEvents(conversation$1);
190
190
  await conversation$1._subscribe();
191
- this.emit('conversationAdded', conversation$1);
191
+ this.emit("conversationAdded", conversation$1);
192
192
  return conversation$1;
193
193
  }
194
194
  /**
@@ -197,11 +197,11 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
197
197
  async fetchConversations() {
198
198
  try {
199
199
  const map = await this._getMap();
200
- map.on('itemAdded', args => {
200
+ map.on("itemAdded", (args) => {
201
201
  log.debug(`itemAdded: ${args.item.key}`);
202
- this._upsertConversation('sync', args.item.key, args.item.data);
202
+ this._upsertConversation("sync", args.item.key, args.item.data);
203
203
  });
204
- map.on('itemRemoved', args => {
204
+ map.on("itemRemoved", (args) => {
205
205
  log.debug(`itemRemoved: ${args.key}`);
206
206
  const sid = args.key;
207
207
  if (!this.myConversationsFetched) {
@@ -211,48 +211,48 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
211
211
  if (!conversation) {
212
212
  return;
213
213
  }
214
- if (conversation.status === 'joined') {
215
- conversation._setStatus('notParticipating', 'sync');
216
- this.emit('conversationLeft', conversation);
214
+ if (conversation.status === "joined") {
215
+ conversation._setStatus("notParticipating", "sync");
216
+ this.emit("conversationLeft", conversation);
217
217
  }
218
218
  this.conversations.delete(sid);
219
- this.emit('conversationRemoved', conversation);
220
- conversation.emit('removed', conversation);
219
+ this.emit("conversationRemoved", conversation);
220
+ conversation.emit("removed", conversation);
221
221
  });
222
- map.on('itemUpdated', args => {
222
+ map.on("itemUpdated", (args) => {
223
223
  log.debug(`itemUpdated: ${args.item.key}`);
224
- this._upsertConversation('sync', args.item.key, args.item.data);
224
+ this._upsertConversation("sync", args.item.key, args.item.data);
225
225
  });
226
226
  const myConversations = await this._fetchMyConversations();
227
227
  const upserts = [];
228
228
  for (const conversation of myConversations) {
229
- upserts.push(this._upsertConversation('rest', conversation.channel_sid, conversation));
229
+ upserts.push(this._upsertConversation("rest", conversation["channel_sid"], conversation));
230
230
  }
231
231
  this.myConversationsRead.set(true);
232
232
  await Promise.all(upserts);
233
233
  this.myConversationsFetched = true;
234
234
  this.tombstones.clear();
235
- log.debug('The conversations list has been successfully fetched');
235
+ log.debug("The conversations list has been successfully fetched");
236
236
  return this;
237
237
  }
238
238
  catch (error) {
239
- const errorMessage = 'Failed to fetch the conversations list';
240
- if (this.services.syncClient.connectionState !== 'disconnected') {
239
+ const errorMessage = "Failed to fetch the conversations list";
240
+ if (this.services.syncClient.connectionState !== "disconnected") {
241
241
  log.error(errorMessage, error);
242
242
  }
243
243
  log.debug(`ERROR: ${errorMessage}`, error);
244
244
  throw error;
245
245
  }
246
246
  }
247
- async getConversations(args) {
247
+ async getConversations() {
248
248
  const conversationsMap = await this._getMap();
249
249
  const page = await conversationsMap.getItems();
250
- return this._wrapPaginator(page, items => Promise.all(items.map((item) => this._upsertConversation('sync', item.key, item.data))));
250
+ return this._wrapPaginator(page, (items) => Promise.all(items.map((item) => this._upsertConversation("sync", item.key, item.data))));
251
251
  }
252
252
  async getConversation(sid) {
253
253
  const conversationsMap = await this._getMap();
254
254
  const page = await conversationsMap.getItems({ key: sid });
255
- const items = page.items.map((item) => this._upsertConversation('sync', item.key, item.data));
255
+ const items = page.items.map((item) => this._upsertConversation("sync", item.key, item.data));
256
256
  return items.length > 0 ? items[0] : null;
257
257
  }
258
258
  async getConversationByUniqueName(uniqueName) {
@@ -265,7 +265,7 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
265
265
  const data = {
266
266
  entityName: null,
267
267
  lastConsumedMessageIndex: body.last_read_message_index,
268
- status: (body === null || body === void 0 ? void 0 : body.status) || 'unknown',
268
+ status: (body === null || body === void 0 ? void 0 : body.status) || "unknown",
269
269
  friendlyName: body.friendly_name,
270
270
  dateUpdated: body.date_updated,
271
271
  dateCreated: body.date_created,
@@ -274,9 +274,9 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
274
274
  attributes: body.attributes,
275
275
  channel: body.sync_objects.conversation,
276
276
  notificationLevel: body === null || body === void 0 ? void 0 : body.notification_level,
277
- sid
277
+ sid,
278
278
  };
279
- return this._upsertConversation('sync', sid, data);
279
+ return sid ? this._upsertConversation("sync", sid, data) : null;
280
280
  }
281
281
  async peekConversation(sid) {
282
282
  const url = new index.UriBuilder(this.configuration.links.conversations)
@@ -287,7 +287,7 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
287
287
  const data = {
288
288
  entityName: null,
289
289
  // lastConsumedMessageIndex: body.last_read_message_index,
290
- status: (body === null || body === void 0 ? void 0 : body.status) || 'unknown',
290
+ status: (body === null || body === void 0 ? void 0 : body.status) || "unknown",
291
291
  friendlyName: body.friendly_name,
292
292
  dateUpdated: body.date_updated,
293
293
  dateCreated: body.date_created,
@@ -296,14 +296,14 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
296
296
  attributes: body.attributes,
297
297
  channel: `${sid}.channel`,
298
298
  // notificationLevel: body?.notification_level,
299
- sid
299
+ sid,
300
300
  };
301
- return this._upsertConversation('sync', sid, data);
301
+ return this._upsertConversation("sync", sid, data);
302
302
  }
303
303
  async _getMap() {
304
304
  return await this.services.syncClient.map({
305
305
  id: this.configuration.myConversations,
306
- mode: 'open_existing'
306
+ mode: "open_existing",
307
307
  });
308
308
  }
309
309
  async _wrapPaginator(page, op) {
@@ -312,46 +312,48 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
312
312
  items,
313
313
  hasNextPage: page.hasNextPage,
314
314
  hasPrevPage: page.hasPrevPage,
315
- nextPage: () => page.nextPage().then(x => this._wrapPaginator(x, op)),
316
- prevPage: () => page.prevPage().then(x => this._wrapPaginator(x, op))
315
+ nextPage: () => page.nextPage().then((x) => this._wrapPaginator(x, op)),
316
+ prevPage: () => page.prevPage().then((x) => this._wrapPaginator(x, op)),
317
317
  };
318
318
  }
319
319
  async _updateConversation(source, conversation, data) {
320
- const areSourcesDifferent = conversation._statusSource() !== undefined && source !== conversation._statusSource();
321
- const isChannelSourceSync = source !== 'rest' || conversation._statusSource() === 'sync';
322
- if (areSourcesDifferent && isChannelSourceSync && source !== 'sync') {
323
- log.trace('upsertConversation: conversation is known from sync and came from chat, ignoring', {
320
+ const areSourcesDifferent = conversation._statusSource() !== undefined &&
321
+ source !== conversation._statusSource();
322
+ const isChannelSourceSync = source !== "rest" || conversation._statusSource() === "sync";
323
+ if (areSourcesDifferent && isChannelSourceSync && source !== "sync") {
324
+ log.trace("upsertConversation: conversation is known from sync and came from chat, ignoring", {
324
325
  sid: conversation.sid,
325
326
  data: data.status,
326
- conversation: conversation.status
327
+ conversation: conversation.status,
327
328
  });
328
329
  return;
329
330
  }
330
- if (data.status === 'joined' && conversation.status !== 'joined') {
331
- conversation._setStatus('joined', source);
332
- let updateData = {};
333
- if (typeof data.notificationLevel !== 'undefined') {
331
+ if (data.status === "joined" && conversation.status !== "joined") {
332
+ conversation._setStatus("joined", source);
333
+ const updateData = {};
334
+ if (typeof data.notificationLevel !== "undefined") {
334
335
  updateData.notificationLevel = data.notificationLevel;
335
336
  }
336
- if (typeof data.lastConsumedMessageIndex !== 'undefined') {
337
+ if (typeof data.lastConsumedMessageIndex !== "undefined") {
337
338
  updateData.lastConsumedMessageIndex = data.lastConsumedMessageIndex;
338
339
  }
339
340
  if (!isEqual__default['default'](updateData, {})) {
340
341
  conversation._update(updateData);
341
342
  }
342
343
  conversation._subscribe().then(() => {
343
- this.emit('conversationJoined', conversation);
344
+ this.emit("conversationJoined", conversation);
344
345
  });
345
346
  return;
346
347
  }
347
- if (data.status === 'notParticipating' && conversation.status === 'joined') {
348
- conversation._setStatus('notParticipating', source);
348
+ if (data.status === "notParticipating" &&
349
+ conversation.status === "joined") {
350
+ conversation._setStatus("notParticipating", source);
349
351
  conversation._update(data);
350
352
  await conversation._subscribe();
351
- this.emit('conversationLeft', conversation);
353
+ this.emit("conversationLeft", conversation);
352
354
  return;
353
355
  }
354
- if (data.status === 'notParticipating') {
356
+ if (data.status === "notParticipating") {
355
357
  await conversation._subscribe();
356
358
  return;
357
359
  }
@@ -370,47 +372,49 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
370
372
  return conversation$1;
371
373
  }
372
374
  // If the conversations is deleted, ignore it
373
- if (['chat', 'rest'].includes(source) && this.tombstones.has(sid)) {
374
- log.trace('upsertChannel: the channel is deleted but reappeared again from chat, ignoring', sid);
375
- return;
375
+ if (["chat", "rest"].includes(source) && this.tombstones.has(sid)) {
376
+ log.trace("upsertChannel: the channel is deleted but reappeared again from chat, ignoring", sid);
377
+ return null;
376
378
  }
377
379
  // If the conversation is unknown, fetch it
378
- log.trace('upsertConversation: creating a local conversation object with sid ' + sid, data);
380
+ log.trace("upsertConversation: creating a local conversation object with sid " +
381
+ sid, data);
379
382
  const baseLink = `${this.configuration.links.conversations}/${sid}`;
380
383
  const links = {
381
384
  self: baseLink,
382
385
  messages: `${baseLink}/Messages`,
383
- participants: `${baseLink}/Participants`
386
+ participants: `${baseLink}/Participants`,
384
387
  };
385
388
  const newConversation = new conversation.Conversation(data, sid, links, this.configuration, this.services);
386
389
  this.conversations.set(sid, newConversation);
387
390
  await newConversation._subscribe();
388
391
  this._registerForEvents(newConversation);
389
- this.emit('conversationAdded', newConversation);
390
- if (data.status === 'joined') {
391
- newConversation._setStatus('joined', source);
392
- this.emit('conversationJoined', newConversation);
392
+ this.emit("conversationAdded", newConversation);
393
+ if (data.status === "joined") {
394
+ newConversation._setStatus("joined", source);
395
+ this.emit("conversationJoined", newConversation);
393
396
  }
394
397
  return newConversation;
395
398
  }
396
399
  async _fetchMyConversations() {
400
+ var _a;
397
401
  let conversations = [];
398
402
  let pageToken = null;
399
403
  do {
400
404
  const url = new index.UriBuilder(this.configuration.links.myConversations);
401
405
  if (pageToken) {
402
- url.arg('PageToken', pageToken);
406
+ url.arg("PageToken", pageToken);
403
407
  }
404
408
  const response = await this.services.network.get(url.build());
405
- const receivedConversations = response.body.conversations.map((conversationDescriptor) => ({
409
+ const receivedConversations = (_a = response.body) === null || _a === void 0 ? void 0 : _a.conversations.map((conversationDescriptor) => ({
406
410
  descriptor: conversationDescriptor,
407
411
  channel_sid: conversationDescriptor.conversation_sid,
408
412
  status: conversationDescriptor.status,
409
413
  channel: conversationDescriptor.sync_objects.conversation,
410
414
  messages: conversationDescriptor.sync_objects.messages,
411
415
  roster: `${conversationDescriptor.conversation_sid}.roster`,
412
- lastConsumedMessageIndex: conversationDescriptor.last_consumed_message_index,
413
- notificationLevel: conversationDescriptor.notification_level
416
+ lastConsumedMessageIndex: conversationDescriptor.last_read_message_index,
417
+ notificationLevel: conversationDescriptor.notification_level,
414
418
  }));
415
419
  pageToken = response.body.meta.next_token;
416
420
  conversations = [...conversations, ...receivedConversations];
@@ -421,20 +425,20 @@ class Conversations extends replayEventEmitter.ReplayEventEmitter {
421
425
  const conversation = this.conversations.get(sid);
422
426
  if (conversation) {
423
427
  this.conversations.delete(sid);
424
- this.emit('conversationRemoved', conversation);
428
+ this.emit("conversationRemoved", conversation);
425
429
  }
426
430
  }
427
431
  _registerForEvents(conversation) {
428
- conversation.on('removed', () => this._onConversationRemoved(conversation.sid));
429
- conversation.on('updated', (args) => this.emit('conversationUpdated', args));
430
- conversation.on('participantJoined', this.emit.bind(this, 'participantJoined'));
431
- conversation.on('participantLeft', this.emit.bind(this, 'participantLeft'));
432
- conversation.on('participantUpdated', (args) => this.emit('participantUpdated', args));
433
- conversation.on('messageAdded', this.emit.bind(this, 'messageAdded'));
434
- conversation.on('messageUpdated', (args) => this.emit('messageUpdated', args));
435
- conversation.on('messageRemoved', this.emit.bind(this, 'messageRemoved'));
436
- conversation.on('typingStarted', this.emit.bind(this, 'typingStarted'));
437
- conversation.on('typingEnded', this.emit.bind(this, 'typingEnded'));
432
+ conversation.on("removed", () => this._onConversationRemoved(conversation.sid));
433
+ conversation.on("updated", (args) => this.emit("conversationUpdated", args));
434
+ conversation.on("participantJoined", (participant) => this.emit("participantJoined", participant));
435
+ conversation.on("participantLeft", (participant) => this.emit("participantLeft", participant));
436
+ conversation.on("participantUpdated", (args) => this.emit("participantUpdated", args));
437
+ conversation.on("messageAdded", (message) => this.emit("messageAdded", message));
438
+ conversation.on("messageUpdated", (args) => this.emit("messageUpdated", args));
439
+ conversation.on("messageRemoved", (message) => this.emit("messageRemoved", message));
440
+ conversation.on("typingStarted", (participant) => this.emit("typingStarted", participant));
441
+ conversation.on("typingEnded", (participant) => this.emit("typingEnded", participant));
438
442
  }
439
443
  }
440
444
 
@@ -1 +1 @@
1
- {"version":3,"file":"conversations.js","sources":["../../src/data/conversations.ts"],"sourcesContent":["import { Logger } from '../logger';\nimport {\n Conversation,\n ConversationUpdatedEventArgs,\n ConversationUpdateReason\n} from '../conversation';\nimport { SyncMap, SyncClient, SyncMapItem } from 'twilio-sync';\nimport { Users } from './users';\nimport { Network } from '../services/network';\nimport { TypingIndicator } from '../services/typing-indicator';\nimport { McsClient } from '@twilio/mcs-client';\nimport { Deferred } from '../util/deferred';\nimport {\n Participant,\n ParticipantUpdatedEventArgs,\n ParticipantUpdateReason\n} from '../participant';\nimport {\n Message,\n MessageUpdatedEventArgs,\n MessageUpdateReason\n} from '../message';\nimport { UriBuilder } from '../util';\nimport { Configuration } from '../configuration';\nimport { CommandExecutor } from '../command-executor';\nimport {\n CreateConversationRequest\n} from '../interfaces/commands/create-conversation';\nimport { ConversationResponse } from '../interfaces/commands/conversation-response';\nimport { ReplayEventEmitter } from '@twilio/replay-event-emitter';\nimport isEqual from 'lodash.isequal';\n\ntype ConversationsEvents = {\n conversationAdded: (conversation: Conversation) => void;\n conversationJoined: (conversation: Conversation) => void;\n conversationLeft: (conversation: Conversation) => void;\n conversationRemoved: (conversation: Conversation) => void;\n conversationUpdated: (data: {\n conversation: Conversation;\n updateReasons: ConversationUpdateReason[];\n }) => void;\n participantJoined: (participant: Participant) => void;\n participantLeft: (participant: Participant) => void;\n participantUpdated: (data: {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n }) => void;\n messageAdded: (message: Message) => void;\n messageRemoved: (message: Message) => void;\n messageUpdated: (data: {\n message: Message;\n updateReasons: MessageUpdateReason[];\n }) => void;\n typingEnded: (participant: Participant) => void;\n typingStarted: (participant: Participant) => void;\n};\n\ntype ConversationsDataSource = 'sync' | 'chat' | 'rest';\n\ninterface ConversationsServices {\n syncClient: SyncClient;\n users: Users;\n typingIndicator: TypingIndicator;\n network: Network;\n mcsClient: McsClient;\n commandExecutor: CommandExecutor;\n}\n\nconst log = Logger.scope('Conversations');\n\n/**\n * Represents conversations collection\n * {@see Conversation}\n */\nclass Conversations extends ReplayEventEmitter<ConversationsEvents> {\n public readonly conversations: Map<string, Conversation> = new Map();\n public readonly myConversationsRead: Deferred<boolean> = new Deferred();\n private readonly configuration: Configuration;\n private readonly services: ConversationsServices;\n private readonly tombstones: Set<string> = new Set();\n private myConversationsFetched = false;\n\n public constructor(\n configuration: Configuration,\n services: ConversationsServices\n ) {\n super();\n\n this.configuration = configuration;\n this.services = services;\n }\n\n public async addConversation(options): Promise<Conversation> {\n const attributes = typeof options?.attributes !== 'undefined'\n ? options.attributes\n : {};\n\n const response = await this.services.commandExecutor.mutateResource<CreateConversationRequest, ConversationResponse>(\n 'post',\n this.configuration.links.conversations,\n {\n friendly_name: options.friendlyName,\n unique_name: options.uniqueName,\n attributes: typeof attributes !== 'undefined' ? JSON.stringify(attributes) : undefined\n }\n );\n\n const conversationSid = response.sid ?? null;\n const conversationDocument = response.sync_objects?.conversation ?? null;\n const links = {\n self: response.url,\n ...response.links\n };\n const existingConversation = this.conversations.get(conversationSid);\n\n if (existingConversation) {\n await existingConversation._subscribe();\n return existingConversation;\n }\n\n const conversation = new Conversation(\n {\n channel: conversationDocument,\n entityName: null,\n uniqueName: null,\n attributes: null,\n createdBy: null,\n friendlyName: null,\n lastConsumedMessageIndex: null,\n dateCreated: null,\n dateUpdated: null\n },\n conversationSid,\n links,\n this.configuration,\n this.services\n );\n\n this.conversations.set(conversation.sid, conversation);\n this._registerForEvents(conversation);\n\n await conversation._subscribe();\n this.emit('conversationAdded', conversation);\n\n return conversation;\n }\n\n /**\n * Fetch conversations list and instantiate all necessary objects\n */\n public async fetchConversations(): Promise<Conversations> {\n try {\n const map = await this._getMap();\n\n map.on('itemAdded', args => {\n log.debug(`itemAdded: ${args.item.key}`);\n\n this._upsertConversation('sync', args.item.key, args.item.data);\n });\n\n map.on('itemRemoved', args => {\n log.debug(`itemRemoved: ${args.key}`);\n\n const sid = args.key;\n\n if (!this.myConversationsFetched) {\n this.tombstones.add(sid);\n }\n\n const conversation = this.conversations.get(sid);\n\n if (!conversation) {\n return;\n }\n\n if (conversation.status === 'joined') {\n conversation._setStatus('notParticipating', 'sync');\n this.emit('conversationLeft', conversation);\n }\n\n this.conversations.delete(sid);\n this.emit('conversationRemoved', conversation);\n conversation.emit('removed', conversation);\n });\n\n map.on('itemUpdated', args => {\n log.debug(`itemUpdated: ${args.item.key}`);\n\n this._upsertConversation('sync', args.item.key, args.item.data);\n });\n\n const myConversations = await this._fetchMyConversations();\n const upserts = [];\n\n for (const conversation of myConversations) {\n upserts.push(this._upsertConversation('rest', conversation.channel_sid, conversation));\n }\n\n this.myConversationsRead.set(true);\n\n await Promise.all(upserts);\n\n this.myConversationsFetched = true;\n this.tombstones.clear();\n\n log.debug('The conversations list has been successfully fetched');\n\n return this;\n } catch (error) {\n const errorMessage = 'Failed to fetch the conversations list';\n\n if (this.services.syncClient.connectionState !== 'disconnected') {\n log.error(errorMessage, error);\n }\n\n log.debug(`ERROR: ${errorMessage}`, error);\n\n throw error;\n }\n }\n\n public async getConversations(args) {\n const conversationsMap = await this._getMap();\n const page = await conversationsMap.getItems();\n\n return this._wrapPaginator(page\n , items => Promise.all(items.map((item: SyncMapItem) => this._upsertConversation('sync', item.key, item.data))));\n }\n\n public async getConversation(sid: string): Promise<Conversation> {\n const conversationsMap = await this._getMap();\n const page = await conversationsMap.getItems({ key: sid });\n const items = page.items.map((item: SyncMapItem) => this._upsertConversation('sync', item.key, item.data));\n\n return items.length > 0 ? items[0] : null;\n }\n\n public async getConversationByUniqueName(uniqueName: string): Promise<Conversation> {\n const url = new UriBuilder(this.configuration.links.myConversations)\n .path(uniqueName)\n .build();\n const response = await this.services.network.get(url);\n const body = response.body;\n\n const sid = body.conversation_sid;\n const data = {\n entityName: null,\n lastConsumedMessageIndex: body.last_read_message_index,\n status: body?.status || 'unknown',\n friendlyName: body.friendly_name,\n dateUpdated: body.date_updated,\n dateCreated: body.date_created,\n uniqueName: body.unique_name,\n createdBy: body.created_by,\n attributes: body.attributes,\n channel: body.sync_objects.conversation,\n notificationLevel: body?.notification_level,\n sid\n };\n\n return this._upsertConversation('sync', sid, data);\n }\n\n public async peekConversation(sid: string): Promise<Conversation> {\n const url = new UriBuilder(this.configuration.links.conversations)\n .path(sid)\n .build();\n const response = await this.services.network.get(url);\n const body = response.body;\n\n const data = {\n entityName: null,\n // lastConsumedMessageIndex: body.last_read_message_index,\n status: body?.status || 'unknown',\n friendlyName: body.friendly_name,\n dateUpdated: body.date_updated,\n dateCreated: body.date_created,\n uniqueName: body.unique_name,\n createdBy: body.created_by,\n attributes: body.attributes,\n channel: `${sid}.channel`,\n // notificationLevel: body?.notification_level,\n sid\n };\n\n return this._upsertConversation('sync', sid, data);\n }\n\n private async _getMap(): Promise<SyncMap> {\n return await this.services.syncClient.map({\n id: this.configuration.myConversations,\n mode: 'open_existing'\n });\n }\n\n private async _wrapPaginator(page, op) {\n const items = await op(page.items);\n\n return {\n items,\n hasNextPage: page.hasNextPage,\n hasPrevPage: page.hasPrevPage,\n nextPage: () => page.nextPage().then(x => this._wrapPaginator(x, op)),\n prevPage: () => page.prevPage().then(x => this._wrapPaginator(x, op))\n };\n }\n\n private async _updateConversation(source: ConversationsDataSource, conversation: Conversation, data): Promise<void> {\n const areSourcesDifferent = conversation._statusSource() !== undefined && source !== conversation._statusSource();\n const isChannelSourceSync = source !== 'rest' || conversation._statusSource() === 'sync';\n\n if (areSourcesDifferent && isChannelSourceSync && source !== 'sync') {\n log.trace('upsertConversation: conversation is known from sync and came from chat, ignoring', {\n sid: conversation.sid,\n data: data.status,\n conversation: conversation.status\n });\n\n return;\n }\n\n if (data.status === 'joined' && conversation.status !== 'joined') {\n conversation._setStatus('joined', source);\n\n let updateData: any = {};\n\n if (typeof data.notificationLevel !== 'undefined') {\n updateData.notificationLevel = data.notificationLevel;\n }\n\n if (typeof data.lastConsumedMessageIndex !== 'undefined') {\n updateData.lastConsumedMessageIndex = data.lastConsumedMessageIndex;\n }\n\n if (!isEqual(updateData, {})) {\n conversation._update(updateData);\n }\n\n conversation._subscribe().then(() => {\n this.emit('conversationJoined', conversation);\n });\n\n return;\n }\n\n if (data.status === 'notParticipating' && conversation.status === 'joined') {\n conversation._setStatus('notParticipating', source);\n conversation._update(data);\n await conversation._subscribe();\n this.emit('conversationLeft', conversation);\n\n return;\n }\n\n if (data.status === 'notParticipating') {\n await conversation._subscribe();\n\n return;\n }\n\n conversation._update(data);\n }\n\n private async _upsertConversation(source: ConversationsDataSource, sid: string, data): Promise<Conversation> {\n log.trace(`upsertConversation called for ${sid}`, data);\n\n const conversation = this.conversations.get(sid);\n\n // If the channel is known, update it\n if (conversation) {\n log.trace(\n `upsertConversation: the conversation ${conversation.sid} is known;` +\n `its status is known from the source ${conversation._statusSource()} ` +\n `and the update came from the source ${source}`,\n conversation\n );\n\n await this._updateConversation(source, conversation, data);\n await conversation._subscribe();\n\n return conversation;\n }\n\n // If the conversations is deleted, ignore it\n if (['chat', 'rest'].includes(source) && this.tombstones.has(sid)) {\n log.trace('upsertChannel: the channel is deleted but reappeared again from chat, ignoring', sid);\n return;\n }\n\n // If the conversation is unknown, fetch it\n log.trace('upsertConversation: creating a local conversation object with sid ' + sid, data);\n\n const baseLink = `${this.configuration.links.conversations}/${sid}`;\n const links = {\n self: baseLink,\n messages: `${baseLink}/Messages`,\n participants: `${baseLink}/Participants`\n };\n const newConversation = new Conversation(\n data,\n sid,\n links,\n this.configuration,\n this.services\n );\n this.conversations.set(sid, newConversation);\n\n await newConversation._subscribe();\n this._registerForEvents(newConversation);\n this.emit('conversationAdded', newConversation);\n\n if (data.status === 'joined') {\n newConversation._setStatus('joined', source);\n this.emit('conversationJoined', newConversation);\n }\n\n return newConversation;\n }\n\n private async _fetchMyConversations() {\n let conversations = [];\n let pageToken: null | string = null;\n\n do {\n const url = new UriBuilder(this.configuration.links.myConversations);\n\n if (pageToken) {\n url.arg('PageToken', pageToken);\n }\n\n const response = await this.services.network.get(url.build());\n const receivedConversations = response.body.conversations.map(\n (conversationDescriptor) => ({\n descriptor: conversationDescriptor,\n channel_sid: conversationDescriptor.conversation_sid,\n status: conversationDescriptor.status,\n channel: conversationDescriptor.sync_objects.conversation,\n messages: conversationDescriptor.sync_objects.messages,\n roster: `${conversationDescriptor.conversation_sid}.roster`,\n lastConsumedMessageIndex: conversationDescriptor.last_consumed_message_index,\n notificationLevel: conversationDescriptor.notification_level\n })\n );\n\n pageToken = response.body.meta.next_token;\n conversations = [...conversations, ...receivedConversations];\n } while (pageToken);\n\n return conversations;\n }\n\n private _onConversationRemoved(sid: string) {\n const conversation = this.conversations.get(sid);\n\n if (conversation) {\n this.conversations.delete(sid);\n this.emit('conversationRemoved', conversation);\n }\n }\n\n private _registerForEvents(conversation) {\n conversation.on('removed', () => this._onConversationRemoved(conversation.sid));\n conversation.on('updated', (args: ConversationUpdatedEventArgs) => this.emit('conversationUpdated', args));\n conversation.on('participantJoined', this.emit.bind(this, 'participantJoined'));\n conversation.on('participantLeft', this.emit.bind(this, 'participantLeft'));\n conversation.on('participantUpdated', (args: ParticipantUpdatedEventArgs) => this.emit('participantUpdated', args));\n conversation.on('messageAdded', this.emit.bind(this, 'messageAdded'));\n conversation.on('messageUpdated', (args: MessageUpdatedEventArgs) => this.emit('messageUpdated', args));\n conversation.on('messageRemoved', this.emit.bind(this, 'messageRemoved'));\n conversation.on('typingStarted', this.emit.bind(this, 'typingStarted'));\n conversation.on('typingEnded', this.emit.bind(this, 'typingEnded'));\n }\n}\n\nexport {\n ConversationsServices,\n ConversationsDataSource,\n Conversation,\n Conversations\n};\n"],"names":["Logger","ReplayEventEmitter","Deferred","conversation","Conversation","UriBuilder","isEqual"],"mappings":"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"}
1
+ {"version":3,"file":"conversations.js","sources":["../../src/data/conversations.ts"],"sourcesContent":["import { Logger } from \"../logger\";\nimport {\n Conversation,\n ConversationDescriptor,\n ConversationUpdatedEventArgs,\n ConversationUpdateReason,\n} from \"../conversation\";\nimport { SyncMap, SyncClient, SyncMapItem } from \"twilio-sync\";\nimport { Users } from \"./users\";\nimport { Network } from \"../services/network\";\nimport { TypingIndicator } from \"../services/typing-indicator\";\nimport { McsClient } from \"@twilio/mcs-client\";\nimport { Deferred } from \"../util/deferred\";\nimport {\n Participant,\n ParticipantUpdatedEventArgs,\n ParticipantUpdateReason,\n} from \"../participant\";\nimport {\n Message,\n MessageUpdatedEventArgs,\n MessageUpdateReason,\n} from \"../message\";\nimport { UriBuilder } from \"../util\";\nimport { Configuration } from \"../configuration\";\nimport { CommandExecutor } from \"../command-executor\";\nimport { CreateConversationRequest } from \"../interfaces/commands/create-conversation\";\nimport { ConversationResponse } from \"../interfaces/commands/conversation-response\";\nimport { ReplayEventEmitter } from \"@twilio/replay-event-emitter\";\nimport isEqual from \"lodash.isequal\";\nimport { ResponseMeta } from \"../interfaces/commands/response-meta\";\n\ntype ConversationsEvents = {\n conversationAdded: (conversation: Conversation) => void;\n conversationJoined: (conversation: Conversation) => void;\n conversationLeft: (conversation: Conversation) => void;\n conversationRemoved: (conversation: Conversation) => void;\n conversationUpdated: (data: {\n conversation: Conversation;\n updateReasons: ConversationUpdateReason[];\n }) => void;\n participantJoined: (participant: Participant) => void;\n participantLeft: (participant: Participant) => void;\n participantUpdated: (data: {\n participant: Participant;\n updateReasons: ParticipantUpdateReason[];\n }) => void;\n messageAdded: (message: Message) => void;\n messageRemoved: (message: Message) => void;\n messageUpdated: (data: {\n message: Message;\n updateReasons: MessageUpdateReason[];\n }) => void;\n typingEnded: (participant: Participant) => void;\n typingStarted: (participant: Participant) => void;\n};\n\ntype ConversationsDataSource = \"sync\" | \"chat\" | \"rest\";\n\ninterface ConversationsServices {\n syncClient: SyncClient;\n users: Users;\n typingIndicator: TypingIndicator;\n network: Network;\n mcsClient: McsClient;\n commandExecutor: CommandExecutor;\n}\n\ntype ConversationRestData = {\n roster: string;\n notificationLevel: \"default\" | \"muted\";\n lastConsumedMessageIndex: number;\n channel: string;\n messages: string;\n descriptor: ConversationResponse;\n channel_sid: string;\n status: string;\n};\n\nconst log = Logger.scope(\"Conversations\");\n\n/**\n * Represents conversations collection\n * {@see Conversation}\n */\nclass Conversations extends ReplayEventEmitter<ConversationsEvents> {\n public readonly conversations: Map<string, Conversation> = new Map();\n public readonly myConversationsRead: Deferred<boolean> = new Deferred();\n private readonly configuration: Configuration;\n private readonly services: ConversationsServices;\n private readonly tombstones: Set<string> = new Set();\n private myConversationsFetched = false;\n\n public constructor(\n configuration: Configuration,\n services: ConversationsServices\n ) {\n super();\n\n this.configuration = configuration;\n this.services = services;\n }\n\n public async addConversation(options): Promise<Conversation> {\n const attributes =\n typeof options?.attributes !== \"undefined\" ? options.attributes : {};\n\n const response = await this.services.commandExecutor.mutateResource<\n CreateConversationRequest,\n ConversationResponse\n >(\"post\", this.configuration.links.conversations, {\n friendly_name: options.friendlyName,\n unique_name: options.uniqueName,\n attributes:\n typeof attributes !== \"undefined\"\n ? JSON.stringify(attributes)\n : undefined,\n });\n\n const conversationSid = response.sid ?? null;\n const conversationDocument = response.sync_objects?.conversation ?? null;\n const links = {\n self: response.url,\n ...response.links,\n };\n const existingConversation = this.conversations.get(conversationSid);\n\n if (existingConversation) {\n await existingConversation._subscribe();\n return existingConversation;\n }\n\n const conversation = new Conversation(\n {\n channel: conversationDocument,\n entityName: \"\",\n uniqueName: \"\",\n attributes: null,\n createdBy: \"\",\n friendlyName: \"\",\n lastConsumedMessageIndex: 0,\n dateCreated: null,\n dateUpdated: null,\n },\n conversationSid,\n links,\n this.configuration,\n this.services\n );\n\n this.conversations.set(conversation.sid, conversation);\n this._registerForEvents(conversation);\n\n await conversation._subscribe();\n this.emit(\"conversationAdded\", conversation);\n\n return conversation;\n }\n\n /**\n * Fetch conversations list and instantiate all necessary objects\n */\n public async fetchConversations(): Promise<Conversations> {\n try {\n const map = await this._getMap();\n\n map.on(\"itemAdded\", (args) => {\n log.debug(`itemAdded: ${args.item.key}`);\n\n this._upsertConversation(\"sync\", args.item.key, args.item.data);\n });\n\n map.on(\"itemRemoved\", (args) => {\n log.debug(`itemRemoved: ${args.key}`);\n\n const sid = args.key;\n\n if (!this.myConversationsFetched) {\n this.tombstones.add(sid);\n }\n\n const conversation = this.conversations.get(sid);\n\n if (!conversation) {\n return;\n }\n\n if (conversation.status === \"joined\") {\n conversation._setStatus(\"notParticipating\", \"sync\");\n this.emit(\"conversationLeft\", conversation);\n }\n\n this.conversations.delete(sid);\n this.emit(\"conversationRemoved\", conversation);\n conversation.emit(\"removed\", conversation);\n });\n\n map.on(\"itemUpdated\", (args) => {\n log.debug(`itemUpdated: ${args.item.key}`);\n\n this._upsertConversation(\"sync\", args.item.key, args.item.data);\n });\n\n const myConversations: ConversationRestData[] =\n await this._fetchMyConversations();\n const upserts: Promise<Conversation | null>[] = [];\n\n for (const conversation of myConversations) {\n upserts.push(\n this._upsertConversation(\n \"rest\",\n conversation[\"channel_sid\"],\n conversation\n )\n );\n }\n\n this.myConversationsRead.set(true);\n\n await Promise.all(upserts);\n\n this.myConversationsFetched = true;\n this.tombstones.clear();\n\n log.debug(\"The conversations list has been successfully fetched\");\n\n return this;\n } catch (error) {\n const errorMessage = \"Failed to fetch the conversations list\";\n\n if (this.services.syncClient.connectionState !== \"disconnected\") {\n log.error(errorMessage, error);\n }\n\n log.debug(`ERROR: ${errorMessage}`, error);\n\n throw error;\n }\n }\n\n public async getConversations() {\n const conversationsMap = await this._getMap();\n const page = await conversationsMap.getItems();\n\n return this._wrapPaginator(page, (items) =>\n Promise.all(\n items.map((item: SyncMapItem) =>\n this._upsertConversation(\"sync\", item.key, item.data)\n )\n )\n );\n }\n\n public async getConversation(\n sid: string\n ): Promise<Conversation | undefined | null> {\n const conversationsMap = await this._getMap();\n const page = await conversationsMap.getItems({ key: sid });\n const items = page.items.map((item: SyncMapItem) =>\n this._upsertConversation(\"sync\", item.key, item.data)\n );\n\n return items.length > 0 ? items[0] : null;\n }\n\n public async getConversationByUniqueName(\n uniqueName: string\n ): Promise<Conversation | null> {\n const url = new UriBuilder(this.configuration.links.myConversations)\n .path(uniqueName)\n .build();\n const response = await this.services.network.get<ConversationResponse>(url);\n const body = response.body;\n\n const sid = body.conversation_sid;\n const data = {\n entityName: null,\n lastConsumedMessageIndex: body.last_read_message_index,\n status: body?.status || \"unknown\",\n friendlyName: body.friendly_name,\n dateUpdated: body.date_updated,\n dateCreated: body.date_created,\n uniqueName: body.unique_name,\n createdBy: body.created_by,\n attributes: body.attributes,\n channel: body.sync_objects.conversation,\n notificationLevel: body?.notification_level,\n sid,\n };\n\n return sid ? this._upsertConversation(\"sync\", sid, data) : null;\n }\n\n public async peekConversation(sid: string): Promise<Conversation | null> {\n const url = new UriBuilder(this.configuration.links.conversations)\n .path(sid)\n .build();\n const response = await this.services.network.get<ConversationResponse>(url);\n const body = response.body;\n\n const data = {\n entityName: null,\n // lastConsumedMessageIndex: body.last_read_message_index,\n status: body?.status || \"unknown\",\n friendlyName: body.friendly_name,\n dateUpdated: body.date_updated,\n dateCreated: body.date_created,\n uniqueName: body.unique_name,\n createdBy: body.created_by,\n attributes: body.attributes,\n channel: `${sid}.channel`,\n // notificationLevel: body?.notification_level,\n sid,\n };\n\n return this._upsertConversation(\"sync\", sid, data);\n }\n\n private async _getMap(): Promise<SyncMap> {\n return await this.services.syncClient.map({\n id: this.configuration.myConversations,\n mode: \"open_existing\",\n });\n }\n\n private async _wrapPaginator(page, op) {\n const items = await op(page.items);\n\n return {\n items,\n hasNextPage: page.hasNextPage,\n hasPrevPage: page.hasPrevPage,\n nextPage: () => page.nextPage().then((x) => this._wrapPaginator(x, op)),\n prevPage: () => page.prevPage().then((x) => this._wrapPaginator(x, op)),\n };\n }\n\n private async _updateConversation(\n source: ConversationsDataSource,\n conversation: Conversation,\n data\n ): Promise<void> {\n const areSourcesDifferent =\n conversation._statusSource() !== undefined &&\n source !== conversation._statusSource();\n const isChannelSourceSync =\n source !== \"rest\" || conversation._statusSource() === \"sync\";\n\n if (areSourcesDifferent && isChannelSourceSync && source !== \"sync\") {\n log.trace(\n \"upsertConversation: conversation is known from sync and came from chat, ignoring\",\n {\n sid: conversation.sid,\n data: data.status,\n conversation: conversation.status,\n }\n );\n\n return;\n }\n\n if (data.status === \"joined\" && conversation.status !== \"joined\") {\n conversation._setStatus(\"joined\", source);\n\n const updateData: Partial<ConversationDescriptor> = {};\n\n if (typeof data.notificationLevel !== \"undefined\") {\n updateData.notificationLevel = data.notificationLevel;\n }\n\n if (typeof data.lastConsumedMessageIndex !== \"undefined\") {\n updateData.lastConsumedMessageIndex = data.lastConsumedMessageIndex;\n }\n\n if (!isEqual(updateData, {})) {\n conversation._update(updateData);\n }\n\n conversation._subscribe().then(() => {\n this.emit(\"conversationJoined\", conversation);\n });\n\n return;\n }\n\n if (\n data.status === \"notParticipating\" &&\n conversation.status === \"joined\"\n ) {\n conversation._setStatus(\"notParticipating\", source);\n conversation._update(data);\n await conversation._subscribe();\n this.emit(\"conversationLeft\", conversation);\n\n return;\n }\n\n if (data.status === \"notParticipating\") {\n await conversation._subscribe();\n\n return;\n }\n\n conversation._update(data);\n }\n\n private async _upsertConversation(\n source: ConversationsDataSource,\n sid: string,\n data\n ): Promise<Conversation | null> {\n log.trace(`upsertConversation called for ${sid}`, data);\n\n const conversation = this.conversations.get(sid);\n\n // If the channel is known, update it\n if (conversation) {\n log.trace(\n `upsertConversation: the conversation ${conversation.sid} is known;` +\n `its status is known from the source ${conversation._statusSource()} ` +\n `and the update came from the source ${source}`,\n conversation\n );\n\n await this._updateConversation(source, conversation, data);\n await conversation._subscribe();\n\n return conversation;\n }\n\n // If the conversations is deleted, ignore it\n if ([\"chat\", \"rest\"].includes(source) && this.tombstones.has(sid)) {\n log.trace(\n \"upsertChannel: the channel is deleted but reappeared again from chat, ignoring\",\n sid\n );\n return null;\n }\n\n // If the conversation is unknown, fetch it\n log.trace(\n \"upsertConversation: creating a local conversation object with sid \" +\n sid,\n data\n );\n\n const baseLink = `${this.configuration.links.conversations}/${sid}`;\n const links = {\n self: baseLink,\n messages: `${baseLink}/Messages`,\n participants: `${baseLink}/Participants`,\n };\n const newConversation = new Conversation(\n data,\n sid,\n links,\n this.configuration,\n this.services\n );\n this.conversations.set(sid, newConversation);\n\n await newConversation._subscribe();\n this._registerForEvents(newConversation);\n this.emit(\"conversationAdded\", newConversation);\n\n if (data.status === \"joined\") {\n newConversation._setStatus(\"joined\", source);\n this.emit(\"conversationJoined\", newConversation);\n }\n\n return newConversation;\n }\n private async _fetchMyConversations(): Promise<ConversationRestData[]> {\n let conversations: ConversationRestData[] = [];\n let pageToken: null | string = null;\n\n do {\n const url = new UriBuilder(this.configuration.links.myConversations);\n\n if (pageToken) {\n url.arg(\"PageToken\", pageToken);\n }\n\n const response = await this.services.network.get<\n { conversations: ConversationResponse[] } & ResponseMeta\n >(url.build());\n const receivedConversations = response.body?.conversations.map(\n (conversationDescriptor) => ({\n descriptor: conversationDescriptor,\n channel_sid: conversationDescriptor.conversation_sid,\n status: conversationDescriptor.status,\n channel: conversationDescriptor.sync_objects.conversation,\n messages: conversationDescriptor.sync_objects.messages,\n roster: `${conversationDescriptor.conversation_sid}.roster`,\n lastConsumedMessageIndex:\n conversationDescriptor.last_read_message_index,\n notificationLevel: conversationDescriptor.notification_level,\n })\n );\n\n pageToken = response.body.meta.next_token;\n conversations = [...conversations, ...receivedConversations];\n } while (pageToken);\n\n return conversations;\n }\n\n private _onConversationRemoved(sid: string) {\n const conversation = this.conversations.get(sid);\n\n if (conversation) {\n this.conversations.delete(sid);\n this.emit(\"conversationRemoved\", conversation);\n }\n }\n\n private _registerForEvents(conversation) {\n conversation.on(\"removed\", () =>\n this._onConversationRemoved(conversation.sid)\n );\n conversation.on(\"updated\", (args: ConversationUpdatedEventArgs) =>\n this.emit(\"conversationUpdated\", args)\n );\n conversation.on(\"participantJoined\", (participant) =>\n this.emit(\"participantJoined\", participant)\n );\n conversation.on(\"participantLeft\", (participant) =>\n this.emit(\"participantLeft\", participant)\n );\n conversation.on(\"participantUpdated\", (args: ParticipantUpdatedEventArgs) =>\n this.emit(\"participantUpdated\", args)\n );\n conversation.on(\"messageAdded\", (message) =>\n this.emit(\"messageAdded\", message)\n );\n conversation.on(\"messageUpdated\", (args: MessageUpdatedEventArgs) =>\n this.emit(\"messageUpdated\", args)\n );\n conversation.on(\"messageRemoved\", (message) =>\n this.emit(\"messageRemoved\", message)\n );\n conversation.on(\"typingStarted\", (participant) =>\n this.emit(\"typingStarted\", participant)\n );\n conversation.on(\"typingEnded\", (participant) =>\n this.emit(\"typingEnded\", participant)\n );\n }\n}\n\nexport {\n ConversationsServices,\n ConversationsDataSource,\n Conversation,\n Conversations,\n};\n"],"names":["Logger","ReplayEventEmitter","Deferred","conversation","Conversation","UriBuilder","isEqual"],"mappings":"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"}