@xpert-ai/chatkit-web-component 0.5.0 → 0.5.2

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.
@@ -51,7 +51,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
51
51
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
52
52
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
53
53
 
54
- var _a, _b, _setTrainingOptOut_dec, _hideHistory_dec, _showHistory_dec, _sendCustomAction_dec, _shareThread_dec, _setThreadId_dec, _setRuntimeCapabilities_dec, _setComposerValue_dec, _sendUserMessage_dec, _fetchUpdates_dec, _focusComposer_dec, _c, _opts, _frameUrl, _frame, _wrapper, _launcherCloseButton, _launcherOpen, _chatMinimizedToPet, _framePetOptionsOverride, _petClosedByContextMenu, _shadow, _petOverlay, _resolveLoaded, _loaded, _messenger, _ChatKitElementBase_instances, emitAndThrow_fn, setOptionsDataAttributes_fn, getDisplayMode_fn, getConfiguredPetOptions_fn, mergeConfiguredPetPositionDefaults_fn, getOverlayPetOptions_fn, resolvePetAssetUrl_fn, resolveOverlayPetOptions_fn, getFrameOptions_fn, setLauncherOpen_fn, setChatMinimizedToPet_fn, syncPetOverlayOptions_fn, handlePetActivate_fn, handlePetClose_fn, handlePetReply_fn, handlePetThreadSummaryActivate_fn, _handleLauncherClose, getFrameUrl_fn, setFrameUrl_fn, consumeFrameUrl_fn, _handleFrameLoad, _initialized, maybeInit_fn, _init;
54
+ var _a, _b, _setTrainingOptOut_dec, _hideHistory_dec, _showHistory_dec, _sendCustomAction_dec, _shareThread_dec, _setThreadId_dec, _setRuntimeCapabilities_dec, _setComposerValue_dec, _sendUserMessage_dec, _fetchUpdates_dec, _focusComposer_dec, _c, _opts, _frameUrl, _frame, _wrapper, _launcherCloseButton, _launcherOpen, _chatMinimizedToPet, _framePetOptionsOverride, _petClosedByContextMenu, _shadow, _petOverlay, _resolveLoaded, _loaded, _channelId, _messenger, _ChatKitElementBase_instances, emitAndThrow_fn, setOptionsDataAttributes_fn, getDisplayMode_fn, getConfiguredPetOptions_fn, mergeConfiguredPetPositionDefaults_fn, getOverlayPetOptions_fn, resolvePetAssetUrl_fn, resolveOverlayPetOptions_fn, getFrameOptions_fn, setLauncherOpen_fn, setChatMinimizedToPet_fn, syncPetOverlayOptions_fn, handlePetActivate_fn, handlePetClose_fn, handlePetReply_fn, handlePetThreadSummaryActivate_fn, _handleLauncherClose, getFrameUrl_fn, setFrameUrl_fn, consumeFrameUrl_fn, _handleFrameLoad, _initialized, maybeInit_fn, _init;
55
55
  class EventEmitter {
56
56
  constructor() {
57
57
  __publicField(this, "callbacks", /* @__PURE__ */ new Map());
@@ -370,7 +370,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
370
370
  }
371
371
  });
372
372
  };
373
- function safeRandomUUID() {
373
+ function createSecureChannelId() {
374
374
  const cryptoRef = globalThis.crypto;
375
375
  if (typeof (cryptoRef == null ? void 0 : cryptoRef.randomUUID) === "function") {
376
376
  return cryptoRef.randomUUID();
@@ -382,7 +382,30 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
382
382
  bytes[8] = bytes[8] & 63 | 128;
383
383
  return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "$1-$2-$3-$4-$5");
384
384
  }
385
- return `ck_${Date.now()}_${Math.random().toString(16).slice(2)}`;
385
+ return null;
386
+ }
387
+ function safeRandomUUID() {
388
+ return createSecureChannelId() ?? `ck_${Date.now()}_${Math.random().toString(16).slice(2)}`;
389
+ }
390
+ function isTrustedChatKitMessageEvent(event, { channelId, expectedOrigin, expectedSource }) {
391
+ const payload = event.data;
392
+ if (!payload || typeof payload !== "object" || !("__xpaiChatKit" in payload)) {
393
+ return false;
394
+ }
395
+ if (payload.__xpaiChatKit !== true) {
396
+ return false;
397
+ }
398
+ if (expectedOrigin !== "*" && event.origin !== expectedOrigin) {
399
+ return false;
400
+ }
401
+ if (event.source === expectedSource) {
402
+ return true;
403
+ }
404
+ const normalizedChannelId = channelId == null ? void 0 : channelId.trim();
405
+ if (normalizedChannelId) {
406
+ return "channelId" in payload && payload.channelId === normalizedChannelId;
407
+ }
408
+ return false;
386
409
  }
387
410
  let IntegrationError$1 = class IntegrationError2 extends Error {
388
411
  constructor(message) {
@@ -416,10 +439,12 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
416
439
  handlers,
417
440
  target,
418
441
  targetOrigin,
442
+ channelId,
419
443
  fetch: fetch2 = window.fetch
420
444
  }) {
421
445
  __publicField(this, "targetOrigin");
422
446
  __publicField(this, "target");
447
+ __publicField(this, "channelId");
423
448
  __publicField(this, "commandHandlers");
424
449
  __publicField(this, "_fetch");
425
450
  __publicField(this, "emitter", new EventEmitter());
@@ -450,7 +475,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
450
475
  ));
451
476
  __publicField(this, "handleMessage", async (event) => {
452
477
  var _a2, _b2, _c2, _d;
453
- if (!event.data || event.data.__xpaiChatKit !== true || event.origin !== this.targetOrigin || event.source !== this.target()) {
478
+ if (!isTrustedChatKitMessageEvent(event, {
479
+ channelId: this.channelId,
480
+ expectedOrigin: this.targetOrigin,
481
+ expectedSource: this.target()
482
+ })) {
454
483
  return;
455
484
  }
456
485
  const data = event.data;
@@ -591,6 +620,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
591
620
  this.commandHandlers = handlers;
592
621
  this.target = target;
593
622
  this.targetOrigin = targetOrigin;
623
+ this.channelId = (channelId == null ? void 0 : channelId.trim()) || void 0;
594
624
  this._fetch = (...args) => fetch2(...args);
595
625
  }
596
626
  setTargetOrigin(targetOrigin) {
@@ -600,6 +630,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
600
630
  var _a2;
601
631
  const message = {
602
632
  __xpaiChatKit: true,
633
+ ...this.channelId ? { channelId: this.channelId } : {},
603
634
  ...data
604
635
  };
605
636
  (_a2 = this.target()) == null ? void 0 : _a2.postMessage(message, this.targetOrigin, transfer);
@@ -1400,6 +1431,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1400
1431
  this.lastDragPosition = null;
1401
1432
  this.lastDragClientX = null;
1402
1433
  this.dragAnimation = null;
1434
+ this.activePointerId = null;
1403
1435
  this.isDragging = false;
1404
1436
  this.isHovering = false;
1405
1437
  this.movedDuringDrag = false;
@@ -1531,7 +1563,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1531
1563
  };
1532
1564
  this.handlePointerDown = (event) => {
1533
1565
  var _a2, _b2;
1534
- if (event.button !== 0 || event.ctrlKey) {
1566
+ if (event.button !== 0 || event.ctrlKey || this.isDragging) {
1535
1567
  return;
1536
1568
  }
1537
1569
  this.closeContextMenu();
@@ -1557,12 +1589,17 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1557
1589
  this.movedDuringDrag = false;
1558
1590
  this.dragPosition = nextPosition;
1559
1591
  this.isDragging = true;
1592
+ this.activePointerId = event.pointerId;
1560
1593
  this.clearRestingDelayTimer();
1561
1594
  this.isHovering = true;
1595
+ this.captureActivePointer();
1562
1596
  this.installDragListeners();
1563
1597
  this.rescheduleAnimation();
1564
1598
  };
1565
1599
  this.handlePointerMove = (event) => {
1600
+ if (!this.isActiveDragPointer(event)) {
1601
+ return;
1602
+ }
1566
1603
  const nextPosition = this.getNextDragPosition(event);
1567
1604
  const last = this.lastDragPosition;
1568
1605
  if (last && (Math.abs(last.x - nextPosition.x) > DRAG_DIRECTION_THRESHOLD_PX || Math.abs(last.y - nextPosition.y) > DRAG_DIRECTION_THRESHOLD_PX)) {
@@ -1582,20 +1619,18 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1582
1619
  this.render();
1583
1620
  };
1584
1621
  this.handlePointerUp = (event) => {
1622
+ if (!this.isActiveDragPointer(event)) {
1623
+ return;
1624
+ }
1585
1625
  const finalPosition = this.lastDragPosition ?? this.getNextDragPosition(event);
1586
- this.isDragging = false;
1587
- this.dragPosition = null;
1588
- this.dragAnimation = null;
1589
- this.lastDragClientX = null;
1590
- this.removeDragListeners();
1591
- this.persistPosition(finalPosition);
1592
- if (event.pointerType === "mouse" && this.isPointerOverPet(event)) {
1593
- this.isHovering = true;
1594
- this.rescheduleAnimation();
1595
- } else {
1596
- this.enterRestingAfterDelay();
1597
- this.rescheduleAnimation();
1626
+ this.finishDrag(finalPosition, event);
1627
+ };
1628
+ this.handleLostPointerCapture = (event) => {
1629
+ if (!this.isActiveDragPointer(event)) {
1630
+ return;
1598
1631
  }
1632
+ const finalPosition = this.lastDragPosition ?? this.getNextDragPosition(event);
1633
+ this.finishDrag(finalPosition, event);
1599
1634
  };
1600
1635
  this.handleClick = () => {
1601
1636
  var _a2;
@@ -1799,6 +1834,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1799
1834
  pet.addEventListener("pointerenter", this.handlePointerEnter);
1800
1835
  pet.addEventListener("pointerleave", this.handlePointerLeave);
1801
1836
  pet.addEventListener("pointerdown", this.handlePointerDown);
1837
+ pet.addEventListener("lostpointercapture", this.handleLostPointerCapture);
1802
1838
  pet.addEventListener("contextmenu", this.handleContextMenu);
1803
1839
  pet.addEventListener("click", this.handleClick);
1804
1840
  overlay.append(style, pet);
@@ -1808,6 +1844,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1808
1844
  }
1809
1845
  removeOverlay() {
1810
1846
  var _a2;
1847
+ this.cancelActiveDrag();
1811
1848
  this.clearRestingDelayTimer();
1812
1849
  this.clearTimers();
1813
1850
  this.closeContextMenu();
@@ -1824,6 +1861,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1824
1861
  "pointerdown",
1825
1862
  this.handlePointerDown
1826
1863
  );
1864
+ this.petElement.removeEventListener(
1865
+ "lostpointercapture",
1866
+ this.handleLostPointerCapture
1867
+ );
1827
1868
  this.petElement.removeEventListener(
1828
1869
  "contextmenu",
1829
1870
  this.handleContextMenu
@@ -2541,6 +2582,34 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2541
2582
  this.render();
2542
2583
  }
2543
2584
  }
2585
+ captureActivePointer() {
2586
+ const pointerId = this.activePointerId;
2587
+ const pet = this.petElement;
2588
+ if (pointerId === null || typeof (pet == null ? void 0 : pet.setPointerCapture) !== "function") {
2589
+ return;
2590
+ }
2591
+ try {
2592
+ pet.setPointerCapture(pointerId);
2593
+ } catch {
2594
+ }
2595
+ }
2596
+ releaseActivePointer() {
2597
+ const pointerId = this.activePointerId;
2598
+ const pet = this.petElement;
2599
+ this.activePointerId = null;
2600
+ if (pointerId === null || typeof (pet == null ? void 0 : pet.hasPointerCapture) !== "function" || typeof pet.releasePointerCapture !== "function") {
2601
+ return;
2602
+ }
2603
+ try {
2604
+ if (pet.hasPointerCapture(pointerId)) {
2605
+ pet.releasePointerCapture(pointerId);
2606
+ }
2607
+ } catch {
2608
+ }
2609
+ }
2610
+ isActiveDragPointer(event) {
2611
+ return this.isDragging && event.pointerId === this.activePointerId;
2612
+ }
2544
2613
  getNextDragPosition(event) {
2545
2614
  if (!this.options) {
2546
2615
  return { x: 0, y: 0 };
@@ -2555,12 +2624,35 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2555
2624
  normalizeBoundsPadding(this.options.position.boundsPadding)
2556
2625
  );
2557
2626
  }
2627
+ finishDrag(finalPosition, event) {
2628
+ this.isDragging = false;
2629
+ this.dragPosition = null;
2630
+ this.dragAnimation = null;
2631
+ this.lastDragClientX = null;
2632
+ this.removeDragListeners();
2633
+ this.releaseActivePointer();
2634
+ this.persistPosition(finalPosition);
2635
+ if (event.pointerType === "mouse" && this.isPointerOverPet(event)) {
2636
+ this.isHovering = true;
2637
+ this.rescheduleAnimation();
2638
+ } else {
2639
+ this.enterRestingAfterDelay();
2640
+ this.rescheduleAnimation();
2641
+ }
2642
+ }
2643
+ cancelActiveDrag() {
2644
+ this.isDragging = false;
2645
+ this.dragPosition = null;
2646
+ this.dragAnimation = null;
2647
+ this.lastDragPosition = null;
2648
+ this.lastDragClientX = null;
2649
+ this.removeDragListeners();
2650
+ this.releaseActivePointer();
2651
+ }
2558
2652
  installDragListeners() {
2559
2653
  window.addEventListener("pointermove", this.handlePointerMove);
2560
- window.addEventListener("pointerup", this.handlePointerUp, { once: true });
2561
- window.addEventListener("pointercancel", this.handlePointerUp, {
2562
- once: true
2563
- });
2654
+ window.addEventListener("pointerup", this.handlePointerUp);
2655
+ window.addEventListener("pointercancel", this.handlePointerUp);
2564
2656
  }
2565
2657
  removeDragListeners() {
2566
2658
  window.removeEventListener("pointermove", this.handlePointerMove);
@@ -2607,7 +2699,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2607
2699
  __privateAdd(this, _loaded, new Promise((resolve) => {
2608
2700
  __privateSet(this, _resolveLoaded, resolve);
2609
2701
  }));
2702
+ __privateAdd(this, _channelId, createSecureChannelId());
2610
2703
  __privateAdd(this, _messenger, new ChatFrameMessenger({
2704
+ channelId: __privateGet(this, _channelId) ?? void 0,
2611
2705
  fetch: (...args) => {
2612
2706
  var _a2;
2613
2707
  const customFetch = ((_a2 = __privateGet(this, _opts)) == null ? void 0 : _a2.api) && "fetch" in __privateGet(this, _opts).api && __privateGet(this, _opts).api.fetch;
@@ -3106,6 +3200,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3106
3200
  _petOverlay = new WeakMap();
3107
3201
  _resolveLoaded = new WeakMap();
3108
3202
  _loaded = new WeakMap();
3203
+ _channelId = new WeakMap();
3109
3204
  _messenger = new WeakMap();
3110
3205
  _ChatKitElementBase_instances = new WeakSet();
3111
3206
  emitAndThrow_fn = function(error) {
@@ -3316,7 +3411,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3316
3411
  frameURL.hash = encodeBase64({
3317
3412
  options: getInnerOptions(__privateMethod(this, _ChatKitElementBase_instances, getFrameOptions_fn).call(this, __privateGet(this, _opts))),
3318
3413
  referrer: window.location.origin,
3319
- profile: this.profile
3414
+ profile: this.profile,
3415
+ ...__privateGet(this, _channelId) ? { channelId: __privateGet(this, _channelId) } : {}
3320
3416
  });
3321
3417
  __privateGet(this, _messenger).connect();
3322
3418
  __privateGet(this, _frame).src = frameURL.toString();