@qualified-salesforce/web 0.0.1-oidc-bootstrap → 0.1.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 (97) hide show
  1. package/CAPABILITY-REFERENCE.md +44 -0
  2. package/CHANGELOG.md +75 -0
  3. package/constants.generated.js +30 -2
  4. package/css/widget/multimodal_v2/index.split-css.panda.css +265 -47
  5. package/package.json +17 -3
  6. package/packs/widget/api/docking/viewport_lock.js +93 -2
  7. package/packs/widget/esm/index.d.ts +134 -0
  8. package/packs/widget/esm/index.js +18 -2
  9. package/packs/widget/esm/qualified.css +265 -47
  10. package/src/graphql-types.js +74 -1
  11. package/src/url.js +4 -1
  12. package/vendor/actioncable/connection.js +40 -3
  13. package/vendor/actioncable/connection_monitor.js +8 -0
  14. package/vendor/actioncable/consumer.js +7 -1
  15. package/vendor/actioncable/index.js +5 -2
  16. package/vendor/actioncable/sse_socket.js +262 -0
  17. package/widget/analytics.js +8 -0
  18. package/widget/api_handler/base_api_handler.js +24 -0
  19. package/widget/booker_outcome_tracker.js +58 -20
  20. package/widget/capabilities.js +190 -0
  21. package/widget/channel.js +38 -6
  22. package/widget/constants.generated.js +2 -1
  23. package/widget/multimodal_v2/components/AppLayout.js +1 -1
  24. package/widget/multimodal_v2/components/app/Foreground.js +10 -9
  25. package/widget/multimodal_v2/components/app/Input.js +8 -3
  26. package/widget/multimodal_v2/components/app/LightboxExperience.js +17 -3
  27. package/widget/multimodal_v2/components/app/Main.js +87 -31
  28. package/widget/multimodal_v2/components/app/MessengerButton.js +18 -1
  29. package/widget/multimodal_v2/components/chat/ChatInputForm.js +8 -6
  30. package/widget/multimodal_v2/components/chat/timeline/CalendarEventPickRenderer.js +2 -2
  31. package/widget/multimodal_v2/components/chat/timeline/PresentDeckRenderer.js +346 -170
  32. package/widget/multimodal_v2/components/chat/timeline/SystemRenderer.js +4 -7
  33. package/widget/multimodal_v2/components/decks/index.js +506 -52
  34. package/widget/multimodal_v2/components/helpers/content_click_payloads.js +67 -1
  35. package/widget/multimodal_v2/components/lightbox_gather/index.js +4 -4
  36. package/widget/multimodal_v2/components/meetings/MeetingBookerEntry.js +8 -1
  37. package/widget/multimodal_v2/components/meetings/MeetingOfferEmailStep.js +1 -1
  38. package/widget/multimodal_v2/components/meetings/MeetingSummaryRail.js +1 -1
  39. package/widget/multimodal_v2/components/meetings/MeetingTimeSelector.js +1 -1
  40. package/widget/multimodal_v2/components/multimodal/Controls.js +11 -3
  41. package/widget/multimodal_v2/components/multimodal/useMultimodal.js +19 -7
  42. package/widget/multimodal_v2/components/presentations/index.js +61 -0
  43. package/widget/multimodal_v2/constants.js +1 -1
  44. package/widget/multimodal_v2/images/icons.js +17 -1
  45. package/widget/multimodal_v2/index.panda.js +2 -2
  46. package/widget/multimodal_v2/locales/cs.js +8 -1
  47. package/widget/multimodal_v2/locales/da.js +8 -1
  48. package/widget/multimodal_v2/locales/de.js +8 -1
  49. package/widget/multimodal_v2/locales/en.js +8 -1
  50. package/widget/multimodal_v2/locales/en_AU.js +8 -1
  51. package/widget/multimodal_v2/locales/en_GB.js +8 -1
  52. package/widget/multimodal_v2/locales/es.js +8 -1
  53. package/widget/multimodal_v2/locales/es_LA.js +8 -1
  54. package/widget/multimodal_v2/locales/fi.js +8 -1
  55. package/widget/multimodal_v2/locales/fr.js +8 -1
  56. package/widget/multimodal_v2/locales/fr_CA.js +8 -1
  57. package/widget/multimodal_v2/locales/id.js +8 -1
  58. package/widget/multimodal_v2/locales/it.js +8 -1
  59. package/widget/multimodal_v2/locales/ja.js +8 -1
  60. package/widget/multimodal_v2/locales/ko.js +8 -1
  61. package/widget/multimodal_v2/locales/nb.js +8 -1
  62. package/widget/multimodal_v2/locales/nl.js +8 -1
  63. package/widget/multimodal_v2/locales/pl.js +8 -1
  64. package/widget/multimodal_v2/locales/pt_BR.js +8 -1
  65. package/widget/multimodal_v2/locales/ru.js +8 -1
  66. package/widget/multimodal_v2/locales/sv.js +8 -1
  67. package/widget/multimodal_v2/locales/th.js +8 -1
  68. package/widget/multimodal_v2/locales/tr.js +8 -1
  69. package/widget/multimodal_v2/locales/vi.js +8 -1
  70. package/widget/multimodal_v2/locales/zh_CN.js +8 -1
  71. package/widget/multimodal_v2/locales/zh_TW.js +8 -1
  72. package/widget/multimodal_v2/multimodal.js +5 -1
  73. package/widget/multimodal_v2/multimodal_channel.js +13 -8
  74. package/widget/multimodal_v2/signals/messages_signal.js +4 -0
  75. package/widget/multimodal_v2/stores/ai_conversation_store.js +6 -2
  76. package/widget/multimodal_v2/stores/artifact_store.js +352 -27
  77. package/widget/multimodal_v2/stores/call_store.js +40 -1
  78. package/widget/multimodal_v2/stores/call_ui_adapter.js +1 -1
  79. package/widget/multimodal_v2/stores/decks_store.js +405 -39
  80. package/widget/multimodal_v2/stores/meeting_store.js +15 -10
  81. package/widget/multimodal_v2/stores/presentation_ga_adapter.js +64 -0
  82. package/widget/multimodal_v2/stores/presentation_telemetry_store.js +556 -0
  83. package/widget/multimodal_v2/stores/presentations_store.js +1 -0
  84. package/widget/multimodal_v2/stores/root_store.js +157 -268
  85. package/widget/multimodal_v2/stores/screen_share_store.js +41 -21
  86. package/widget/multimodal_v2/stores/translation_store.js +9 -0
  87. package/widget/multimodal_v2/stores/ui_store.js +7 -7
  88. package/widget/multimodal_v2/stores/website_navigation_store.js +3 -1
  89. package/widget/multimodal_v2/text_turn_response_tracker.js +419 -0
  90. package/widget/multimodal_v2/types.js +21 -1
  91. package/widget/multimodal_v2/utils/locale.js +2 -1
  92. package/widget/multimodal_v2/utils/signals.js +35 -4
  93. package/widget/pardot_visitor.js +7 -1
  94. package/widget/server-logger.js +97 -2
  95. package/widget/tracker.js +69 -21
  96. package/widget/widget/page_mirror_factory.js +9 -1
  97. package/widget/widget/widget.js +29 -4
@@ -154,18 +154,17 @@ class MeetingStore {
154
154
  * content first renders, whether that is the slot grid or the no-availability
155
155
  * empty state. Empty availability is a successful render (backend responded
156
156
  * with no open times), not a booker failure.
157
- */ /**
158
- * @param offerMessageId The offer this render is reporting. Callers should pass
159
- * the id they rendered with rather than relying on the default: the default
160
- * reads live state, and a second offer landing between the render and this
161
- * call would report the newer id, which the intent tracker rejects as
162
- * belonging to a different intent — silently dropping the timing.
157
+ *
158
+ * @param offerMessageId The offer this render is reporting. Pass the id you
159
+ * rendered with rather than relying on the default, which reads live state
160
+ * and would report a newer offer that landed in between. Both trackers
161
+ * reject a mark for an offer other than the one they armed.
163
162
  */ markShown(offerMessageId) {
164
163
  if (offerMessageId === void 0) offerMessageId = (()=>{
165
164
  var _this_activeOfferMessage_value;
166
165
  return (_this_activeOfferMessage_value = this.activeOfferMessage.value) == null ? void 0 : _this_activeOfferMessage_value.id;
167
166
  })();
168
- this.outcomeTracker.markShown();
167
+ this.outcomeTracker.markShown(offerMessageId);
169
168
  // Closes the pre-offer window's visitor-experienced total (intent -> shown).
170
169
  // No-ops unless this offer was preceded by an intent signal on this page.
171
170
  if (offerMessageId) this.rootStore.bookerIntentTracker.markShown(offerMessageId);
@@ -372,7 +371,9 @@ class MeetingStore {
372
371
  const slot = this.selectedTimeSlot.value;
373
372
  if (!slot) return [];
374
373
  const tz = this.timeZone.value;
375
- const locale = this.rootStore.translationStore.effectiveLocale.value;
374
+ // Already Intl-normalized; buildCalendarDays/formatDayShort re-normalize internally,
375
+ // which is a no-op here since toIntlLocale is idempotent on hyphenated input.
376
+ const locale = this.rootStore.translationStore.effectiveIntlLocale.value;
376
377
  return buildCalendarDays(slot, tz, this.sortedSlots.value, locale);
377
378
  });
378
379
  this.hasPrevWeek = signals_core_module_w(()=>$exists(this.prevSlotBeforeWeek).value);
@@ -382,7 +383,9 @@ class MeetingStore {
382
383
  this.displayedTimeSlotItems = signals_core_module_w(()=>{
383
384
  const slot = this.selectedTimeSlot.value;
384
385
  const tz = this.timeZone.value;
385
- const locale = this.rootStore.translationStore.effectiveLocale.value;
386
+ // Already Intl-normalized; formatTimeShort re-normalizes internally, which is a
387
+ // no-op here since toIntlLocale is idempotent on hyphenated input.
388
+ const locale = this.rootStore.translationStore.effectiveIntlLocale.value;
386
389
  return this.displayedTimeSlots.value.map((s)=>({
387
390
  slot: s,
388
391
  label: formatTimeShort(s.startsAt, tz, locale),
@@ -426,7 +429,9 @@ class MeetingStore {
426
429
  if (!slot) return null;
427
430
  const d = new Date(slot.startsAt);
428
431
  const key = d.getFullYear() + "-" + ("" + (d.getMonth() + 1)).padStart(2, "0") + "-" + ("" + d.getDate()).padStart(2, "0");
429
- const locale = this.rootStore.translationStore.effectiveLocale.value;
432
+ // Already Intl-normalized; formatMonthTitle re-normalizes internally, which is a
433
+ // no-op here since toIntlLocale is idempotent on hyphenated input.
434
+ const locale = this.rootStore.translationStore.effectiveIntlLocale.value;
430
435
  return formatMonthTitle(key, locale);
431
436
  });
432
437
  this.minDate = signals_core_module_w(()=>{
@@ -0,0 +1,64 @@
1
+ import { PRESENTATION_TYPE_LABELS, buildCustEvChatPresentationSlidePayload, buildCustEvChatPresentationStartPayload, buildCustEvChatPresentationEndPayload } from "../components/helpers/content_click_payloads.js";
2
+
3
+
4
+ class PresentationGaAdapter {
5
+ dispose() {
6
+ this.unsubscribe();
7
+ }
8
+ emitEvent(event) {
9
+ if (event.type === "start") {
10
+ const data = buildCustEvChatPresentationStartPayload({
11
+ conversationId: this.options.conversationId(),
12
+ formJoinIDUnique: this.options.formJoinIDUnique(),
13
+ title: event.title,
14
+ type: PRESENTATION_TYPE_LABELS[event.contentType],
15
+ totalSlides: event.totalSlides,
16
+ triggeredBy: event.triggeredBy
17
+ });
18
+ this.options.emit({
19
+ name: "custEv_chatPresentationStart",
20
+ data
21
+ });
22
+ } else if (event.type === "slide") {
23
+ const data = buildCustEvChatPresentationSlidePayload({
24
+ conversationId: this.options.conversationId(),
25
+ formJoinIDUnique: this.options.formJoinIDUnique(),
26
+ title: event.title,
27
+ type: PRESENTATION_TYPE_LABELS[event.contentType],
28
+ slideTitle: event.slideTitle,
29
+ slidePosition: event.slidePosition
30
+ });
31
+ this.options.emit({
32
+ name: "custEv_chatPresentationSlide",
33
+ data
34
+ });
35
+ } else {
36
+ const data = buildCustEvChatPresentationEndPayload({
37
+ conversationId: this.options.conversationId(),
38
+ formJoinIDUnique: this.options.formJoinIDUnique(),
39
+ title: event.title,
40
+ type: PRESENTATION_TYPE_LABELS[event.contentType],
41
+ slidesShown: event.slidesShown,
42
+ secondsWatched: Math.floor(event.activeMilliseconds / 1000)
43
+ });
44
+ this.options.emit({
45
+ name: "custEv_chatPresentationEnd",
46
+ data
47
+ });
48
+ }
49
+ }
50
+ constructor(options){
51
+ this.options = options;
52
+ this.handleEvent = (event)=>{
53
+ if (!this.options.isEnabled()) return;
54
+ try {
55
+ this.emitEvent(event);
56
+ } catch (unused) {
57
+ // GA delivery cannot alter presentation lifecycle or persistence.
58
+ }
59
+ };
60
+ this.unsubscribe = options.telemetry.subscribe(this.handleEvent);
61
+ }
62
+ }
63
+
64
+ export { PresentationGaAdapter };
@@ -0,0 +1,556 @@
1
+ import { __webpack_require__ } from "../../../js/runtime.js";
2
+ import "../../utils/native_globals.js";
3
+ import { esm_browser_v4 } from "../../../js/4101.js";
4
+
5
+ /* provided dependency */ var __nativeDocumentRemoveEventListener = __webpack_require__(68034).LA;
6
+ /* provided dependency */ var __nativeWindowRemoveEventListener = __webpack_require__(68034).kZ;
7
+ /* provided dependency */ var presentation_telemetry_store_setTimeout = __webpack_require__(68034).pS;
8
+ /* provided dependency */ var presentation_telemetry_store_clearTimeout = __webpack_require__(68034).Kj;
9
+ /* provided dependency */ var __nativeDocumentAddEventListener = __webpack_require__(68034).Qj;
10
+ /* provided dependency */ var __nativeWindowAddEventListener = __webpack_require__(68034).zh;
11
+ function _extends() {
12
+ _extends = Object.assign || function(target) {
13
+ for(var i = 1; i < arguments.length; i++){
14
+ var source = arguments[i];
15
+ for(var key in source){
16
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
17
+ target[key] = source[key];
18
+ }
19
+ }
20
+ }
21
+ return target;
22
+ };
23
+ return _extends.apply(this, arguments);
24
+ }
25
+
26
+ const CHECKPOINT_MS = 5000;
27
+ const PERSISTENCE_RETRY_MS = 5000;
28
+ const MAX_PERSISTED_SEQUENCE = 2000;
29
+ const MAX_TERMINAL_FLUSH_ACTIVITIES = 100;
30
+ class PresentationTelemetryStore {
31
+ onLiveArtifactVisible(message) {
32
+ const assetKey = assetKeyFor(message);
33
+ if (this.lifecycle && !this.lifecycle.ended && this.lifecycle.assetKey !== assetKey) {
34
+ this.end("replaced");
35
+ }
36
+ if ((!this.lifecycle || this.lifecycle.ended) && typeof document !== "undefined" && document.visibilityState !== "visible") {
37
+ this.pendingVisiblePresentation = {
38
+ message
39
+ };
40
+ return;
41
+ }
42
+ this.pendingVisiblePresentation = null;
43
+ if (!this.lifecycle || this.lifecycle.ended) {
44
+ this.lifecycle = this.createLifecycle(message);
45
+ this.emit({
46
+ type: "start",
47
+ lifecycleId: this.lifecycle.lifecycleId,
48
+ messageId: this.lifecycle.originatingMessageId,
49
+ contentType: this.lifecycle.contentType,
50
+ title: this.lifecycle.title,
51
+ totalSlides: this.lifecycle.totalSlides,
52
+ triggeredBy: this.lifecycle.triggeredBy
53
+ });
54
+ this.enqueueActivity(this.createActivity("started"));
55
+ if (message.type === "present_content") {
56
+ this.recordSlide(message.slideId, 0, this.lifecycle.title);
57
+ }
58
+ } else {
59
+ const isNewMessage = this.lifecycle.currentMessageId !== message.id;
60
+ if (!isNewMessage) return;
61
+ this.lifecycle.currentMessageId = message.id;
62
+ this.lifecycle.interrupted = false;
63
+ if (message.type === "present_video") {
64
+ this.demoPlaybackState = {
65
+ playing: false,
66
+ buffering: false,
67
+ seeking: false
68
+ };
69
+ }
70
+ }
71
+ if (message.type === "present_deck") {
72
+ var _ref, _message_slideIndex, _message_pageId, _ref1, _message_pageTitle;
73
+ var _message_slides_, _message_slides, _message_slides1;
74
+ const slideIndex = (_ref = (_message_slideIndex = message.slideIndex) != null ? _message_slideIndex : (_message_slides = message.slides) == null ? void 0 : (_message_slides_ = _message_slides[0]) == null ? void 0 : _message_slides_.slideIndex) != null ? _ref : 0;
75
+ const slide = (_message_slides1 = message.slides) == null ? void 0 : _message_slides1.find((candidate)=>candidate.slideIndex === slideIndex);
76
+ const slideId = (_message_pageId = message.pageId) != null ? _message_pageId : slide == null ? void 0 : slide.pageId;
77
+ const slideTitle = (_ref1 = (_message_pageTitle = message.pageTitle) != null ? _message_pageTitle : slide == null ? void 0 : slide.pageTitle) != null ? _ref1 : "Slide " + (slideIndex + 1);
78
+ this.recordSlide(slideId, slideIndex, slideTitle);
79
+ }
80
+ this.startActiveInterval();
81
+ }
82
+ recordPendingTrigger(context) {
83
+ this.pendingTrigger = context;
84
+ }
85
+ onDeckSlideRendered(slideId, slideIndex, slideTitle) {
86
+ var _this_pendingVisiblePresentation, _this_lifecycle;
87
+ if (((_this_pendingVisiblePresentation = this.pendingVisiblePresentation) == null ? void 0 : _this_pendingVisiblePresentation.message.type) === "present_deck" && (!this.lifecycle || this.lifecycle.ended)) {
88
+ this.pendingVisiblePresentation.latestDeckSlide = {
89
+ slideId,
90
+ slideIndex,
91
+ slideTitle: slideTitle != null ? slideTitle : "Slide " + (slideIndex + 1)
92
+ };
93
+ return;
94
+ }
95
+ if (((_this_lifecycle = this.lifecycle) == null ? void 0 : _this_lifecycle.contentType) !== "present_deck" || this.lifecycle.ended) return;
96
+ this.recordSlide(slideId, slideIndex, slideTitle != null ? slideTitle : "Slide " + (slideIndex + 1));
97
+ }
98
+ onDeckInterrupted() {
99
+ if (!this.lifecycle || this.lifecycle.contentType !== "present_deck") return;
100
+ this.lifecycle.interrupted = true;
101
+ this.pauseActiveInterval();
102
+ }
103
+ onDeckFinalDisplayIntervalComplete() {
104
+ var _this_pendingVisiblePresentation, _this_lifecycle;
105
+ if (((_this_pendingVisiblePresentation = this.pendingVisiblePresentation) == null ? void 0 : _this_pendingVisiblePresentation.message.type) === "present_deck") {
106
+ this.pendingVisiblePresentation = null;
107
+ return;
108
+ }
109
+ if (((_this_lifecycle = this.lifecycle) == null ? void 0 : _this_lifecycle.contentType) === "present_deck") this.end("completed");
110
+ }
111
+ onDemoPlaybackState(messageId, state) {
112
+ var _this_pendingVisiblePresentation, _this_lifecycle;
113
+ if (((_this_pendingVisiblePresentation = this.pendingVisiblePresentation) == null ? void 0 : _this_pendingVisiblePresentation.message.type) === "present_video" && this.pendingVisiblePresentation.message.id === messageId) {
114
+ this.pendingVisiblePresentation.demoPlaybackState = state;
115
+ return;
116
+ }
117
+ if (((_this_lifecycle = this.lifecycle) == null ? void 0 : _this_lifecycle.contentType) !== "present_video" || this.lifecycle.ended || this.lifecycle.currentMessageId !== messageId) {
118
+ return;
119
+ }
120
+ this.demoPlaybackState = state;
121
+ if (this.canAccumulate()) this.startActiveInterval();
122
+ else this.pauseActiveInterval();
123
+ }
124
+ onDemoInterrupted() {
125
+ if (!this.lifecycle || this.lifecycle.contentType !== "present_video") return;
126
+ this.lifecycle.interrupted = true;
127
+ this.pauseActiveInterval();
128
+ }
129
+ onDemoNaturalCompletion(messageId) {
130
+ var _this_pendingVisiblePresentation, _this_lifecycle;
131
+ if (((_this_pendingVisiblePresentation = this.pendingVisiblePresentation) == null ? void 0 : _this_pendingVisiblePresentation.message.type) === "present_video" && this.pendingVisiblePresentation.message.id === messageId) {
132
+ this.pendingVisiblePresentation = null;
133
+ return;
134
+ }
135
+ if (((_this_lifecycle = this.lifecycle) == null ? void 0 : _this_lifecycle.contentType) === "present_video" && this.lifecycle.currentMessageId === messageId) {
136
+ this.end("completed");
137
+ }
138
+ }
139
+ onVisitorDismiss(messageId) {
140
+ this.onArtifactHidden(messageId, "dismissed");
141
+ }
142
+ onAgentHide(messageId) {
143
+ this.onArtifactHidden(messageId, "agent_hidden");
144
+ }
145
+ onArtifactHidden(messageId, reason) {
146
+ if (reason === void 0) reason = "dismissed";
147
+ var _this_pendingVisiblePresentation, _this_lifecycle;
148
+ if (((_this_pendingVisiblePresentation = this.pendingVisiblePresentation) == null ? void 0 : _this_pendingVisiblePresentation.message.id) === messageId) {
149
+ this.pendingVisiblePresentation = null;
150
+ }
151
+ if (((_this_lifecycle = this.lifecycle) == null ? void 0 : _this_lifecycle.currentMessageId) === messageId) this.end(reason);
152
+ }
153
+ onCallEnded() {
154
+ this.pendingTrigger = null;
155
+ this.pendingVisiblePresentation = null;
156
+ this.end("call_ended");
157
+ }
158
+ onConversationEnded() {
159
+ this.pendingTrigger = null;
160
+ this.pendingVisiblePresentation = null;
161
+ this.end("conversation_ended");
162
+ }
163
+ onExperienceReplaced() {
164
+ this.pendingTrigger = null;
165
+ this.pendingVisiblePresentation = null;
166
+ this.end("replaced");
167
+ this.flushTerminalActivities();
168
+ }
169
+ subscribe(listener) {
170
+ this.listeners.add(listener);
171
+ return ()=>this.listeners.delete(listener);
172
+ }
173
+ dispose() {
174
+ this.disposed = true;
175
+ if (typeof document !== "undefined") {
176
+ __nativeDocumentRemoveEventListener("visibilitychange", this.handleVisibilityChange);
177
+ }
178
+ if (typeof window !== "undefined") {
179
+ __nativeWindowRemoveEventListener("pagehide", this.handlePageHide);
180
+ __nativeWindowRemoveEventListener("pageshow", this.handlePageShow);
181
+ }
182
+ this.clearCheckpointTimer();
183
+ this.clearPersistenceRetryTimer();
184
+ this.pendingVisiblePresentation = null;
185
+ this.listeners.clear();
186
+ }
187
+ resumeVisibleLifecycle() {
188
+ const pendingPresentation = this.pendingVisiblePresentation;
189
+ this.pendingVisiblePresentation = null;
190
+ if (pendingPresentation) {
191
+ const currentArtifact = this.rootStore.artifact.message.peek();
192
+ if ((currentArtifact == null ? void 0 : currentArtifact.id) === pendingPresentation.message.id) {
193
+ const message = pendingPresentation.message.type === "present_deck" && pendingPresentation.latestDeckSlide ? _extends({}, pendingPresentation.message, {
194
+ pageId: pendingPresentation.latestDeckSlide.slideId,
195
+ slideIndex: pendingPresentation.latestDeckSlide.slideIndex,
196
+ pageTitle: pendingPresentation.latestDeckSlide.slideTitle
197
+ }) : pendingPresentation.message;
198
+ this.onLiveArtifactVisible(message);
199
+ if (message.type === "present_video" && pendingPresentation.demoPlaybackState) {
200
+ this.onDemoPlaybackState(message.id, pendingPresentation.demoPlaybackState);
201
+ }
202
+ return;
203
+ }
204
+ }
205
+ const { lifecycle } = this;
206
+ const pendingSlide = lifecycle == null ? void 0 : lifecycle.pendingVisibleSlide;
207
+ if (pendingSlide) {
208
+ lifecycle.pendingVisibleSlide = undefined;
209
+ this.recordSlide(pendingSlide.slideId, pendingSlide.slideIndex, pendingSlide.slideTitle);
210
+ }
211
+ this.startActiveInterval();
212
+ }
213
+ createLifecycle(message) {
214
+ const contentType = message.type;
215
+ const triggeredBy = this.triggerMatches(message) ? "cta" : "conversational";
216
+ if (triggeredBy === "cta") this.pendingTrigger = null;
217
+ if (contentType === "present_video") {
218
+ this.demoPlaybackState = {
219
+ playing: false,
220
+ buffering: false,
221
+ seeking: false
222
+ };
223
+ }
224
+ return {
225
+ assetKey: assetKeyFor(message),
226
+ contentType,
227
+ lifecycleId: createLifecycleId(),
228
+ originatingMessageId: message.id,
229
+ currentMessageId: message.id,
230
+ title: titleFor(message),
231
+ totalSlides: totalSlidesFor(message),
232
+ triggeredBy,
233
+ uniqueSlideIds: new Set(),
234
+ activeMilliseconds: 0,
235
+ activeSince: null,
236
+ interrupted: false,
237
+ ended: false,
238
+ nextSequence: 1,
239
+ lastCheckpointActiveMilliseconds: 0
240
+ };
241
+ }
242
+ triggerMatches(message) {
243
+ var _this_pendingTrigger;
244
+ const trigger = (_this_pendingTrigger = this.pendingTrigger) == null ? void 0 : _this_pendingTrigger.trigger;
245
+ if (!trigger) return false;
246
+ return message.type === "present_deck" && trigger.type === "start_deck" && trigger.deckId === message.deckId || message.type === "present_video" && trigger.type === "start_presentation" && trigger.presentationId === message.presentationId;
247
+ }
248
+ recordSlide(slideId, slideIndex, slideTitle) {
249
+ const { lifecycle } = this;
250
+ if (!lifecycle || lifecycle.contentType === "present_video") return;
251
+ if (typeof document !== "undefined" && document.visibilityState !== "visible") {
252
+ lifecycle.pendingVisibleSlide = {
253
+ slideId,
254
+ slideIndex,
255
+ slideTitle
256
+ };
257
+ return;
258
+ }
259
+ lifecycle.pendingVisibleSlide = undefined;
260
+ lifecycle.uniqueSlideIds.add(slideId);
261
+ this.emit({
262
+ type: "slide",
263
+ lifecycleId: lifecycle.lifecycleId,
264
+ messageId: lifecycle.originatingMessageId,
265
+ contentType: lifecycle.contentType,
266
+ title: lifecycle.title,
267
+ slideTitle,
268
+ slidePosition: slideIndex + 1
269
+ });
270
+ this.enqueueActivity(this.createActivity("slide_shown", {
271
+ slideId,
272
+ slideIndex
273
+ }));
274
+ }
275
+ end(reason) {
276
+ const { lifecycle } = this;
277
+ if (!lifecycle || lifecycle.ended) return;
278
+ if (lifecycle.activeSince !== null) {
279
+ lifecycle.activeMilliseconds = this.currentActiveMilliseconds();
280
+ lifecycle.activeSince = null;
281
+ }
282
+ this.clearCheckpointTimer();
283
+ lifecycle.pendingVisibleSlide = undefined;
284
+ lifecycle.ended = true;
285
+ lifecycle.endReason = reason;
286
+ this.emit({
287
+ type: "end",
288
+ lifecycleId: lifecycle.lifecycleId,
289
+ messageId: lifecycle.originatingMessageId,
290
+ contentType: lifecycle.contentType,
291
+ title: lifecycle.title,
292
+ slidesShown: lifecycle.uniqueSlideIds.size,
293
+ activeMilliseconds: Math.floor(lifecycle.activeMilliseconds),
294
+ endReason: reason
295
+ });
296
+ const ended = this.createActivity("ended", {
297
+ endReason: reason
298
+ });
299
+ this.enqueueActivity(ended);
300
+ }
301
+ startActiveInterval() {
302
+ if (!this.lifecycle || this.lifecycle.ended || this.lifecycle.activeSince != null) return;
303
+ if (!this.canAccumulate()) return;
304
+ this.lifecycle.activeSince = performance.now();
305
+ this.scheduleCheckpoint();
306
+ }
307
+ pauseActiveInterval() {
308
+ const { lifecycle } = this;
309
+ if (!lifecycle || lifecycle.activeSince === null) return;
310
+ lifecycle.activeMilliseconds = this.currentActiveMilliseconds();
311
+ lifecycle.activeSince = null;
312
+ this.clearCheckpointTimer();
313
+ this.checkpointIfChanged();
314
+ }
315
+ currentActiveMilliseconds() {
316
+ const { lifecycle } = this;
317
+ if (!lifecycle) return 0;
318
+ if (lifecycle.activeSince === null) return lifecycle.activeMilliseconds;
319
+ return lifecycle.activeMilliseconds + performance.now() - lifecycle.activeSince;
320
+ }
321
+ checkpointIfChanged() {
322
+ const { lifecycle } = this;
323
+ if (!lifecycle || lifecycle.ended) return;
324
+ const activeMilliseconds = Math.floor(this.currentActiveMilliseconds());
325
+ if (activeMilliseconds <= lifecycle.lastCheckpointActiveMilliseconds) return;
326
+ const checkpoint = this.createActivity("exposure_checkpoint");
327
+ if (!checkpoint) return;
328
+ lifecycle.lastCheckpointActiveMilliseconds = checkpoint.activeMilliseconds;
329
+ this.enqueueActivity(checkpoint);
330
+ }
331
+ scheduleCheckpoint() {
332
+ this.clearCheckpointTimer();
333
+ const { lifecycle } = this;
334
+ if (!lifecycle) return;
335
+ const elapsedIntoInterval = lifecycle.activeMilliseconds % CHECKPOINT_MS;
336
+ const delay = Math.ceil(elapsedIntoInterval === 0 ? CHECKPOINT_MS : CHECKPOINT_MS - elapsedIntoInterval);
337
+ this.checkpointTimer = presentation_telemetry_store_setTimeout(()=>{
338
+ const current = this.lifecycle;
339
+ if (!current || current.activeSince === null) return;
340
+ current.activeMilliseconds = this.currentActiveMilliseconds();
341
+ current.activeSince = performance.now();
342
+ this.checkpointIfChanged();
343
+ if (this.canAccumulate()) this.scheduleCheckpoint();
344
+ }, delay);
345
+ }
346
+ clearCheckpointTimer() {
347
+ if (this.checkpointTimer !== null) presentation_telemetry_store_clearTimeout(this.checkpointTimer);
348
+ this.checkpointTimer = null;
349
+ }
350
+ clearPersistenceRetryTimer() {
351
+ if (this.persistenceRetryTimer !== null) presentation_telemetry_store_clearTimeout(this.persistenceRetryTimer);
352
+ this.persistenceRetryTimer = null;
353
+ }
354
+ canAccumulate() {
355
+ const { lifecycle } = this;
356
+ if (!lifecycle || lifecycle.ended || lifecycle.interrupted || typeof document !== "undefined" && document.visibilityState !== "visible") {
357
+ return false;
358
+ }
359
+ return lifecycle.contentType !== "present_video" || this.demoPlaybackState.playing && !this.demoPlaybackState.buffering && !this.demoPlaybackState.seeking;
360
+ }
361
+ createActivity(activityType, options) {
362
+ if (options === void 0) options = {};
363
+ const { lifecycle } = this;
364
+ if (!lifecycle) throw new Error("Cannot create presentation activity without a lifecycle");
365
+ const { slideId, slideIndex, endReason } = options;
366
+ if (activityType !== "ended" && lifecycle.nextSequence >= MAX_PERSISTED_SEQUENCE) {
367
+ return null;
368
+ }
369
+ return _extends({
370
+ presentationMessageId: lifecycle.originatingMessageId,
371
+ lifecycleId: lifecycle.lifecycleId,
372
+ sequence: activityType === "ended" ? Math.min(lifecycle.nextSequence++, MAX_PERSISTED_SEQUENCE) : lifecycle.nextSequence++,
373
+ activityType,
374
+ contentType: lifecycle.contentType,
375
+ occurredAt: new Date().toISOString(),
376
+ activeMilliseconds: Math.floor(this.currentActiveMilliseconds())
377
+ }, slideId !== undefined && {
378
+ slideId
379
+ }, slideIndex !== undefined && {
380
+ slideIndex
381
+ }, endReason !== undefined && {
382
+ endReason
383
+ });
384
+ }
385
+ enqueueActivity(activity) {
386
+ if (this.disposed || !activity) return;
387
+ if (activity.activityType === "exposure_checkpoint") {
388
+ const firstReplaceableIndex = this.persistenceInFlight || this.persistenceRetryTimer !== null ? 1 : 0;
389
+ for(let index = this.persistenceQueue.length - 1; index >= firstReplaceableIndex; index--){
390
+ const queued = this.persistenceQueue[index];
391
+ if (queued.lifecycleId === activity.lifecycleId && queued.activityType === "exposure_checkpoint") {
392
+ this.persistenceQueue.splice(index, 1);
393
+ break;
394
+ }
395
+ }
396
+ }
397
+ this.persistenceQueue.push(activity);
398
+ this.persistNextActivity();
399
+ }
400
+ persistNextActivity() {
401
+ if (this.disposed || this.persistenceInFlight || this.persistenceRetryTimer !== null || this.persistenceQueue.length === 0) {
402
+ return;
403
+ }
404
+ const activity = this.persistenceQueue[0];
405
+ this.persistenceInFlight = activity;
406
+ try {
407
+ Promise.resolve(this.persistActivity(activity)).then((result)=>this.settlePersistence(activity, !result.error), ()=>this.settlePersistence(activity, false));
408
+ } catch (unused) {
409
+ this.settlePersistence(activity, false);
410
+ }
411
+ }
412
+ settlePersistence(activity, acknowledged) {
413
+ if (this.persistenceInFlight !== activity) return;
414
+ this.persistenceInFlight = null;
415
+ if (this.disposed) return;
416
+ if (acknowledged && this.persistenceQueue[0] === activity) {
417
+ this.persistenceQueue.shift();
418
+ this.persistNextActivity();
419
+ return;
420
+ }
421
+ this.persistenceRetryTimer = presentation_telemetry_store_setTimeout(()=>{
422
+ this.persistenceRetryTimer = null;
423
+ this.persistNextActivity();
424
+ }, PERSISTENCE_RETRY_MS);
425
+ }
426
+ persistActivity(activity) {
427
+ return this.rootStore.channel.perform("record_presentation_activity", this.activityPayload(activity), {
428
+ reportTimeout: false
429
+ });
430
+ }
431
+ activityPayload(activity) {
432
+ return _extends({
433
+ presentation_message_id: activity.presentationMessageId,
434
+ lifecycle_id: activity.lifecycleId,
435
+ sequence: activity.sequence,
436
+ activity_type: activity.activityType,
437
+ content_type: activity.contentType,
438
+ occurred_at: activity.occurredAt,
439
+ active_milliseconds: activity.activeMilliseconds
440
+ }, activity.slideId !== undefined && {
441
+ slide_id: activity.slideId
442
+ }, activity.slideIndex !== undefined && {
443
+ slide_index: activity.slideIndex
444
+ }, activity.endReason !== undefined && {
445
+ end_reason: activity.endReason
446
+ });
447
+ }
448
+ flushTerminalActivities() {
449
+ if (this.disposed || this.terminalFlushSent || this.persistenceQueue.length === 0 || typeof fetch === "undefined") {
450
+ return;
451
+ }
452
+ const pending = this.persistenceQueue.length <= MAX_TERMINAL_FLUSH_ACTIVITIES ? this.persistenceQueue : [
453
+ this.persistenceQueue[0],
454
+ ...this.persistenceQueue.slice(-(MAX_TERMINAL_FLUSH_ACTIVITIES - 1))
455
+ ];
456
+ this.terminalFlushSent = true;
457
+ try {
458
+ void fetch(this.rootStore.visitor.resourceUrl("presentation_activities", {}), {
459
+ method: "POST",
460
+ body: JSON.stringify({
461
+ activities: pending.map((activity)=>this.activityPayload(activity))
462
+ }),
463
+ headers: {
464
+ "Content-Type": "text/plain;charset=UTF-8"
465
+ },
466
+ keepalive: true,
467
+ credentials: "omit"
468
+ }).catch(()=>undefined);
469
+ } catch (unused) {
470
+ // Page teardown cannot wait for or recover from a synchronous transport failure.
471
+ }
472
+ }
473
+ emit(event) {
474
+ this.listeners.forEach((listener)=>{
475
+ try {
476
+ listener(event);
477
+ } catch (unused) {
478
+ // Lifecycle consumers must not change presentation behavior.
479
+ }
480
+ });
481
+ }
482
+ constructor(rootStore){
483
+ this.rootStore = rootStore;
484
+ this.lifecycle = null;
485
+ this.pendingTrigger = null;
486
+ this.pendingVisiblePresentation = null;
487
+ this.demoPlaybackState = {
488
+ playing: false,
489
+ buffering: false,
490
+ seeking: false
491
+ };
492
+ this.checkpointTimer = null;
493
+ this.listeners = new Set();
494
+ this.persistenceQueue = [];
495
+ this.persistenceInFlight = null;
496
+ this.persistenceRetryTimer = null;
497
+ this.terminalFlushSent = false;
498
+ this.disposed = false;
499
+ this.handleVisibilityChange = ()=>{
500
+ if (document.visibilityState === "visible") this.resumeVisibleLifecycle();
501
+ else this.pauseActiveInterval();
502
+ };
503
+ this.handlePageHide = (event)=>{
504
+ if (event.persisted) {
505
+ this.pauseActiveInterval();
506
+ return;
507
+ }
508
+ this.pendingVisiblePresentation = null;
509
+ this.end("page_exit");
510
+ this.flushTerminalActivities();
511
+ };
512
+ this.handlePageShow = ()=>{
513
+ this.resumeVisibleLifecycle();
514
+ };
515
+ if (typeof document !== "undefined") {
516
+ __nativeDocumentAddEventListener("visibilitychange", this.handleVisibilityChange);
517
+ }
518
+ if (typeof window !== "undefined") {
519
+ __nativeWindowAddEventListener("pagehide", this.handlePageHide);
520
+ __nativeWindowAddEventListener("pageshow", this.handlePageShow);
521
+ }
522
+ }
523
+ }
524
+ function assetKeyFor(message) {
525
+ switch(message.type){
526
+ case "present_deck":
527
+ return message.type + ":" + message.deckId;
528
+ case "present_video":
529
+ return message.type + ":" + message.presentationId;
530
+ case "present_content":
531
+ return message.type + ":" + message.slideId;
532
+ }
533
+ }
534
+ function titleFor(message) {
535
+ var _ref, _message_deckTitle, _message_presentationTitle, _message_slideTitle;
536
+ if (message.type === "present_deck") return (_ref = (_message_deckTitle = message.deckTitle) != null ? _message_deckTitle : message.pageTitle) != null ? _ref : "";
537
+ if (message.type === "present_video") return (_message_presentationTitle = message.presentationTitle) != null ? _message_presentationTitle : message.sectionTitle;
538
+ return (_message_slideTitle = message.slideTitle) != null ? _message_slideTitle : "";
539
+ }
540
+ function totalSlidesFor(message) {
541
+ var _message_slides, _message_slideImageUrls;
542
+ if (message.type === "present_content") return 1;
543
+ if (message.type === "present_video") return 0;
544
+ return message.totalSlides || ((_message_slides = message.slides) == null ? void 0 : _message_slides.length) || ((_message_slideImageUrls = message.slideImageUrls) == null ? void 0 : _message_slideImageUrls.length) || 1;
545
+ }
546
+ function createLifecycleId() {
547
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
548
+ return crypto.randomUUID();
549
+ }
550
+ return esm_browser_v4();
551
+ }
552
+ /* export default */ const presentation_telemetry_store = ((/* unused pure expression or super */ null && (PresentationTelemetryStore)));
553
+
554
+ var presentation_telemetry_store_default = /* unused export */ undefined;
555
+ export { PresentationTelemetryStore };
556
+ export default presentation_telemetry_store_default;