@blotoutio/providers-shop-gpt-sdk 1.10.3 → 1.11.0

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 (4) hide show
  1. package/index.cjs.js +107 -29
  2. package/index.js +107 -29
  3. package/index.mjs +107 -29
  4. package/package.json +1 -1
package/index.cjs.js CHANGED
@@ -412,9 +412,18 @@ const createExperiment = (props) => {
412
412
  const uiActions = new Set([
413
413
  'shopGPTInitialized',
414
414
  'chatbotOpened',
415
+ 'chatbotClosed',
416
+ 'singleThreadDelete',
417
+ 'allThreadsDelete',
418
+ 'switchThread',
419
+ 'newSearch',
420
+ 'thumbsUp',
421
+ 'thumbsDown',
422
+ 'showThreads',
415
423
  'queryInteractions',
416
424
  'promptClicked',
417
425
  'productRecommendationClicked',
426
+ 'blotoutLinkClicked',
418
427
  ]);
419
428
  /** Action length should not exceed 42 */
420
429
  new Set([
@@ -769,10 +778,11 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
769
778
  const data = (await response.json());
770
779
  return data.customPrompts;
771
780
  };
772
- const sendEvent = async (action, currency, actionData) => {
781
+ const sendEvent = (action, currency, actionData) => {
773
782
  var _a;
774
783
  const storageData = (_a = getProductActions(baseURL, sessionId)) !== null && _a !== void 0 ? _a : {};
775
- const response = await fetchImpl(getURL('/user/event'), {
784
+ // This endpoint sends user events to the server, we don't need to wait for the response
785
+ fetchImpl(getURL('/user/event'), {
776
786
  method: 'POST',
777
787
  headers: getHeaders(true),
778
788
  body: JSON.stringify({
@@ -786,10 +796,13 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
786
796
  },
787
797
  }),
788
798
  credentials: 'include',
789
- });
790
- if (!response.ok) {
791
- throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
792
- }
799
+ })
800
+ .then(async (response) => {
801
+ if (!response.ok) {
802
+ throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
803
+ }
804
+ })
805
+ .catch(logger.error);
793
806
  };
794
807
  return {
795
808
  processQuery,
@@ -1091,6 +1104,7 @@ const shopGPTStyles = i$4 `
1091
1104
  height: 56px;
1092
1105
  background-color: var(--shopgpt-primary);
1093
1106
  border-radius: 50%;
1107
+ display: flex;
1094
1108
  justify-content: center;
1095
1109
  align-items: center;
1096
1110
  box-shadow: 0 0 4px 1px var(--shopgpt-white);
@@ -1523,6 +1537,13 @@ class ChatThreads extends r$2 {
1523
1537
  }
1524
1538
  return `https://${this.merchantUrl}`;
1525
1539
  }
1540
+ sendEvent(action, actionData) {
1541
+ this.dispatchEvent(new CustomEvent('send-event', {
1542
+ detail: { action, actionData },
1543
+ composed: true,
1544
+ bubbles: true,
1545
+ }));
1546
+ }
1526
1547
  handleThreadDelete() {
1527
1548
  if (this.deleteAllThreads) {
1528
1549
  this.dispatchEvent(new CustomEvent('delete-all-threads', {
@@ -1557,7 +1578,7 @@ class ChatThreads extends r$2 {
1557
1578
  ? x `<div
1558
1579
  class="trash-icon"
1559
1580
  @click=${() => {
1560
- if (this.isLoading || this.isTyping) {
1581
+ if (this.isLoading || this.isStreaming) {
1561
1582
  return;
1562
1583
  }
1563
1584
  this.deleteAllThreads = true;
@@ -1574,13 +1595,15 @@ class ChatThreads extends r$2 {
1574
1595
  class=${e$1({
1575
1596
  'thread-wrapper': true,
1576
1597
  active: this.selectedThreadId === thread.threadId,
1577
- disabled: this.isTyping,
1598
+ disabled: this.isStreaming,
1578
1599
  })}
1579
1600
  >
1580
1601
  <div
1581
1602
  class="thread-title"
1582
1603
  @click=${async () => {
1583
- if (this.isLoading || this.isTyping) {
1604
+ if (this.isLoading ||
1605
+ this.isStreaming ||
1606
+ this.selectedThreadId === thread.threadId) {
1584
1607
  return;
1585
1608
  }
1586
1609
  await this.setSelectedThreadId(thread.threadId);
@@ -1591,7 +1614,7 @@ class ChatThreads extends r$2 {
1591
1614
  <div
1592
1615
  class="trash-icon"
1593
1616
  @click=${() => {
1594
- if (this.isLoading || this.isTyping) {
1617
+ if (this.isLoading || this.isStreaming) {
1595
1618
  return;
1596
1619
  }
1597
1620
  this.deleteThreadId = thread.threadId;
@@ -1612,8 +1635,13 @@ class ChatThreads extends r$2 {
1612
1635
  <span class="line"></span>
1613
1636
  <button
1614
1637
  class="btn-new-search"
1615
- ?disabled=${this.isLoading || this.isTyping}
1616
- @click=${() => this.setSelectedThreadId('')}
1638
+ ?disabled=${this.isLoading || this.isStreaming}
1639
+ @click=${() => {
1640
+ if (this.selectedThreadId) {
1641
+ this.sendEvent('newSearch');
1642
+ }
1643
+ this.setSelectedThreadId('');
1644
+ }}
1617
1645
  >
1618
1646
  New Search
1619
1647
  </button>
@@ -1670,7 +1698,7 @@ __decorate([
1670
1698
  __decorate([
1671
1699
  n({ type: Boolean }),
1672
1700
  __metadata("design:type", Boolean)
1673
- ], ChatThreads.prototype, "isTyping", void 0);
1701
+ ], ChatThreads.prototype, "isStreaming", void 0);
1674
1702
  __decorate([
1675
1703
  n({ type: String }),
1676
1704
  __metadata("design:type", String)
@@ -2341,6 +2369,12 @@ const chatSectionStyles = i$4 `
2341
2369
  background: #2b65cf;
2342
2370
  opacity: 1;
2343
2371
  }
2372
+
2373
+ .new-search-btn:disabled {
2374
+ background: #808080;
2375
+ cursor: not-allowed;
2376
+ opacity: 0.5;
2377
+ }
2344
2378
  }
2345
2379
  }
2346
2380
 
@@ -2373,6 +2407,7 @@ const chatSectionStyles = i$4 `
2373
2407
  line-height: 150%;
2374
2408
  letter-spacing: -0.32px;
2375
2409
 
2410
+ box-sizing: border-box;
2376
2411
  background: #fff;
2377
2412
  border-radius: 10px;
2378
2413
  border: 1px solid #dbe2eb;
@@ -2491,6 +2526,11 @@ const chatSectionStyles = i$4 `
2491
2526
  color: rgb(140, 137, 156);
2492
2527
  border-radius: 50%;
2493
2528
 
2529
+ & > svg {
2530
+ height: 22px;
2531
+ width: 22px;
2532
+ }
2533
+
2494
2534
  &:hover {
2495
2535
  background-color: rgba(47, 43, 61, 0.08);
2496
2536
  }
@@ -3984,6 +4024,7 @@ class ChatSection extends r$2 {
3984
4024
  handleFeedback(rating, messageId, comment) {
3985
4025
  var _a, _b;
3986
4026
  if (rating === 'bad') {
4027
+ this.sendEvent('thumbsDown');
3987
4028
  this.feedbackDetails = {
3988
4029
  messageId,
3989
4030
  threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
@@ -3991,6 +4032,7 @@ class ChatSection extends r$2 {
3991
4032
  };
3992
4033
  return;
3993
4034
  }
4035
+ this.sendEvent('thumbsUp');
3994
4036
  this.dispatchEvent(new CustomEvent('submit-feedback', {
3995
4037
  detail: {
3996
4038
  messageId: messageId,
@@ -4126,7 +4168,7 @@ class ChatSection extends r$2 {
4126
4168
  `;
4127
4169
  }
4128
4170
  renderPrompts() {
4129
- if (this.isLoadingHistory || this.isTyping || this.isLoadingThreads) {
4171
+ if (this.isLoadingHistory || this.isStreaming || this.isLoadingThreads) {
4130
4172
  return E;
4131
4173
  }
4132
4174
  const isWelcomeMessage = this.messages.length === 1 && this.messages[0].sender === 'bot';
@@ -4257,10 +4299,14 @@ class ChatSection extends r$2 {
4257
4299
  <button
4258
4300
  class="btn btn-icon new-search-btn"
4259
4301
  @click=${(e) => {
4260
- var _a;
4302
+ var _a, _b;
4261
4303
  e.preventDefault();
4262
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, '');
4304
+ if ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) {
4305
+ this.sendEvent('newSearch');
4306
+ }
4307
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, '');
4263
4308
  }}
4309
+ ?disabled=${this.isStreaming}
4264
4310
  >
4265
4311
  ${plusBtn}
4266
4312
  </button>
@@ -4279,6 +4325,9 @@ class ChatSection extends r$2 {
4279
4325
  @click=${(e) => {
4280
4326
  e.preventDefault();
4281
4327
  this.showChatThreads = !this.showChatThreads;
4328
+ if (this.showChatThreads) {
4329
+ this.sendEvent('showThreads');
4330
+ }
4282
4331
  }}
4283
4332
  >
4284
4333
  ${timerBtn}
@@ -4348,7 +4397,7 @@ class ChatSection extends r$2 {
4348
4397
  ? x `<div
4349
4398
  class="trash-icon"
4350
4399
  @click=${() => {
4351
- if (this.isTyping) {
4400
+ if (this.isStreaming) {
4352
4401
  return;
4353
4402
  }
4354
4403
  this.deleteAllThreads = true;
@@ -4364,17 +4413,18 @@ class ChatSection extends r$2 {
4364
4413
  <div
4365
4414
  class=${e$1({
4366
4415
  'thread-title': true,
4367
- disabled: this.isTyping,
4416
+ disabled: this.isStreaming,
4368
4417
  })}
4369
4418
  >
4370
4419
  <p
4371
4420
  @click=${() => {
4372
- var _a;
4373
- if (this.isTyping) {
4421
+ var _a, _b;
4422
+ if (this.isStreaming ||
4423
+ ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) === thread.threadId) {
4374
4424
  return;
4375
4425
  }
4376
4426
  this.showChatThreads = false;
4377
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, thread.threadId);
4427
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, thread.threadId);
4378
4428
  }}
4379
4429
  >
4380
4430
  ${thread.title || 'New Search'}
@@ -4382,7 +4432,7 @@ class ChatSection extends r$2 {
4382
4432
  <div
4383
4433
  class="trash-icon"
4384
4434
  @click=${() => {
4385
- if (this.isTyping) {
4435
+ if (this.isStreaming) {
4386
4436
  return;
4387
4437
  }
4388
4438
  this.deleteThreadId = thread.threadId;
@@ -4431,7 +4481,7 @@ class ChatSection extends r$2 {
4431
4481
  modal: this.viewType === 'modal',
4432
4482
  })}
4433
4483
  type="submit"
4434
- ?disabled=${this.isTyping || this.isLoadingHistory}
4484
+ ?disabled=${this.isStreaming || this.isLoadingHistory}
4435
4485
  >
4436
4486
  ${sendFilledIcon}
4437
4487
  </button>
@@ -4439,9 +4489,15 @@ class ChatSection extends r$2 {
4439
4489
  ${this.viewType === 'modal'
4440
4490
  ? x ` <footer>
4441
4491
  Powered by
4442
- <a target="_blank" href="https://shopgpt.edgeagents.ai"
4443
- >Blotout</a
4492
+ <a
4493
+ target="_blank"
4494
+ href="https://shopgpt.edgeagents.ai"
4495
+ @click=${() => {
4496
+ this.sendEvent('blotoutLinkClicked');
4497
+ }}
4444
4498
  >
4499
+ Blotout
4500
+ </a>
4445
4501
  </footer>`
4446
4502
  : E}
4447
4503
  </div>
@@ -4545,6 +4601,10 @@ __decorate([
4545
4601
  n({ type: Boolean }),
4546
4602
  __metadata("design:type", Boolean)
4547
4603
  ], ChatSection.prototype, "isTyping", void 0);
4604
+ __decorate([
4605
+ n({ type: Boolean }),
4606
+ __metadata("design:type", Boolean)
4607
+ ], ChatSection.prototype, "isStreaming", void 0);
4548
4608
  __decorate([
4549
4609
  n({ type: Boolean }),
4550
4610
  __metadata("design:type", Boolean)
@@ -4677,6 +4737,7 @@ class ShopGPT extends r$2 {
4677
4737
  this.isLoadingHistory = false;
4678
4738
  this.isLoadingThreads = false;
4679
4739
  this.isTyping = false;
4740
+ this.isStreaming = false;
4680
4741
  this.isFailed = false;
4681
4742
  this.selectedThreadId = '';
4682
4743
  this.products = [];
@@ -4810,6 +4871,7 @@ class ShopGPT extends r$2 {
4810
4871
  }
4811
4872
  try {
4812
4873
  this.isTyping = true;
4874
+ this.isStreaming = true;
4813
4875
  const response = await this.shopGPTAPI.processQuery('', thread.threadId, productHandle);
4814
4876
  this.processMessageResponse(response);
4815
4877
  }
@@ -4817,6 +4879,7 @@ class ShopGPT extends r$2 {
4817
4879
  logger.error(error);
4818
4880
  this.isFailed = true;
4819
4881
  this.isTyping = false;
4882
+ this.isStreaming = false;
4820
4883
  }
4821
4884
  }
4822
4885
  async loadChatThreads() {
@@ -4843,7 +4906,7 @@ class ShopGPT extends r$2 {
4843
4906
  }
4844
4907
  }
4845
4908
  if (latestThread) {
4846
- this.setSelectedThreadId(latestThread.threadId);
4909
+ this.setSelectedThreadId(latestThread.threadId, true);
4847
4910
  }
4848
4911
  else if (!this.devMode && this.isFromAd()) {
4849
4912
  this.createChatThread({ title: '' }, true);
@@ -4898,9 +4961,12 @@ class ShopGPT extends r$2 {
4898
4961
  logger.error(e);
4899
4962
  }
4900
4963
  }
4901
- async setSelectedThreadId(threadId) {
4964
+ async setSelectedThreadId(threadId, silent) {
4902
4965
  this.isFailed = false;
4903
4966
  this.selectedThreadId = threadId;
4967
+ if (threadId && !silent) {
4968
+ this.shopGPTAPI.sendEvent('switchThread');
4969
+ }
4904
4970
  await Promise.all([
4905
4971
  this.loadHistory(threadId),
4906
4972
  this.loadCustomPrompts(threadId),
@@ -4932,6 +4998,7 @@ class ShopGPT extends r$2 {
4932
4998
  logger.error('ThreadId is missing to delete the thread!');
4933
4999
  return;
4934
5000
  }
5001
+ this.shopGPTAPI.sendEvent('singleThreadDelete');
4935
5002
  this.shopGPTAPI
4936
5003
  .deleteSingleThread(threadId)
4937
5004
  .then(this.loadChatThreads.bind(this))
@@ -4946,6 +5013,7 @@ class ShopGPT extends r$2 {
4946
5013
  handleAllThreadsDelete(e) {
4947
5014
  e.stopPropagation();
4948
5015
  this.isLoadingThreads = true;
5016
+ this.shopGPTAPI.sendEvent('allThreadsDelete');
4949
5017
  this.shopGPTAPI
4950
5018
  .deleteAllThreads()
4951
5019
  .then(this.loadChatThreads.bind(this))
@@ -5023,6 +5091,7 @@ class ShopGPT extends r$2 {
5023
5091
  }
5024
5092
  else if (eventName === 'MessageComplete') {
5025
5093
  isMessageCompleted = true;
5094
+ this.isStreaming = false;
5026
5095
  this.handleProductsComplete(products, isMessageCompleted);
5027
5096
  this.handleCompleteMessage(data);
5028
5097
  }
@@ -5042,7 +5111,7 @@ class ShopGPT extends r$2 {
5042
5111
  async sendMessageToServer(e, message, isPrompt = false) {
5043
5112
  e.preventDefault();
5044
5113
  e.stopPropagation();
5045
- if (!message || this.isTyping || this.isLoadingHistory) {
5114
+ if (!message || this.isStreaming || this.isLoadingHistory) {
5046
5115
  return;
5047
5116
  }
5048
5117
  this.isFailed = false;
@@ -5053,6 +5122,7 @@ class ShopGPT extends r$2 {
5053
5122
  }
5054
5123
  this.messages = [{ sender: 'user', message }, ...this.messages];
5055
5124
  this.isTyping = true;
5125
+ this.isStreaming = true;
5056
5126
  const response = await this.submitQuery(message);
5057
5127
  this.processMessageResponse(response);
5058
5128
  }
@@ -5060,6 +5130,7 @@ class ShopGPT extends r$2 {
5060
5130
  logger.error(err);
5061
5131
  this.isFailed = true;
5062
5132
  this.isTyping = false;
5133
+ this.isStreaming = false;
5063
5134
  }
5064
5135
  }
5065
5136
  submitFeedback(e) {
@@ -5113,7 +5184,7 @@ class ShopGPT extends r$2 {
5113
5184
  .selectedThreadId=${this.selectedThreadId}
5114
5185
  .setSelectedThreadId=${this.setSelectedThreadId.bind(this)}
5115
5186
  .isLoading=${this.isLoadingThreads}
5116
- .isTyping=${this.isTyping}
5187
+ .isStreaming=${this.isStreaming}
5117
5188
  .merchantUrl=${this.merchantUrl}
5118
5189
  .css=${this.css}
5119
5190
  ></chat-threads>
@@ -5131,6 +5202,7 @@ class ShopGPT extends r$2 {
5131
5202
  .isFailed=${this.isFailed}
5132
5203
  .isLoadingHistory=${this.isLoadingHistory}
5133
5204
  .isTyping=${this.isTyping}
5205
+ .isStreaming=${this.isStreaming}
5134
5206
  .messages=${this.messages}
5135
5207
  .siteCurrency=${this.getSiteCurrency()}
5136
5208
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5155,6 +5227,7 @@ class ShopGPT extends r$2 {
5155
5227
  const thread = this.chatThreads.get(this.selectedThreadId);
5156
5228
  const closeModal = () => {
5157
5229
  this.modalState = 'close';
5230
+ this.shopGPTAPI.sendEvent('chatbotClosed');
5158
5231
  };
5159
5232
  if (this.modalState === 'close') {
5160
5233
  return x ` <div class="chatbot-widget">
@@ -5201,6 +5274,7 @@ class ShopGPT extends r$2 {
5201
5274
  .isFailed=${this.isFailed}
5202
5275
  .isLoadingHistory=${this.isLoadingHistory}
5203
5276
  .isTyping=${this.isTyping}
5277
+ .isStreaming=${this.isStreaming}
5204
5278
  .messages=${this.messages}
5205
5279
  .siteCurrency=${this.getSiteCurrency()}
5206
5280
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5291,6 +5365,10 @@ __decorate([
5291
5365
  n({ type: Boolean }),
5292
5366
  __metadata("design:type", Object)
5293
5367
  ], ShopGPT.prototype, "isTyping", void 0);
5368
+ __decorate([
5369
+ n({ type: Boolean }),
5370
+ __metadata("design:type", Object)
5371
+ ], ShopGPT.prototype, "isStreaming", void 0);
5294
5372
  __decorate([
5295
5373
  n({ type: Boolean }),
5296
5374
  __metadata("design:type", Object)
package/index.js CHANGED
@@ -413,9 +413,18 @@ var ProvidersShopGptSdk = (function () {
413
413
  const uiActions = new Set([
414
414
  'shopGPTInitialized',
415
415
  'chatbotOpened',
416
+ 'chatbotClosed',
417
+ 'singleThreadDelete',
418
+ 'allThreadsDelete',
419
+ 'switchThread',
420
+ 'newSearch',
421
+ 'thumbsUp',
422
+ 'thumbsDown',
423
+ 'showThreads',
416
424
  'queryInteractions',
417
425
  'promptClicked',
418
426
  'productRecommendationClicked',
427
+ 'blotoutLinkClicked',
419
428
  ]);
420
429
  /** Action length should not exceed 42 */
421
430
  new Set([
@@ -770,10 +779,11 @@ var ProvidersShopGptSdk = (function () {
770
779
  const data = (await response.json());
771
780
  return data.customPrompts;
772
781
  };
773
- const sendEvent = async (action, currency, actionData) => {
782
+ const sendEvent = (action, currency, actionData) => {
774
783
  var _a;
775
784
  const storageData = (_a = getProductActions(baseURL, sessionId)) !== null && _a !== void 0 ? _a : {};
776
- const response = await fetchImpl(getURL('/user/event'), {
785
+ // This endpoint sends user events to the server, we don't need to wait for the response
786
+ fetchImpl(getURL('/user/event'), {
777
787
  method: 'POST',
778
788
  headers: getHeaders(true),
779
789
  body: JSON.stringify({
@@ -787,10 +797,13 @@ var ProvidersShopGptSdk = (function () {
787
797
  },
788
798
  }),
789
799
  credentials: 'include',
790
- });
791
- if (!response.ok) {
792
- throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
793
- }
800
+ })
801
+ .then(async (response) => {
802
+ if (!response.ok) {
803
+ throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
804
+ }
805
+ })
806
+ .catch(logger.error);
794
807
  };
795
808
  return {
796
809
  processQuery,
@@ -1092,6 +1105,7 @@ var ProvidersShopGptSdk = (function () {
1092
1105
  height: 56px;
1093
1106
  background-color: var(--shopgpt-primary);
1094
1107
  border-radius: 50%;
1108
+ display: flex;
1095
1109
  justify-content: center;
1096
1110
  align-items: center;
1097
1111
  box-shadow: 0 0 4px 1px var(--shopgpt-white);
@@ -1524,6 +1538,13 @@ var ProvidersShopGptSdk = (function () {
1524
1538
  }
1525
1539
  return `https://${this.merchantUrl}`;
1526
1540
  }
1541
+ sendEvent(action, actionData) {
1542
+ this.dispatchEvent(new CustomEvent('send-event', {
1543
+ detail: { action, actionData },
1544
+ composed: true,
1545
+ bubbles: true,
1546
+ }));
1547
+ }
1527
1548
  handleThreadDelete() {
1528
1549
  if (this.deleteAllThreads) {
1529
1550
  this.dispatchEvent(new CustomEvent('delete-all-threads', {
@@ -1558,7 +1579,7 @@ var ProvidersShopGptSdk = (function () {
1558
1579
  ? x `<div
1559
1580
  class="trash-icon"
1560
1581
  @click=${() => {
1561
- if (this.isLoading || this.isTyping) {
1582
+ if (this.isLoading || this.isStreaming) {
1562
1583
  return;
1563
1584
  }
1564
1585
  this.deleteAllThreads = true;
@@ -1575,13 +1596,15 @@ var ProvidersShopGptSdk = (function () {
1575
1596
  class=${e$1({
1576
1597
  'thread-wrapper': true,
1577
1598
  active: this.selectedThreadId === thread.threadId,
1578
- disabled: this.isTyping,
1599
+ disabled: this.isStreaming,
1579
1600
  })}
1580
1601
  >
1581
1602
  <div
1582
1603
  class="thread-title"
1583
1604
  @click=${async () => {
1584
- if (this.isLoading || this.isTyping) {
1605
+ if (this.isLoading ||
1606
+ this.isStreaming ||
1607
+ this.selectedThreadId === thread.threadId) {
1585
1608
  return;
1586
1609
  }
1587
1610
  await this.setSelectedThreadId(thread.threadId);
@@ -1592,7 +1615,7 @@ var ProvidersShopGptSdk = (function () {
1592
1615
  <div
1593
1616
  class="trash-icon"
1594
1617
  @click=${() => {
1595
- if (this.isLoading || this.isTyping) {
1618
+ if (this.isLoading || this.isStreaming) {
1596
1619
  return;
1597
1620
  }
1598
1621
  this.deleteThreadId = thread.threadId;
@@ -1613,8 +1636,13 @@ var ProvidersShopGptSdk = (function () {
1613
1636
  <span class="line"></span>
1614
1637
  <button
1615
1638
  class="btn-new-search"
1616
- ?disabled=${this.isLoading || this.isTyping}
1617
- @click=${() => this.setSelectedThreadId('')}
1639
+ ?disabled=${this.isLoading || this.isStreaming}
1640
+ @click=${() => {
1641
+ if (this.selectedThreadId) {
1642
+ this.sendEvent('newSearch');
1643
+ }
1644
+ this.setSelectedThreadId('');
1645
+ }}
1618
1646
  >
1619
1647
  New Search
1620
1648
  </button>
@@ -1671,7 +1699,7 @@ var ProvidersShopGptSdk = (function () {
1671
1699
  __decorate([
1672
1700
  n({ type: Boolean }),
1673
1701
  __metadata("design:type", Boolean)
1674
- ], ChatThreads.prototype, "isTyping", void 0);
1702
+ ], ChatThreads.prototype, "isStreaming", void 0);
1675
1703
  __decorate([
1676
1704
  n({ type: String }),
1677
1705
  __metadata("design:type", String)
@@ -2342,6 +2370,12 @@ var ProvidersShopGptSdk = (function () {
2342
2370
  background: #2b65cf;
2343
2371
  opacity: 1;
2344
2372
  }
2373
+
2374
+ .new-search-btn:disabled {
2375
+ background: #808080;
2376
+ cursor: not-allowed;
2377
+ opacity: 0.5;
2378
+ }
2345
2379
  }
2346
2380
  }
2347
2381
 
@@ -2374,6 +2408,7 @@ var ProvidersShopGptSdk = (function () {
2374
2408
  line-height: 150%;
2375
2409
  letter-spacing: -0.32px;
2376
2410
 
2411
+ box-sizing: border-box;
2377
2412
  background: #fff;
2378
2413
  border-radius: 10px;
2379
2414
  border: 1px solid #dbe2eb;
@@ -2492,6 +2527,11 @@ var ProvidersShopGptSdk = (function () {
2492
2527
  color: rgb(140, 137, 156);
2493
2528
  border-radius: 50%;
2494
2529
 
2530
+ & > svg {
2531
+ height: 22px;
2532
+ width: 22px;
2533
+ }
2534
+
2495
2535
  &:hover {
2496
2536
  background-color: rgba(47, 43, 61, 0.08);
2497
2537
  }
@@ -3985,6 +4025,7 @@ ${this.comment ? this.comment : E}</textarea
3985
4025
  handleFeedback(rating, messageId, comment) {
3986
4026
  var _a, _b;
3987
4027
  if (rating === 'bad') {
4028
+ this.sendEvent('thumbsDown');
3988
4029
  this.feedbackDetails = {
3989
4030
  messageId,
3990
4031
  threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
@@ -3992,6 +4033,7 @@ ${this.comment ? this.comment : E}</textarea
3992
4033
  };
3993
4034
  return;
3994
4035
  }
4036
+ this.sendEvent('thumbsUp');
3995
4037
  this.dispatchEvent(new CustomEvent('submit-feedback', {
3996
4038
  detail: {
3997
4039
  messageId: messageId,
@@ -4127,7 +4169,7 @@ ${this.comment ? this.comment : E}</textarea
4127
4169
  `;
4128
4170
  }
4129
4171
  renderPrompts() {
4130
- if (this.isLoadingHistory || this.isTyping || this.isLoadingThreads) {
4172
+ if (this.isLoadingHistory || this.isStreaming || this.isLoadingThreads) {
4131
4173
  return E;
4132
4174
  }
4133
4175
  const isWelcomeMessage = this.messages.length === 1 && this.messages[0].sender === 'bot';
@@ -4258,10 +4300,14 @@ ${this.comment ? this.comment : E}</textarea
4258
4300
  <button
4259
4301
  class="btn btn-icon new-search-btn"
4260
4302
  @click=${(e) => {
4261
- var _a;
4303
+ var _a, _b;
4262
4304
  e.preventDefault();
4263
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, '');
4305
+ if ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) {
4306
+ this.sendEvent('newSearch');
4307
+ }
4308
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, '');
4264
4309
  }}
4310
+ ?disabled=${this.isStreaming}
4265
4311
  >
4266
4312
  ${plusBtn}
4267
4313
  </button>
@@ -4280,6 +4326,9 @@ ${this.comment ? this.comment : E}</textarea
4280
4326
  @click=${(e) => {
4281
4327
  e.preventDefault();
4282
4328
  this.showChatThreads = !this.showChatThreads;
4329
+ if (this.showChatThreads) {
4330
+ this.sendEvent('showThreads');
4331
+ }
4283
4332
  }}
4284
4333
  >
4285
4334
  ${timerBtn}
@@ -4349,7 +4398,7 @@ ${this.comment ? this.comment : E}</textarea
4349
4398
  ? x `<div
4350
4399
  class="trash-icon"
4351
4400
  @click=${() => {
4352
- if (this.isTyping) {
4401
+ if (this.isStreaming) {
4353
4402
  return;
4354
4403
  }
4355
4404
  this.deleteAllThreads = true;
@@ -4365,17 +4414,18 @@ ${this.comment ? this.comment : E}</textarea
4365
4414
  <div
4366
4415
  class=${e$1({
4367
4416
  'thread-title': true,
4368
- disabled: this.isTyping,
4417
+ disabled: this.isStreaming,
4369
4418
  })}
4370
4419
  >
4371
4420
  <p
4372
4421
  @click=${() => {
4373
- var _a;
4374
- if (this.isTyping) {
4422
+ var _a, _b;
4423
+ if (this.isStreaming ||
4424
+ ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) === thread.threadId) {
4375
4425
  return;
4376
4426
  }
4377
4427
  this.showChatThreads = false;
4378
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, thread.threadId);
4428
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, thread.threadId);
4379
4429
  }}
4380
4430
  >
4381
4431
  ${thread.title || 'New Search'}
@@ -4383,7 +4433,7 @@ ${this.comment ? this.comment : E}</textarea
4383
4433
  <div
4384
4434
  class="trash-icon"
4385
4435
  @click=${() => {
4386
- if (this.isTyping) {
4436
+ if (this.isStreaming) {
4387
4437
  return;
4388
4438
  }
4389
4439
  this.deleteThreadId = thread.threadId;
@@ -4432,7 +4482,7 @@ ${this.comment ? this.comment : E}</textarea
4432
4482
  modal: this.viewType === 'modal',
4433
4483
  })}
4434
4484
  type="submit"
4435
- ?disabled=${this.isTyping || this.isLoadingHistory}
4485
+ ?disabled=${this.isStreaming || this.isLoadingHistory}
4436
4486
  >
4437
4487
  ${sendFilledIcon}
4438
4488
  </button>
@@ -4440,9 +4490,15 @@ ${this.comment ? this.comment : E}</textarea
4440
4490
  ${this.viewType === 'modal'
4441
4491
  ? x ` <footer>
4442
4492
  Powered by
4443
- <a target="_blank" href="https://shopgpt.edgeagents.ai"
4444
- >Blotout</a
4493
+ <a
4494
+ target="_blank"
4495
+ href="https://shopgpt.edgeagents.ai"
4496
+ @click=${() => {
4497
+ this.sendEvent('blotoutLinkClicked');
4498
+ }}
4445
4499
  >
4500
+ Blotout
4501
+ </a>
4446
4502
  </footer>`
4447
4503
  : E}
4448
4504
  </div>
@@ -4546,6 +4602,10 @@ ${this.comment ? this.comment : E}</textarea
4546
4602
  n({ type: Boolean }),
4547
4603
  __metadata("design:type", Boolean)
4548
4604
  ], ChatSection.prototype, "isTyping", void 0);
4605
+ __decorate([
4606
+ n({ type: Boolean }),
4607
+ __metadata("design:type", Boolean)
4608
+ ], ChatSection.prototype, "isStreaming", void 0);
4549
4609
  __decorate([
4550
4610
  n({ type: Boolean }),
4551
4611
  __metadata("design:type", Boolean)
@@ -4678,6 +4738,7 @@ ${this.comment ? this.comment : E}</textarea
4678
4738
  this.isLoadingHistory = false;
4679
4739
  this.isLoadingThreads = false;
4680
4740
  this.isTyping = false;
4741
+ this.isStreaming = false;
4681
4742
  this.isFailed = false;
4682
4743
  this.selectedThreadId = '';
4683
4744
  this.products = [];
@@ -4811,6 +4872,7 @@ ${this.comment ? this.comment : E}</textarea
4811
4872
  }
4812
4873
  try {
4813
4874
  this.isTyping = true;
4875
+ this.isStreaming = true;
4814
4876
  const response = await this.shopGPTAPI.processQuery('', thread.threadId, productHandle);
4815
4877
  this.processMessageResponse(response);
4816
4878
  }
@@ -4818,6 +4880,7 @@ ${this.comment ? this.comment : E}</textarea
4818
4880
  logger.error(error);
4819
4881
  this.isFailed = true;
4820
4882
  this.isTyping = false;
4883
+ this.isStreaming = false;
4821
4884
  }
4822
4885
  }
4823
4886
  async loadChatThreads() {
@@ -4844,7 +4907,7 @@ ${this.comment ? this.comment : E}</textarea
4844
4907
  }
4845
4908
  }
4846
4909
  if (latestThread) {
4847
- this.setSelectedThreadId(latestThread.threadId);
4910
+ this.setSelectedThreadId(latestThread.threadId, true);
4848
4911
  }
4849
4912
  else if (!this.devMode && this.isFromAd()) {
4850
4913
  this.createChatThread({ title: '' }, true);
@@ -4899,9 +4962,12 @@ ${this.comment ? this.comment : E}</textarea
4899
4962
  logger.error(e);
4900
4963
  }
4901
4964
  }
4902
- async setSelectedThreadId(threadId) {
4965
+ async setSelectedThreadId(threadId, silent) {
4903
4966
  this.isFailed = false;
4904
4967
  this.selectedThreadId = threadId;
4968
+ if (threadId && !silent) {
4969
+ this.shopGPTAPI.sendEvent('switchThread');
4970
+ }
4905
4971
  await Promise.all([
4906
4972
  this.loadHistory(threadId),
4907
4973
  this.loadCustomPrompts(threadId),
@@ -4933,6 +4999,7 @@ ${this.comment ? this.comment : E}</textarea
4933
4999
  logger.error('ThreadId is missing to delete the thread!');
4934
5000
  return;
4935
5001
  }
5002
+ this.shopGPTAPI.sendEvent('singleThreadDelete');
4936
5003
  this.shopGPTAPI
4937
5004
  .deleteSingleThread(threadId)
4938
5005
  .then(this.loadChatThreads.bind(this))
@@ -4947,6 +5014,7 @@ ${this.comment ? this.comment : E}</textarea
4947
5014
  handleAllThreadsDelete(e) {
4948
5015
  e.stopPropagation();
4949
5016
  this.isLoadingThreads = true;
5017
+ this.shopGPTAPI.sendEvent('allThreadsDelete');
4950
5018
  this.shopGPTAPI
4951
5019
  .deleteAllThreads()
4952
5020
  .then(this.loadChatThreads.bind(this))
@@ -5024,6 +5092,7 @@ ${this.comment ? this.comment : E}</textarea
5024
5092
  }
5025
5093
  else if (eventName === 'MessageComplete') {
5026
5094
  isMessageCompleted = true;
5095
+ this.isStreaming = false;
5027
5096
  this.handleProductsComplete(products, isMessageCompleted);
5028
5097
  this.handleCompleteMessage(data);
5029
5098
  }
@@ -5043,7 +5112,7 @@ ${this.comment ? this.comment : E}</textarea
5043
5112
  async sendMessageToServer(e, message, isPrompt = false) {
5044
5113
  e.preventDefault();
5045
5114
  e.stopPropagation();
5046
- if (!message || this.isTyping || this.isLoadingHistory) {
5115
+ if (!message || this.isStreaming || this.isLoadingHistory) {
5047
5116
  return;
5048
5117
  }
5049
5118
  this.isFailed = false;
@@ -5054,6 +5123,7 @@ ${this.comment ? this.comment : E}</textarea
5054
5123
  }
5055
5124
  this.messages = [{ sender: 'user', message }, ...this.messages];
5056
5125
  this.isTyping = true;
5126
+ this.isStreaming = true;
5057
5127
  const response = await this.submitQuery(message);
5058
5128
  this.processMessageResponse(response);
5059
5129
  }
@@ -5061,6 +5131,7 @@ ${this.comment ? this.comment : E}</textarea
5061
5131
  logger.error(err);
5062
5132
  this.isFailed = true;
5063
5133
  this.isTyping = false;
5134
+ this.isStreaming = false;
5064
5135
  }
5065
5136
  }
5066
5137
  submitFeedback(e) {
@@ -5114,7 +5185,7 @@ ${this.comment ? this.comment : E}</textarea
5114
5185
  .selectedThreadId=${this.selectedThreadId}
5115
5186
  .setSelectedThreadId=${this.setSelectedThreadId.bind(this)}
5116
5187
  .isLoading=${this.isLoadingThreads}
5117
- .isTyping=${this.isTyping}
5188
+ .isStreaming=${this.isStreaming}
5118
5189
  .merchantUrl=${this.merchantUrl}
5119
5190
  .css=${this.css}
5120
5191
  ></chat-threads>
@@ -5132,6 +5203,7 @@ ${this.comment ? this.comment : E}</textarea
5132
5203
  .isFailed=${this.isFailed}
5133
5204
  .isLoadingHistory=${this.isLoadingHistory}
5134
5205
  .isTyping=${this.isTyping}
5206
+ .isStreaming=${this.isStreaming}
5135
5207
  .messages=${this.messages}
5136
5208
  .siteCurrency=${this.getSiteCurrency()}
5137
5209
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5156,6 +5228,7 @@ ${this.comment ? this.comment : E}</textarea
5156
5228
  const thread = this.chatThreads.get(this.selectedThreadId);
5157
5229
  const closeModal = () => {
5158
5230
  this.modalState = 'close';
5231
+ this.shopGPTAPI.sendEvent('chatbotClosed');
5159
5232
  };
5160
5233
  if (this.modalState === 'close') {
5161
5234
  return x ` <div class="chatbot-widget">
@@ -5202,6 +5275,7 @@ ${this.comment ? this.comment : E}</textarea
5202
5275
  .isFailed=${this.isFailed}
5203
5276
  .isLoadingHistory=${this.isLoadingHistory}
5204
5277
  .isTyping=${this.isTyping}
5278
+ .isStreaming=${this.isStreaming}
5205
5279
  .messages=${this.messages}
5206
5280
  .siteCurrency=${this.getSiteCurrency()}
5207
5281
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5292,6 +5366,10 @@ ${this.comment ? this.comment : E}</textarea
5292
5366
  n({ type: Boolean }),
5293
5367
  __metadata("design:type", Object)
5294
5368
  ], ShopGPT.prototype, "isTyping", void 0);
5369
+ __decorate([
5370
+ n({ type: Boolean }),
5371
+ __metadata("design:type", Object)
5372
+ ], ShopGPT.prototype, "isStreaming", void 0);
5295
5373
  __decorate([
5296
5374
  n({ type: Boolean }),
5297
5375
  __metadata("design:type", Object)
package/index.mjs CHANGED
@@ -410,9 +410,18 @@ const createExperiment = (props) => {
410
410
  const uiActions = new Set([
411
411
  'shopGPTInitialized',
412
412
  'chatbotOpened',
413
+ 'chatbotClosed',
414
+ 'singleThreadDelete',
415
+ 'allThreadsDelete',
416
+ 'switchThread',
417
+ 'newSearch',
418
+ 'thumbsUp',
419
+ 'thumbsDown',
420
+ 'showThreads',
413
421
  'queryInteractions',
414
422
  'promptClicked',
415
423
  'productRecommendationClicked',
424
+ 'blotoutLinkClicked',
416
425
  ]);
417
426
  /** Action length should not exceed 42 */
418
427
  new Set([
@@ -767,10 +776,11 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
767
776
  const data = (await response.json());
768
777
  return data.customPrompts;
769
778
  };
770
- const sendEvent = async (action, currency, actionData) => {
779
+ const sendEvent = (action, currency, actionData) => {
771
780
  var _a;
772
781
  const storageData = (_a = getProductActions(baseURL, sessionId)) !== null && _a !== void 0 ? _a : {};
773
- const response = await fetchImpl(getURL('/user/event'), {
782
+ // This endpoint sends user events to the server, we don't need to wait for the response
783
+ fetchImpl(getURL('/user/event'), {
774
784
  method: 'POST',
775
785
  headers: getHeaders(true),
776
786
  body: JSON.stringify({
@@ -784,10 +794,13 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
784
794
  },
785
795
  }),
786
796
  credentials: 'include',
787
- });
788
- if (!response.ok) {
789
- throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
790
- }
797
+ })
798
+ .then(async (response) => {
799
+ if (!response.ok) {
800
+ throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
801
+ }
802
+ })
803
+ .catch(logger.error);
791
804
  };
792
805
  return {
793
806
  processQuery,
@@ -1089,6 +1102,7 @@ const shopGPTStyles = i$4 `
1089
1102
  height: 56px;
1090
1103
  background-color: var(--shopgpt-primary);
1091
1104
  border-radius: 50%;
1105
+ display: flex;
1092
1106
  justify-content: center;
1093
1107
  align-items: center;
1094
1108
  box-shadow: 0 0 4px 1px var(--shopgpt-white);
@@ -1521,6 +1535,13 @@ class ChatThreads extends r$2 {
1521
1535
  }
1522
1536
  return `https://${this.merchantUrl}`;
1523
1537
  }
1538
+ sendEvent(action, actionData) {
1539
+ this.dispatchEvent(new CustomEvent('send-event', {
1540
+ detail: { action, actionData },
1541
+ composed: true,
1542
+ bubbles: true,
1543
+ }));
1544
+ }
1524
1545
  handleThreadDelete() {
1525
1546
  if (this.deleteAllThreads) {
1526
1547
  this.dispatchEvent(new CustomEvent('delete-all-threads', {
@@ -1555,7 +1576,7 @@ class ChatThreads extends r$2 {
1555
1576
  ? x `<div
1556
1577
  class="trash-icon"
1557
1578
  @click=${() => {
1558
- if (this.isLoading || this.isTyping) {
1579
+ if (this.isLoading || this.isStreaming) {
1559
1580
  return;
1560
1581
  }
1561
1582
  this.deleteAllThreads = true;
@@ -1572,13 +1593,15 @@ class ChatThreads extends r$2 {
1572
1593
  class=${e$1({
1573
1594
  'thread-wrapper': true,
1574
1595
  active: this.selectedThreadId === thread.threadId,
1575
- disabled: this.isTyping,
1596
+ disabled: this.isStreaming,
1576
1597
  })}
1577
1598
  >
1578
1599
  <div
1579
1600
  class="thread-title"
1580
1601
  @click=${async () => {
1581
- if (this.isLoading || this.isTyping) {
1602
+ if (this.isLoading ||
1603
+ this.isStreaming ||
1604
+ this.selectedThreadId === thread.threadId) {
1582
1605
  return;
1583
1606
  }
1584
1607
  await this.setSelectedThreadId(thread.threadId);
@@ -1589,7 +1612,7 @@ class ChatThreads extends r$2 {
1589
1612
  <div
1590
1613
  class="trash-icon"
1591
1614
  @click=${() => {
1592
- if (this.isLoading || this.isTyping) {
1615
+ if (this.isLoading || this.isStreaming) {
1593
1616
  return;
1594
1617
  }
1595
1618
  this.deleteThreadId = thread.threadId;
@@ -1610,8 +1633,13 @@ class ChatThreads extends r$2 {
1610
1633
  <span class="line"></span>
1611
1634
  <button
1612
1635
  class="btn-new-search"
1613
- ?disabled=${this.isLoading || this.isTyping}
1614
- @click=${() => this.setSelectedThreadId('')}
1636
+ ?disabled=${this.isLoading || this.isStreaming}
1637
+ @click=${() => {
1638
+ if (this.selectedThreadId) {
1639
+ this.sendEvent('newSearch');
1640
+ }
1641
+ this.setSelectedThreadId('');
1642
+ }}
1615
1643
  >
1616
1644
  New Search
1617
1645
  </button>
@@ -1668,7 +1696,7 @@ __decorate([
1668
1696
  __decorate([
1669
1697
  n({ type: Boolean }),
1670
1698
  __metadata("design:type", Boolean)
1671
- ], ChatThreads.prototype, "isTyping", void 0);
1699
+ ], ChatThreads.prototype, "isStreaming", void 0);
1672
1700
  __decorate([
1673
1701
  n({ type: String }),
1674
1702
  __metadata("design:type", String)
@@ -2339,6 +2367,12 @@ const chatSectionStyles = i$4 `
2339
2367
  background: #2b65cf;
2340
2368
  opacity: 1;
2341
2369
  }
2370
+
2371
+ .new-search-btn:disabled {
2372
+ background: #808080;
2373
+ cursor: not-allowed;
2374
+ opacity: 0.5;
2375
+ }
2342
2376
  }
2343
2377
  }
2344
2378
 
@@ -2371,6 +2405,7 @@ const chatSectionStyles = i$4 `
2371
2405
  line-height: 150%;
2372
2406
  letter-spacing: -0.32px;
2373
2407
 
2408
+ box-sizing: border-box;
2374
2409
  background: #fff;
2375
2410
  border-radius: 10px;
2376
2411
  border: 1px solid #dbe2eb;
@@ -2489,6 +2524,11 @@ const chatSectionStyles = i$4 `
2489
2524
  color: rgb(140, 137, 156);
2490
2525
  border-radius: 50%;
2491
2526
 
2527
+ & > svg {
2528
+ height: 22px;
2529
+ width: 22px;
2530
+ }
2531
+
2492
2532
  &:hover {
2493
2533
  background-color: rgba(47, 43, 61, 0.08);
2494
2534
  }
@@ -3982,6 +4022,7 @@ class ChatSection extends r$2 {
3982
4022
  handleFeedback(rating, messageId, comment) {
3983
4023
  var _a, _b;
3984
4024
  if (rating === 'bad') {
4025
+ this.sendEvent('thumbsDown');
3985
4026
  this.feedbackDetails = {
3986
4027
  messageId,
3987
4028
  threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
@@ -3989,6 +4030,7 @@ class ChatSection extends r$2 {
3989
4030
  };
3990
4031
  return;
3991
4032
  }
4033
+ this.sendEvent('thumbsUp');
3992
4034
  this.dispatchEvent(new CustomEvent('submit-feedback', {
3993
4035
  detail: {
3994
4036
  messageId: messageId,
@@ -4124,7 +4166,7 @@ class ChatSection extends r$2 {
4124
4166
  `;
4125
4167
  }
4126
4168
  renderPrompts() {
4127
- if (this.isLoadingHistory || this.isTyping || this.isLoadingThreads) {
4169
+ if (this.isLoadingHistory || this.isStreaming || this.isLoadingThreads) {
4128
4170
  return E;
4129
4171
  }
4130
4172
  const isWelcomeMessage = this.messages.length === 1 && this.messages[0].sender === 'bot';
@@ -4255,10 +4297,14 @@ class ChatSection extends r$2 {
4255
4297
  <button
4256
4298
  class="btn btn-icon new-search-btn"
4257
4299
  @click=${(e) => {
4258
- var _a;
4300
+ var _a, _b;
4259
4301
  e.preventDefault();
4260
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, '');
4302
+ if ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) {
4303
+ this.sendEvent('newSearch');
4304
+ }
4305
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, '');
4261
4306
  }}
4307
+ ?disabled=${this.isStreaming}
4262
4308
  >
4263
4309
  ${plusBtn}
4264
4310
  </button>
@@ -4277,6 +4323,9 @@ class ChatSection extends r$2 {
4277
4323
  @click=${(e) => {
4278
4324
  e.preventDefault();
4279
4325
  this.showChatThreads = !this.showChatThreads;
4326
+ if (this.showChatThreads) {
4327
+ this.sendEvent('showThreads');
4328
+ }
4280
4329
  }}
4281
4330
  >
4282
4331
  ${timerBtn}
@@ -4346,7 +4395,7 @@ class ChatSection extends r$2 {
4346
4395
  ? x `<div
4347
4396
  class="trash-icon"
4348
4397
  @click=${() => {
4349
- if (this.isTyping) {
4398
+ if (this.isStreaming) {
4350
4399
  return;
4351
4400
  }
4352
4401
  this.deleteAllThreads = true;
@@ -4362,17 +4411,18 @@ class ChatSection extends r$2 {
4362
4411
  <div
4363
4412
  class=${e$1({
4364
4413
  'thread-title': true,
4365
- disabled: this.isTyping,
4414
+ disabled: this.isStreaming,
4366
4415
  })}
4367
4416
  >
4368
4417
  <p
4369
4418
  @click=${() => {
4370
- var _a;
4371
- if (this.isTyping) {
4419
+ var _a, _b;
4420
+ if (this.isStreaming ||
4421
+ ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) === thread.threadId) {
4372
4422
  return;
4373
4423
  }
4374
4424
  this.showChatThreads = false;
4375
- (_a = this.setSelectedThreadId) === null || _a === void 0 ? void 0 : _a.call(this, thread.threadId);
4425
+ (_b = this.setSelectedThreadId) === null || _b === void 0 ? void 0 : _b.call(this, thread.threadId);
4376
4426
  }}
4377
4427
  >
4378
4428
  ${thread.title || 'New Search'}
@@ -4380,7 +4430,7 @@ class ChatSection extends r$2 {
4380
4430
  <div
4381
4431
  class="trash-icon"
4382
4432
  @click=${() => {
4383
- if (this.isTyping) {
4433
+ if (this.isStreaming) {
4384
4434
  return;
4385
4435
  }
4386
4436
  this.deleteThreadId = thread.threadId;
@@ -4429,7 +4479,7 @@ class ChatSection extends r$2 {
4429
4479
  modal: this.viewType === 'modal',
4430
4480
  })}
4431
4481
  type="submit"
4432
- ?disabled=${this.isTyping || this.isLoadingHistory}
4482
+ ?disabled=${this.isStreaming || this.isLoadingHistory}
4433
4483
  >
4434
4484
  ${sendFilledIcon}
4435
4485
  </button>
@@ -4437,9 +4487,15 @@ class ChatSection extends r$2 {
4437
4487
  ${this.viewType === 'modal'
4438
4488
  ? x ` <footer>
4439
4489
  Powered by
4440
- <a target="_blank" href="https://shopgpt.edgeagents.ai"
4441
- >Blotout</a
4490
+ <a
4491
+ target="_blank"
4492
+ href="https://shopgpt.edgeagents.ai"
4493
+ @click=${() => {
4494
+ this.sendEvent('blotoutLinkClicked');
4495
+ }}
4442
4496
  >
4497
+ Blotout
4498
+ </a>
4443
4499
  </footer>`
4444
4500
  : E}
4445
4501
  </div>
@@ -4543,6 +4599,10 @@ __decorate([
4543
4599
  n({ type: Boolean }),
4544
4600
  __metadata("design:type", Boolean)
4545
4601
  ], ChatSection.prototype, "isTyping", void 0);
4602
+ __decorate([
4603
+ n({ type: Boolean }),
4604
+ __metadata("design:type", Boolean)
4605
+ ], ChatSection.prototype, "isStreaming", void 0);
4546
4606
  __decorate([
4547
4607
  n({ type: Boolean }),
4548
4608
  __metadata("design:type", Boolean)
@@ -4675,6 +4735,7 @@ class ShopGPT extends r$2 {
4675
4735
  this.isLoadingHistory = false;
4676
4736
  this.isLoadingThreads = false;
4677
4737
  this.isTyping = false;
4738
+ this.isStreaming = false;
4678
4739
  this.isFailed = false;
4679
4740
  this.selectedThreadId = '';
4680
4741
  this.products = [];
@@ -4808,6 +4869,7 @@ class ShopGPT extends r$2 {
4808
4869
  }
4809
4870
  try {
4810
4871
  this.isTyping = true;
4872
+ this.isStreaming = true;
4811
4873
  const response = await this.shopGPTAPI.processQuery('', thread.threadId, productHandle);
4812
4874
  this.processMessageResponse(response);
4813
4875
  }
@@ -4815,6 +4877,7 @@ class ShopGPT extends r$2 {
4815
4877
  logger.error(error);
4816
4878
  this.isFailed = true;
4817
4879
  this.isTyping = false;
4880
+ this.isStreaming = false;
4818
4881
  }
4819
4882
  }
4820
4883
  async loadChatThreads() {
@@ -4841,7 +4904,7 @@ class ShopGPT extends r$2 {
4841
4904
  }
4842
4905
  }
4843
4906
  if (latestThread) {
4844
- this.setSelectedThreadId(latestThread.threadId);
4907
+ this.setSelectedThreadId(latestThread.threadId, true);
4845
4908
  }
4846
4909
  else if (!this.devMode && this.isFromAd()) {
4847
4910
  this.createChatThread({ title: '' }, true);
@@ -4896,9 +4959,12 @@ class ShopGPT extends r$2 {
4896
4959
  logger.error(e);
4897
4960
  }
4898
4961
  }
4899
- async setSelectedThreadId(threadId) {
4962
+ async setSelectedThreadId(threadId, silent) {
4900
4963
  this.isFailed = false;
4901
4964
  this.selectedThreadId = threadId;
4965
+ if (threadId && !silent) {
4966
+ this.shopGPTAPI.sendEvent('switchThread');
4967
+ }
4902
4968
  await Promise.all([
4903
4969
  this.loadHistory(threadId),
4904
4970
  this.loadCustomPrompts(threadId),
@@ -4930,6 +4996,7 @@ class ShopGPT extends r$2 {
4930
4996
  logger.error('ThreadId is missing to delete the thread!');
4931
4997
  return;
4932
4998
  }
4999
+ this.shopGPTAPI.sendEvent('singleThreadDelete');
4933
5000
  this.shopGPTAPI
4934
5001
  .deleteSingleThread(threadId)
4935
5002
  .then(this.loadChatThreads.bind(this))
@@ -4944,6 +5011,7 @@ class ShopGPT extends r$2 {
4944
5011
  handleAllThreadsDelete(e) {
4945
5012
  e.stopPropagation();
4946
5013
  this.isLoadingThreads = true;
5014
+ this.shopGPTAPI.sendEvent('allThreadsDelete');
4947
5015
  this.shopGPTAPI
4948
5016
  .deleteAllThreads()
4949
5017
  .then(this.loadChatThreads.bind(this))
@@ -5021,6 +5089,7 @@ class ShopGPT extends r$2 {
5021
5089
  }
5022
5090
  else if (eventName === 'MessageComplete') {
5023
5091
  isMessageCompleted = true;
5092
+ this.isStreaming = false;
5024
5093
  this.handleProductsComplete(products, isMessageCompleted);
5025
5094
  this.handleCompleteMessage(data);
5026
5095
  }
@@ -5040,7 +5109,7 @@ class ShopGPT extends r$2 {
5040
5109
  async sendMessageToServer(e, message, isPrompt = false) {
5041
5110
  e.preventDefault();
5042
5111
  e.stopPropagation();
5043
- if (!message || this.isTyping || this.isLoadingHistory) {
5112
+ if (!message || this.isStreaming || this.isLoadingHistory) {
5044
5113
  return;
5045
5114
  }
5046
5115
  this.isFailed = false;
@@ -5051,6 +5120,7 @@ class ShopGPT extends r$2 {
5051
5120
  }
5052
5121
  this.messages = [{ sender: 'user', message }, ...this.messages];
5053
5122
  this.isTyping = true;
5123
+ this.isStreaming = true;
5054
5124
  const response = await this.submitQuery(message);
5055
5125
  this.processMessageResponse(response);
5056
5126
  }
@@ -5058,6 +5128,7 @@ class ShopGPT extends r$2 {
5058
5128
  logger.error(err);
5059
5129
  this.isFailed = true;
5060
5130
  this.isTyping = false;
5131
+ this.isStreaming = false;
5061
5132
  }
5062
5133
  }
5063
5134
  submitFeedback(e) {
@@ -5111,7 +5182,7 @@ class ShopGPT extends r$2 {
5111
5182
  .selectedThreadId=${this.selectedThreadId}
5112
5183
  .setSelectedThreadId=${this.setSelectedThreadId.bind(this)}
5113
5184
  .isLoading=${this.isLoadingThreads}
5114
- .isTyping=${this.isTyping}
5185
+ .isStreaming=${this.isStreaming}
5115
5186
  .merchantUrl=${this.merchantUrl}
5116
5187
  .css=${this.css}
5117
5188
  ></chat-threads>
@@ -5129,6 +5200,7 @@ class ShopGPT extends r$2 {
5129
5200
  .isFailed=${this.isFailed}
5130
5201
  .isLoadingHistory=${this.isLoadingHistory}
5131
5202
  .isTyping=${this.isTyping}
5203
+ .isStreaming=${this.isStreaming}
5132
5204
  .messages=${this.messages}
5133
5205
  .siteCurrency=${this.getSiteCurrency()}
5134
5206
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5153,6 +5225,7 @@ class ShopGPT extends r$2 {
5153
5225
  const thread = this.chatThreads.get(this.selectedThreadId);
5154
5226
  const closeModal = () => {
5155
5227
  this.modalState = 'close';
5228
+ this.shopGPTAPI.sendEvent('chatbotClosed');
5156
5229
  };
5157
5230
  if (this.modalState === 'close') {
5158
5231
  return x ` <div class="chatbot-widget">
@@ -5199,6 +5272,7 @@ class ShopGPT extends r$2 {
5199
5272
  .isFailed=${this.isFailed}
5200
5273
  .isLoadingHistory=${this.isLoadingHistory}
5201
5274
  .isTyping=${this.isTyping}
5275
+ .isStreaming=${this.isStreaming}
5202
5276
  .messages=${this.messages}
5203
5277
  .siteCurrency=${this.getSiteCurrency()}
5204
5278
  .sendMessageToServer=${this.sendMessageToServer.bind(this)}
@@ -5289,6 +5363,10 @@ __decorate([
5289
5363
  n({ type: Boolean }),
5290
5364
  __metadata("design:type", Object)
5291
5365
  ], ShopGPT.prototype, "isTyping", void 0);
5366
+ __decorate([
5367
+ n({ type: Boolean }),
5368
+ __metadata("design:type", Object)
5369
+ ], ShopGPT.prototype, "isStreaming", void 0);
5292
5370
  __decorate([
5293
5371
  n({ type: Boolean }),
5294
5372
  __metadata("design:type", Object)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-shop-gpt-sdk",
3
- "version": "1.10.3",
3
+ "version": "1.11.0",
4
4
  "description": "Shop GPT SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",