@helpway/react 0.13.0 → 0.13.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.
package/dist/index.d.ts CHANGED
@@ -29,6 +29,11 @@ interface HelpwayWidgetProps {
29
29
  * Usually sourced from `?hw_conv=` URL param for email CTAs.
30
30
  */
31
31
  initialConversationId?: string;
32
+ /**
33
+ * HMAC-signed token for cross-device visitor identity restoration.
34
+ * Sourced from `#hw_token=` URL fragment in email deep-links.
35
+ */
36
+ deepLinkToken?: string;
32
37
  /**
33
38
  * Called once after the widget has bootstrapped and exposes
34
39
  * the full programmatic API object (also available as `window.Helpway`).
@@ -76,7 +81,7 @@ type HelpwayPublicAPI = HelpwayMethods;
76
81
  * `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the
77
82
  * widget and its WebSocket connection — useful for route-scoped mounts.
78
83
  */
79
- declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, theme, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
84
+ declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, deepLinkToken, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, theme, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
80
85
 
81
86
  interface IdentifyData {
82
87
  externalId: string;
package/dist/index.js CHANGED
@@ -335,7 +335,10 @@ function createWidgetStore() {
335
335
  next.set(
336
336
  conversationId,
337
337
  existing.map(
338
- (m) => m.id === oldId ? { ...item, _stableKey: m._stableKey ?? oldId } : m
338
+ (m) => m.id === oldId ? {
339
+ ...item,
340
+ _stableKey: m._stableKey ?? oldId
341
+ } : m
339
342
  )
340
343
  );
341
344
  return { messages: next };
@@ -369,9 +372,21 @@ function createWidgetStore() {
369
372
  merged.push(m);
370
373
  if (isAgentMsg(m) && merged.length === 1) keptAgentWelcome = true;
371
374
  }
375
+ const serverVisitorTs = existingItems.find((x) => x.visitorId)?.createdAt;
376
+ let graftedWelcome = false;
372
377
  for (const m of existingItems) {
373
378
  if (seen.has(m.id)) continue;
374
- if (isAgentMsg(m) && keptAgentWelcome) continue;
379
+ const isWelcomeEcho = isAgentMsg(m) && keptAgentWelcome && !graftedWelcome && (!serverVisitorTs || m.createdAt <= serverVisitorTs);
380
+ if (isWelcomeEcho) {
381
+ const seed = merged[0];
382
+ merged[0] = {
383
+ ...m,
384
+ _stableKey: seed ? seed._stableKey ?? seed.id : m.id
385
+ };
386
+ seen.add(m.id);
387
+ graftedWelcome = true;
388
+ continue;
389
+ }
375
390
  seen.add(m.id);
376
391
  merged.push(m);
377
392
  }
@@ -484,9 +499,14 @@ function createWidgetStore() {
484
499
  const isAgentAuthored = !!event.item.aiAgentId && !event.item.visitorId && !event.item.userId;
485
500
  const existing = state.messages.get(event.conversationId);
486
501
  const seedId = existing?.[0]?.id;
487
- const isSeedWelcomeEcho = isAgentAuthored && !!existing && existing.length === 1 && typeof seedId === "string" && seedId.startsWith("seed-welcome-") && seedId !== event.item.id;
488
- if (isSeedWelcomeEcho) {
489
- break;
502
+ const hasSeedWelcome = typeof seedId === "string" && seedId.startsWith("seed-welcome-");
503
+ if (isAgentAuthored && hasSeedWelcome) {
504
+ const firstVisitorTs = existing?.find((m) => m.visitorId)?.createdAt;
505
+ const isWelcomeEcho = !firstVisitorTs || event.item.createdAt <= firstVisitorTs;
506
+ if (isWelcomeEcho) {
507
+ state.replaceMessage(event.conversationId, seedId, event.item);
508
+ break;
509
+ }
490
510
  }
491
511
  state.addMessage(event.conversationId, event.item);
492
512
  }
@@ -4954,6 +4974,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
4954
4974
  onSelectEntry: (slug) => {
4955
4975
  setContentDetailSlug(slug);
4956
4976
  setSubView("content-detail");
4977
+ markEntrySeen(slug);
4957
4978
  },
4958
4979
  onSelectCategory: (cat) => {
4959
4980
  setContentCategoryName(cat.title);
@@ -5528,6 +5549,7 @@ function HelpwayWidget({
5528
5549
  apiUrl,
5529
5550
  locale,
5530
5551
  initialConversationId,
5552
+ deepLinkToken,
5531
5553
  onReady,
5532
5554
  hideLauncher,
5533
5555
  customLauncherSelector,
@@ -5546,6 +5568,7 @@ function HelpwayWidget({
5546
5568
  apiUrl: resolvedApiUrl,
5547
5569
  locale,
5548
5570
  initialConversationId,
5571
+ deepLinkToken,
5549
5572
  onReady,
5550
5573
  customLauncherSelector,
5551
5574
  onOpen,