@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
@@ -391,6 +391,19 @@ const CampaignJoinFailedReasonTypeEnum = (/* unused pure expression or super */
391
391
  /** Salesforce record not found */ SalesforceRecordNotFound: 'salesforce_record_not_found',
392
392
  /** Salesforce sender not found */ SalesforceSenderNotFound: 'salesforce_sender_not_found'
393
393
  }));
394
+ const CampaignNotEnrolledReasonTypeEnum = (/* unused pure expression or super */ null && ({
395
+ ActiveCampaignEnrollment: 'ACTIVE_CAMPAIGN_ENROLLMENT',
396
+ AudienceFilterFailed: 'AUDIENCE_FILTER_FAILED',
397
+ EmailHardBounced: 'EMAIL_HARD_BOUNCED',
398
+ EnrollmentLimitReached: 'ENROLLMENT_LIMIT_REACHED',
399
+ InactiveCampaign: 'INACTIVE_CAMPAIGN',
400
+ InvalidEmail: 'INVALID_EMAIL',
401
+ MeetingAlreadyBooked: 'MEETING_ALREADY_BOOKED',
402
+ SalesforceRecordNotFound: 'SALESFORCE_RECORD_NOT_FOUND',
403
+ SalesforceSenderNotFound: 'SALESFORCE_SENDER_NOT_FOUND',
404
+ UnableToEnroll: 'UNABLE_TO_ENROLL',
405
+ Unsubscribed: 'UNSUBSCRIBED'
406
+ }));
394
407
  const CampaignPausedReasonTypeEnum = (/* unused pure expression or super */ null && ({
395
408
  /** Campaign paused */ CampaignPaused: 'campaign_paused',
396
409
  /** Inactive sender */ InactiveSender: 'inactive_sender',
@@ -484,6 +497,42 @@ const ContentJobStatusEnum = (/* unused pure expression or super */ null && ({
484
497
  /** Processing */ Processing: 'PROCESSING',
485
498
  /** Skipped */ Skipped: 'SKIPPED'
486
499
  }));
500
+ /** An action that can be applied to matching content library items */ const ContentLibraryActionEnum = (/* unused pure expression or super */ null && ({
501
+ /** Enable cobrowse */ Cobrowse: 'COBROWSE',
502
+ /** Delete */ Delete: 'DELETE',
503
+ /** Disable */ Disable: 'DISABLE',
504
+ /** Enable */ Enable: 'ENABLE',
505
+ /** Gate */ Gate: 'GATE',
506
+ /** Promote */ Promote: 'PROMOTE',
507
+ /** Disable cobrowse */ Uncobrowse: 'UNCOBROWSE',
508
+ /** Ungate */ Ungate: 'UNGATE',
509
+ /** Unpromote */ Unpromote: 'UNPROMOTE'
510
+ }));
511
+ const ContentLibraryItemKindEnum = (/* unused pure expression or super */ null && ({
512
+ Demo: 'DEMO',
513
+ Pdf: 'PDF',
514
+ Presentation: 'PRESENTATION',
515
+ Slide: 'SLIDE',
516
+ Snippet: 'SNIPPET',
517
+ WebsitePage: 'WEBSITE_PAGE'
518
+ }));
519
+ const ContentLibraryItemOrderEnum = (/* unused pure expression or super */ null && ({
520
+ AddedByAsc: 'ADDED_BY_ASC',
521
+ AddedByDesc: 'ADDED_BY_DESC',
522
+ DateAddedAsc: 'DATE_ADDED_ASC',
523
+ DateAddedDesc: 'DATE_ADDED_DESC',
524
+ DateModifiedAsc: 'DATE_MODIFIED_ASC',
525
+ DateModifiedDesc: 'DATE_MODIFIED_DESC',
526
+ NameAsc: 'NAME_ASC',
527
+ NameDesc: 'NAME_DESC'
528
+ }));
529
+ const ContentLibraryItemStatusFilterEnum = (/* unused pure expression or super */ null && ({
530
+ Cobrowse: 'COBROWSE',
531
+ Disabled: 'DISABLED',
532
+ Enabled: 'ENABLED',
533
+ New: 'NEW',
534
+ Offers: 'OFFERS'
535
+ }));
487
536
  const ContentSourceFileTypeEnum = (/* unused pure expression or super */ null && ({
488
537
  Pdf: 'PDF'
489
538
  }));
@@ -529,6 +578,11 @@ const CtaTypeEnum = {
529
578
  Form: 'FORM',
530
579
  Link: 'LINK'
531
580
  };
581
+ const CustomVoiceStatusEnum = (/* unused pure expression or super */ null && ({
582
+ /** Creating */ Creating: 'CREATING',
583
+ /** Failed */ Failed: 'FAILED',
584
+ /** Ready */ Ready: 'READY'
585
+ }));
532
586
  const DashboardTileDefinitionNameEnum = (/* unused pure expression or super */ null && ({
533
587
  /** Sessions where visitor accepted voice permissions */ AiSdrAcceptedMediaPermissions: 'AI_SDR_ACCEPTED_MEDIA_PERMISSIONS',
534
588
  /** AI SDR asked for email */ AiSdrAskedEmail: 'AI_SDR_ASKED_EMAIL',
@@ -537,14 +591,18 @@ const DashboardTileDefinitionNameEnum = (/* unused pure expression or super */ n
537
591
  /** Total AI SDR call duration (seconds) */ AiSdrCallDuration: 'AI_SDR_CALL_DURATION',
538
592
  /** AI SDR captured email */ AiSdrCapturedEmail: 'AI_SDR_CAPTURED_EMAIL',
539
593
  /** AI SDR captured email during voice call */ AiSdrCapturedEmailDuringVoiceCall: 'AI_SDR_CAPTURED_EMAIL_DURING_VOICE_CALL',
594
+ /** Total deck slides shown */ AiSdrDeckSlidesShown: 'AI_SDR_DECK_SLIDES_SHOWN',
540
595
  /** Sessions with AI SDR voice call */ AiSdrHasVoiceCall: 'AI_SDR_HAS_VOICE_CALL',
541
596
  /** Meetings booked during voice call */ AiSdrMeetingBookedDuringVoiceCall: 'AI_SDR_MEETING_BOOKED_DURING_VOICE_CALL',
542
597
  /** Meetings offered during voice call */ AiSdrMeetingOfferedDuringVoiceCall: 'AI_SDR_MEETING_OFFERED_DURING_VOICE_CALL',
543
598
  /** Sessions where AI SDR navigated site */ AiSdrNavigatedSite: 'AI_SDR_NAVIGATED_SITE',
599
+ /** Total assets presented */ AiSdrPresentationCount: 'AI_SDR_PRESENTATION_COUNT',
544
600
  /** Sessions where AI SDR presented a product demo */ AiSdrPresentedProductDemo: 'AI_SDR_PRESENTED_PRODUCT_DEMO',
545
601
  /** Sessions where AI SDR presented a slide deck */ AiSdrPresentedSlideDeck: 'AI_SDR_PRESENTED_SLIDE_DECK',
602
+ /** Total product demo seconds watched */ AiSdrProductDemoSecondsWatched: 'AI_SDR_PRODUCT_DEMO_SECONDS_WATCHED',
546
603
  /** Sessions where AI SDR shared presentation content */ AiSdrSharedPresentationContent: 'AI_SDR_SHARED_PRESENTATION_CONTENT',
547
604
  /** Sessions where AI SDR shared slides */ AiSdrSharedSlides: 'AI_SDR_SHARED_SLIDES',
605
+ /** Total slide deck seconds watched */ AiSdrSlideDeckSecondsWatched: 'AI_SDR_SLIDE_DECK_SECONDS_WATCHED',
548
606
  /** Total visitor messages */ AiSdrVisitorMessagesCount: 'AI_SDR_VISITOR_MESSAGES_COUNT',
549
607
  /** Sessions where visitor spoke during voice call */ AiSdrVisitorSpokeDuringVoiceCall: 'AI_SDR_VISITOR_SPOKE_DURING_VOICE_CALL',
550
608
  /** Sessions where AI goals were activated */ AutopilotActivatedStrategiesTotal: 'AUTOPILOT_ACTIVATED_STRATEGIES_TOTAL',
@@ -950,6 +1008,13 @@ const IncludeExcludeTypeEnum = (/* unused pure expression or super */ null && ({
950
1008
  Contains: 'CONTAINS',
951
1009
  Equals: 'EQUALS'
952
1010
  }));
1011
+ const IntegrationDirectoryIntegrationEnum = (/* unused pure expression or super */ null && ({
1012
+ Slack: 'SLACK'
1013
+ }));
1014
+ const IntegrationDirectoryResourceEnum = (/* unused pure expression or super */ null && ({
1015
+ Channels: 'CHANNELS',
1016
+ Users: 'USERS'
1017
+ }));
953
1018
  const LauncherBackgroundShapeEnum = (/* unused pure expression or super */ null && ({
954
1019
  Circle: 'CIRCLE',
955
1020
  Square: 'SQUARE'
@@ -1572,6 +1637,7 @@ var graphql_types_CampaignExitTriggerTypeEnum = /* unused export */ undefined;
1572
1637
  var graphql_types_CampaignGoalTypeEnum = /* unused export */ undefined;
1573
1638
  var graphql_types_CampaignHandoffRoutingRuleTypeEnum = /* unused export */ undefined;
1574
1639
  var graphql_types_CampaignJoinFailedReasonTypeEnum = /* unused export */ undefined;
1640
+ var graphql_types_CampaignNotEnrolledReasonTypeEnum = /* unused export */ undefined;
1575
1641
  var graphql_types_CampaignPausedReasonTypeEnum = /* unused export */ undefined;
1576
1642
  var graphql_types_CampaignReplyHandlingEnum = /* unused export */ undefined;
1577
1643
  var graphql_types_CampaignRoutingRuleTypeEnum = /* unused export */ undefined;
@@ -1582,12 +1648,17 @@ var graphql_types_CampaignTemplateEnum = /* unused export */ undefined;
1582
1648
  var graphql_types_CampaignTransitionEnum = /* unused export */ undefined;
1583
1649
  var graphql_types_CampaignTriggerTypeEnum = /* unused export */ undefined;
1584
1650
  var graphql_types_ContentJobStatusEnum = /* unused export */ undefined;
1651
+ var graphql_types_ContentLibraryActionEnum = /* unused export */ undefined;
1652
+ var graphql_types_ContentLibraryItemKindEnum = /* unused export */ undefined;
1653
+ var graphql_types_ContentLibraryItemOrderEnum = /* unused export */ undefined;
1654
+ var graphql_types_ContentLibraryItemStatusFilterEnum = /* unused export */ undefined;
1585
1655
  var graphql_types_ContentSourceFileTypeEnum = /* unused export */ undefined;
1586
1656
  var graphql_types_ContentSourceTypeEnum = /* unused export */ undefined;
1587
1657
  var graphql_types_ConversationIgnoredTypeEnum = /* unused export */ undefined;
1588
1658
  var graphql_types_ConversationTypeEnum = /* unused export */ undefined;
1589
1659
  var graphql_types_ConversionFilterEnum = /* unused export */ undefined;
1590
1660
  var graphql_types_CookieConsentDisplayModeEnum = /* unused export */ undefined;
1661
+ var graphql_types_CustomVoiceStatusEnum = /* unused export */ undefined;
1591
1662
  var graphql_types_DashboardTileDefinitionNameEnum = /* unused export */ undefined;
1592
1663
  var graphql_types_DashboardTileFunnelTypeEnum = /* unused export */ undefined;
1593
1664
  var graphql_types_DashboardTileGraphTypeEnum = /* unused export */ undefined;
@@ -1623,6 +1694,8 @@ var graphql_types_HeaderBackgroundTypeEnum = /* unused export */ undefined;
1623
1694
  var graphql_types_IdentityProviderEnum = /* unused export */ undefined;
1624
1695
  var graphql_types_ImageConfigTypeEnum = /* unused export */ undefined;
1625
1696
  var graphql_types_IncludeExcludeTypeEnum = /* unused export */ undefined;
1697
+ var graphql_types_IntegrationDirectoryIntegrationEnum = /* unused export */ undefined;
1698
+ var graphql_types_IntegrationDirectoryResourceEnum = /* unused export */ undefined;
1626
1699
  var graphql_types_LauncherBackgroundShapeEnum = /* unused export */ undefined;
1627
1700
  var graphql_types_LauncherBackgroundTypeEnum = /* unused export */ undefined;
1628
1701
  var graphql_types_LauncherIconEnum = /* unused export */ undefined;
@@ -1683,4 +1756,4 @@ var graphql_types_VariableCategoryEnum = /* unused export */ undefined;
1683
1756
  var graphql_types_VariableRequireEnum = /* unused export */ undefined;
1684
1757
  var graphql_types_WorkflowTimingEnum = /* unused export */ undefined;
1685
1758
  var graphql_types_WorkflowTriggerTypeEnum = /* unused export */ undefined;
1686
- export { AssetDeliveryTypeEnum, BackgroundTypeEnum, ContentAnimationTypeEnum, ContentVariationTypeEnum, CtaTypeEnum, ImagePlacementTypeEnum, ImagePositionTypeEnum, LocationEnum, TargetTriggerTypeEnum, graphql_types_AdAccountExternalEnum as AdAccountExternalEnum, graphql_types_AiActivationRuleTriggerTypeEnum as AiActivationRuleTriggerTypeEnum, graphql_types_AiEngagementRuleTypeEnum as AiEngagementRuleTypeEnum, graphql_types_AiInteractionFeedbackRatingCategoryEnum as AiInteractionFeedbackRatingCategoryEnum, graphql_types_AiInteractionFeedbackRatingEnum as AiInteractionFeedbackRatingEnum, graphql_types_AiInteractionMessageComposerEnum as AiInteractionMessageComposerEnum, graphql_types_AiInteractionMessageToneEnum as AiInteractionMessageToneEnum, graphql_types_AiInteractionReportRatingCategoryEnum as AiInteractionReportRatingCategoryEnum, graphql_types_AiInteractionSourceEnum as AiInteractionSourceEnum, graphql_types_AiLocaleEnum as AiLocaleEnum, graphql_types_AiStrategyFallbackTypeEnum as AiStrategyFallbackTypeEnum, graphql_types_AiStrategySelectionMethodTypeEnum as AiStrategySelectionMethodTypeEnum, graphql_types_AnnouncementEventTypeEnum as AnnouncementEventTypeEnum, graphql_types_AnnouncementTypeEnum as AnnouncementTypeEnum, graphql_types_AuthenticationStateEnum as AuthenticationStateEnum, graphql_types_AutoIndexFrequencyTypeEnum as AutoIndexFrequencyTypeEnum, graphql_types_BotTypeEnum as BotTypeEnum, graphql_types_BusinessHoursDaysEnum as BusinessHoursDaysEnum, graphql_types_ButtonShapeEnum as ButtonShapeEnum, graphql_types_ButtonStyleEnum as ButtonStyleEnum, graphql_types_CalendarEventTypeRestrictionTypeEnum as CalendarEventTypeRestrictionTypeEnum, graphql_types_CalendarEventTypeRoutingTypeEnum as CalendarEventTypeRoutingTypeEnum, graphql_types_CalendarEventTypeTimeUnitEnum as CalendarEventTypeTimeUnitEnum, graphql_types_CallboxBackgroundTypeEnum as CallboxBackgroundTypeEnum, graphql_types_CampaignAudienceEstimateJobStatusEnum as CampaignAudienceEstimateJobStatusEnum, graphql_types_CampaignDurationTypeEnum as CampaignDurationTypeEnum, graphql_types_CampaignEmailPersistenceEnum as CampaignEmailPersistenceEnum, graphql_types_CampaignExitReasonTypeEnum as CampaignExitReasonTypeEnum, graphql_types_CampaignExitTriggerTypeEnum as CampaignExitTriggerTypeEnum, graphql_types_CampaignGoalTypeEnum as CampaignGoalTypeEnum, graphql_types_CampaignHandoffRoutingRuleTypeEnum as CampaignHandoffRoutingRuleTypeEnum, graphql_types_CampaignJoinFailedReasonTypeEnum as CampaignJoinFailedReasonTypeEnum, graphql_types_CampaignPausedReasonTypeEnum as CampaignPausedReasonTypeEnum, graphql_types_CampaignReplyHandlingEnum as CampaignReplyHandlingEnum, graphql_types_CampaignRoutingRuleTypeEnum as CampaignRoutingRuleTypeEnum, graphql_types_CampaignSampleMailingEmailTypeEnum as CampaignSampleMailingEmailTypeEnum, graphql_types_CampaignSenderIssueReasonEnum as CampaignSenderIssueReasonEnum, graphql_types_CampaignStatusEnum as CampaignStatusEnum, graphql_types_CampaignTemplateEnum as CampaignTemplateEnum, graphql_types_CampaignTransitionEnum as CampaignTransitionEnum, graphql_types_CampaignTriggerTypeEnum as CampaignTriggerTypeEnum, graphql_types_ContentJobStatusEnum as ContentJobStatusEnum, graphql_types_ContentSourceFileTypeEnum as ContentSourceFileTypeEnum, graphql_types_ContentSourceTypeEnum as ContentSourceTypeEnum, graphql_types_ConversationIgnoredTypeEnum as ConversationIgnoredTypeEnum, graphql_types_ConversationTypeEnum as ConversationTypeEnum, graphql_types_ConversionFilterEnum as ConversionFilterEnum, graphql_types_CookieConsentDisplayModeEnum as CookieConsentDisplayModeEnum, graphql_types_DashboardTileDefinitionNameEnum as DashboardTileDefinitionNameEnum, graphql_types_DashboardTileFunnelTypeEnum as DashboardTileFunnelTypeEnum, graphql_types_DashboardTileGraphTypeEnum as DashboardTileGraphTypeEnum, graphql_types_DashboardTilePercentageBasisEnum as DashboardTilePercentageBasisEnum, graphql_types_DashboardTileTimescaleEnum as DashboardTileTimescaleEnum, graphql_types_DashboardTileWidthEnum as DashboardTileWidthEnum, graphql_types_DefaultSyncActionTypeEnum as DefaultSyncActionTypeEnum, graphql_types_DemandbaseVersion as DemandbaseVersion, graphql_types_DevicesEnum as DevicesEnum, graphql_types_EmailFeedbackEmailSourceEnum as EmailFeedbackEmailSourceEnum, graphql_types_EmailHandoffModeEnum as EmailHandoffModeEnum, graphql_types_ExportStatusEnum as ExportStatusEnum, graphql_types_ExportTypeEnum as ExportTypeEnum, graphql_types_ExternalListTypeEnum as ExternalListTypeEnum, graphql_types_ExternalMailingTypeEnum as ExternalMailingTypeEnum, graphql_types_ExternalObjectMatchingFilterObjectTypeEnum as ExternalObjectMatchingFilterObjectTypeEnum, graphql_types_ExternalPushDiagnosisCauseEnum as ExternalPushDiagnosisCauseEnum, graphql_types_ExternalPushDiagnosisCodeEnum as ExternalPushDiagnosisCodeEnum, graphql_types_ExternalPushDiagnosisStatusEnum as ExternalPushDiagnosisStatusEnum, graphql_types_ExternalPushDiagnosisUndeterminedReasonEnum as ExternalPushDiagnosisUndeterminedReasonEnum, graphql_types_ExternalPushIdentityTypeEnum as ExternalPushIdentityTypeEnum, graphql_types_ExternalPushRemediationEnum as ExternalPushRemediationEnum, graphql_types_ExternalPushSortEnum as ExternalPushSortEnum, graphql_types_ExternalPushSourceEnum as ExternalPushSourceEnum, graphql_types_ExternalSourceEnum as ExternalSourceEnum, graphql_types_FieldCategoryEnum as FieldCategoryEnum, graphql_types_FrequencyEnum as FrequencyEnum, graphql_types_GreetingHeaderImageSizeEnum as GreetingHeaderImageSizeEnum, graphql_types_GreetingHeaderStyleEnum as GreetingHeaderStyleEnum, graphql_types_GuardrailSubCollectionEnum as GuardrailSubCollectionEnum, graphql_types_GuideVersion as GuideVersion, graphql_types_HeaderBackgroundTypeEnum as HeaderBackgroundTypeEnum, graphql_types_IdentityProviderEnum as IdentityProviderEnum, graphql_types_ImageConfigTypeEnum as ImageConfigTypeEnum, graphql_types_IncludeExcludeTypeEnum as IncludeExcludeTypeEnum, graphql_types_LauncherBackgroundShapeEnum as LauncherBackgroundShapeEnum, graphql_types_LauncherBackgroundTypeEnum as LauncherBackgroundTypeEnum, graphql_types_LauncherIconEnum as LauncherIconEnum, graphql_types_LeadMetricTypeEnum as LeadMetricTypeEnum, graphql_types_LeadSortTypeEnum as LeadSortTypeEnum, graphql_types_LeadSpotlightStatusEnum as LeadSpotlightStatusEnum, graphql_types_LeadTimelineEventSourceTypeEnum as LeadTimelineEventSourceTypeEnum, graphql_types_LeadsCampaignEventTypeEnum as LeadsCampaignEventTypeEnum, graphql_types_LeadsCampaignStatusTypeEnum as LeadsCampaignStatusTypeEnum, graphql_types_MailingReasonTypeEnum as MailingReasonTypeEnum, graphql_types_MailingStatusEnum as MailingStatusEnum, graphql_types_MailingTypeEnum as MailingTypeEnum, graphql_types_MarketingDataTypeEnum as MarketingDataTypeEnum, graphql_types_MeetingLinkTypeEnum as MeetingLinkTypeEnum, graphql_types_MeetingOfferChannelTypeEnum as MeetingOfferChannelTypeEnum, graphql_types_MessageEventTypeEnum as MessageEventTypeEnum, graphql_types_MessageSourceEnum as MessageSourceEnum, graphql_types_MessageTransformationSourceEnum as MessageTransformationSourceEnum, graphql_types_MessageTransformationToneEnum as MessageTransformationToneEnum, graphql_types_MessageTransformationTypeEnum as MessageTransformationTypeEnum, graphql_types_MultimodalModalityEnum as MultimodalModalityEnum, graphql_types_MultimodalOpenedPositionEnum as MultimodalOpenedPositionEnum, graphql_types_MultimodalStartingPositionEnum as MultimodalStartingPositionEnum, graphql_types_OpportunityAttributionModelEnum as OpportunityAttributionModelEnum, graphql_types_OpportunityInfluenceTypeEnum as OpportunityInfluenceTypeEnum, graphql_types_OpportunityMatchTypeEnum as OpportunityMatchTypeEnum, graphql_types_PageFilter as PageFilter, graphql_types_PreMeetingQuestionTypeEnum as PreMeetingQuestionTypeEnum, graphql_types_PreferredLanguageInferenceSourceEnum as PreferredLanguageInferenceSourceEnum, graphql_types_PreferredLanguageSourceEnum as PreferredLanguageSourceEnum, graphql_types_PrivacyDisclosureDisplayModeEnum as PrivacyDisclosureDisplayModeEnum, graphql_types_PrivacyDisclosureTargetEnum as PrivacyDisclosureTargetEnum, graphql_types_RoutingLogEntryTypeEnum as RoutingLogEntryTypeEnum, graphql_types_SalesforceFieldPermissionEnum as SalesforceFieldPermissionEnum, graphql_types_SalesforcePersonTypeEnum as SalesforcePersonTypeEnum, graphql_types_SalesforceUserInvitedStateEnum as SalesforceUserInvitedStateEnum, graphql_types_SegmentTypeEnum as SegmentTypeEnum, graphql_types_SessionStatusEnum as SessionStatusEnum, graphql_types_SignalsFilterEnum as SignalsFilterEnum, graphql_types_SignalsHighIntentActionEnum as SignalsHighIntentActionEnum, graphql_types_SignalsListTypeEnum as SignalsListTypeEnum, graphql_types_SimulationLeadActivitySourceEnum as SimulationLeadActivitySourceEnum, graphql_types_SimulatorNotReadyReason as SimulatorNotReadyReason, graphql_types_TargetDurationTypeEnum as TargetDurationTypeEnum, graphql_types_TargetLocationTypeEnum as TargetLocationTypeEnum, graphql_types_TopicMappingImportanceEnum as TopicMappingImportanceEnum, graphql_types_TurnFeedbackSentiment as TurnFeedbackSentiment, graphql_types_TurnstileVersion as TurnstileVersion, graphql_types_UnsubscribeFieldSourceEnum as UnsubscribeFieldSourceEnum, graphql_types_UnsubscribeFieldValueOperatorEnum as UnsubscribeFieldValueOperatorEnum, graphql_types_UserActionRequiredReasonEnum as UserActionRequiredReasonEnum, graphql_types_UserPermissionTypeEnum as UserPermissionTypeEnum, graphql_types_UserProfileFeaturePermissionEnum as UserProfileFeaturePermissionEnum, graphql_types_UserProfilePermissionActionEnum as UserProfilePermissionActionEnum, graphql_types_UserProfileTypeEnum as UserProfileTypeEnum, graphql_types_ValueSourceEnum as ValueSourceEnum, graphql_types_VariableCategoryEnum as VariableCategoryEnum, graphql_types_VariableRequireEnum as VariableRequireEnum, graphql_types_WorkflowTimingEnum as WorkflowTimingEnum, graphql_types_WorkflowTriggerTypeEnum as WorkflowTriggerTypeEnum };
1759
+ export { AssetDeliveryTypeEnum, BackgroundTypeEnum, ContentAnimationTypeEnum, ContentVariationTypeEnum, CtaTypeEnum, ImagePlacementTypeEnum, ImagePositionTypeEnum, LocationEnum, TargetTriggerTypeEnum, graphql_types_AdAccountExternalEnum as AdAccountExternalEnum, graphql_types_AiActivationRuleTriggerTypeEnum as AiActivationRuleTriggerTypeEnum, graphql_types_AiEngagementRuleTypeEnum as AiEngagementRuleTypeEnum, graphql_types_AiInteractionFeedbackRatingCategoryEnum as AiInteractionFeedbackRatingCategoryEnum, graphql_types_AiInteractionFeedbackRatingEnum as AiInteractionFeedbackRatingEnum, graphql_types_AiInteractionMessageComposerEnum as AiInteractionMessageComposerEnum, graphql_types_AiInteractionMessageToneEnum as AiInteractionMessageToneEnum, graphql_types_AiInteractionReportRatingCategoryEnum as AiInteractionReportRatingCategoryEnum, graphql_types_AiInteractionSourceEnum as AiInteractionSourceEnum, graphql_types_AiLocaleEnum as AiLocaleEnum, graphql_types_AiStrategyFallbackTypeEnum as AiStrategyFallbackTypeEnum, graphql_types_AiStrategySelectionMethodTypeEnum as AiStrategySelectionMethodTypeEnum, graphql_types_AnnouncementEventTypeEnum as AnnouncementEventTypeEnum, graphql_types_AnnouncementTypeEnum as AnnouncementTypeEnum, graphql_types_AuthenticationStateEnum as AuthenticationStateEnum, graphql_types_AutoIndexFrequencyTypeEnum as AutoIndexFrequencyTypeEnum, graphql_types_BotTypeEnum as BotTypeEnum, graphql_types_BusinessHoursDaysEnum as BusinessHoursDaysEnum, graphql_types_ButtonShapeEnum as ButtonShapeEnum, graphql_types_ButtonStyleEnum as ButtonStyleEnum, graphql_types_CalendarEventTypeRestrictionTypeEnum as CalendarEventTypeRestrictionTypeEnum, graphql_types_CalendarEventTypeRoutingTypeEnum as CalendarEventTypeRoutingTypeEnum, graphql_types_CalendarEventTypeTimeUnitEnum as CalendarEventTypeTimeUnitEnum, graphql_types_CallboxBackgroundTypeEnum as CallboxBackgroundTypeEnum, graphql_types_CampaignAudienceEstimateJobStatusEnum as CampaignAudienceEstimateJobStatusEnum, graphql_types_CampaignDurationTypeEnum as CampaignDurationTypeEnum, graphql_types_CampaignEmailPersistenceEnum as CampaignEmailPersistenceEnum, graphql_types_CampaignExitReasonTypeEnum as CampaignExitReasonTypeEnum, graphql_types_CampaignExitTriggerTypeEnum as CampaignExitTriggerTypeEnum, graphql_types_CampaignGoalTypeEnum as CampaignGoalTypeEnum, graphql_types_CampaignHandoffRoutingRuleTypeEnum as CampaignHandoffRoutingRuleTypeEnum, graphql_types_CampaignJoinFailedReasonTypeEnum as CampaignJoinFailedReasonTypeEnum, graphql_types_CampaignNotEnrolledReasonTypeEnum as CampaignNotEnrolledReasonTypeEnum, graphql_types_CampaignPausedReasonTypeEnum as CampaignPausedReasonTypeEnum, graphql_types_CampaignReplyHandlingEnum as CampaignReplyHandlingEnum, graphql_types_CampaignRoutingRuleTypeEnum as CampaignRoutingRuleTypeEnum, graphql_types_CampaignSampleMailingEmailTypeEnum as CampaignSampleMailingEmailTypeEnum, graphql_types_CampaignSenderIssueReasonEnum as CampaignSenderIssueReasonEnum, graphql_types_CampaignStatusEnum as CampaignStatusEnum, graphql_types_CampaignTemplateEnum as CampaignTemplateEnum, graphql_types_CampaignTransitionEnum as CampaignTransitionEnum, graphql_types_CampaignTriggerTypeEnum as CampaignTriggerTypeEnum, graphql_types_ContentJobStatusEnum as ContentJobStatusEnum, graphql_types_ContentLibraryActionEnum as ContentLibraryActionEnum, graphql_types_ContentLibraryItemKindEnum as ContentLibraryItemKindEnum, graphql_types_ContentLibraryItemOrderEnum as ContentLibraryItemOrderEnum, graphql_types_ContentLibraryItemStatusFilterEnum as ContentLibraryItemStatusFilterEnum, graphql_types_ContentSourceFileTypeEnum as ContentSourceFileTypeEnum, graphql_types_ContentSourceTypeEnum as ContentSourceTypeEnum, graphql_types_ConversationIgnoredTypeEnum as ConversationIgnoredTypeEnum, graphql_types_ConversationTypeEnum as ConversationTypeEnum, graphql_types_ConversionFilterEnum as ConversionFilterEnum, graphql_types_CookieConsentDisplayModeEnum as CookieConsentDisplayModeEnum, graphql_types_CustomVoiceStatusEnum as CustomVoiceStatusEnum, graphql_types_DashboardTileDefinitionNameEnum as DashboardTileDefinitionNameEnum, graphql_types_DashboardTileFunnelTypeEnum as DashboardTileFunnelTypeEnum, graphql_types_DashboardTileGraphTypeEnum as DashboardTileGraphTypeEnum, graphql_types_DashboardTilePercentageBasisEnum as DashboardTilePercentageBasisEnum, graphql_types_DashboardTileTimescaleEnum as DashboardTileTimescaleEnum, graphql_types_DashboardTileWidthEnum as DashboardTileWidthEnum, graphql_types_DefaultSyncActionTypeEnum as DefaultSyncActionTypeEnum, graphql_types_DemandbaseVersion as DemandbaseVersion, graphql_types_DevicesEnum as DevicesEnum, graphql_types_EmailFeedbackEmailSourceEnum as EmailFeedbackEmailSourceEnum, graphql_types_EmailHandoffModeEnum as EmailHandoffModeEnum, graphql_types_ExportStatusEnum as ExportStatusEnum, graphql_types_ExportTypeEnum as ExportTypeEnum, graphql_types_ExternalListTypeEnum as ExternalListTypeEnum, graphql_types_ExternalMailingTypeEnum as ExternalMailingTypeEnum, graphql_types_ExternalObjectMatchingFilterObjectTypeEnum as ExternalObjectMatchingFilterObjectTypeEnum, graphql_types_ExternalPushDiagnosisCauseEnum as ExternalPushDiagnosisCauseEnum, graphql_types_ExternalPushDiagnosisCodeEnum as ExternalPushDiagnosisCodeEnum, graphql_types_ExternalPushDiagnosisStatusEnum as ExternalPushDiagnosisStatusEnum, graphql_types_ExternalPushDiagnosisUndeterminedReasonEnum as ExternalPushDiagnosisUndeterminedReasonEnum, graphql_types_ExternalPushIdentityTypeEnum as ExternalPushIdentityTypeEnum, graphql_types_ExternalPushRemediationEnum as ExternalPushRemediationEnum, graphql_types_ExternalPushSortEnum as ExternalPushSortEnum, graphql_types_ExternalPushSourceEnum as ExternalPushSourceEnum, graphql_types_ExternalSourceEnum as ExternalSourceEnum, graphql_types_FieldCategoryEnum as FieldCategoryEnum, graphql_types_FrequencyEnum as FrequencyEnum, graphql_types_GreetingHeaderImageSizeEnum as GreetingHeaderImageSizeEnum, graphql_types_GreetingHeaderStyleEnum as GreetingHeaderStyleEnum, graphql_types_GuardrailSubCollectionEnum as GuardrailSubCollectionEnum, graphql_types_GuideVersion as GuideVersion, graphql_types_HeaderBackgroundTypeEnum as HeaderBackgroundTypeEnum, graphql_types_IdentityProviderEnum as IdentityProviderEnum, graphql_types_ImageConfigTypeEnum as ImageConfigTypeEnum, graphql_types_IncludeExcludeTypeEnum as IncludeExcludeTypeEnum, graphql_types_IntegrationDirectoryIntegrationEnum as IntegrationDirectoryIntegrationEnum, graphql_types_IntegrationDirectoryResourceEnum as IntegrationDirectoryResourceEnum, graphql_types_LauncherBackgroundShapeEnum as LauncherBackgroundShapeEnum, graphql_types_LauncherBackgroundTypeEnum as LauncherBackgroundTypeEnum, graphql_types_LauncherIconEnum as LauncherIconEnum, graphql_types_LeadMetricTypeEnum as LeadMetricTypeEnum, graphql_types_LeadSortTypeEnum as LeadSortTypeEnum, graphql_types_LeadSpotlightStatusEnum as LeadSpotlightStatusEnum, graphql_types_LeadTimelineEventSourceTypeEnum as LeadTimelineEventSourceTypeEnum, graphql_types_LeadsCampaignEventTypeEnum as LeadsCampaignEventTypeEnum, graphql_types_LeadsCampaignStatusTypeEnum as LeadsCampaignStatusTypeEnum, graphql_types_MailingReasonTypeEnum as MailingReasonTypeEnum, graphql_types_MailingStatusEnum as MailingStatusEnum, graphql_types_MailingTypeEnum as MailingTypeEnum, graphql_types_MarketingDataTypeEnum as MarketingDataTypeEnum, graphql_types_MeetingLinkTypeEnum as MeetingLinkTypeEnum, graphql_types_MeetingOfferChannelTypeEnum as MeetingOfferChannelTypeEnum, graphql_types_MessageEventTypeEnum as MessageEventTypeEnum, graphql_types_MessageSourceEnum as MessageSourceEnum, graphql_types_MessageTransformationSourceEnum as MessageTransformationSourceEnum, graphql_types_MessageTransformationToneEnum as MessageTransformationToneEnum, graphql_types_MessageTransformationTypeEnum as MessageTransformationTypeEnum, graphql_types_MultimodalModalityEnum as MultimodalModalityEnum, graphql_types_MultimodalOpenedPositionEnum as MultimodalOpenedPositionEnum, graphql_types_MultimodalStartingPositionEnum as MultimodalStartingPositionEnum, graphql_types_OpportunityAttributionModelEnum as OpportunityAttributionModelEnum, graphql_types_OpportunityInfluenceTypeEnum as OpportunityInfluenceTypeEnum, graphql_types_OpportunityMatchTypeEnum as OpportunityMatchTypeEnum, graphql_types_PageFilter as PageFilter, graphql_types_PreMeetingQuestionTypeEnum as PreMeetingQuestionTypeEnum, graphql_types_PreferredLanguageInferenceSourceEnum as PreferredLanguageInferenceSourceEnum, graphql_types_PreferredLanguageSourceEnum as PreferredLanguageSourceEnum, graphql_types_PrivacyDisclosureDisplayModeEnum as PrivacyDisclosureDisplayModeEnum, graphql_types_PrivacyDisclosureTargetEnum as PrivacyDisclosureTargetEnum, graphql_types_RoutingLogEntryTypeEnum as RoutingLogEntryTypeEnum, graphql_types_SalesforceFieldPermissionEnum as SalesforceFieldPermissionEnum, graphql_types_SalesforcePersonTypeEnum as SalesforcePersonTypeEnum, graphql_types_SalesforceUserInvitedStateEnum as SalesforceUserInvitedStateEnum, graphql_types_SegmentTypeEnum as SegmentTypeEnum, graphql_types_SessionStatusEnum as SessionStatusEnum, graphql_types_SignalsFilterEnum as SignalsFilterEnum, graphql_types_SignalsHighIntentActionEnum as SignalsHighIntentActionEnum, graphql_types_SignalsListTypeEnum as SignalsListTypeEnum, graphql_types_SimulationLeadActivitySourceEnum as SimulationLeadActivitySourceEnum, graphql_types_SimulatorNotReadyReason as SimulatorNotReadyReason, graphql_types_TargetDurationTypeEnum as TargetDurationTypeEnum, graphql_types_TargetLocationTypeEnum as TargetLocationTypeEnum, graphql_types_TopicMappingImportanceEnum as TopicMappingImportanceEnum, graphql_types_TurnFeedbackSentiment as TurnFeedbackSentiment, graphql_types_TurnstileVersion as TurnstileVersion, graphql_types_UnsubscribeFieldSourceEnum as UnsubscribeFieldSourceEnum, graphql_types_UnsubscribeFieldValueOperatorEnum as UnsubscribeFieldValueOperatorEnum, graphql_types_UserActionRequiredReasonEnum as UserActionRequiredReasonEnum, graphql_types_UserPermissionTypeEnum as UserPermissionTypeEnum, graphql_types_UserProfileFeaturePermissionEnum as UserProfileFeaturePermissionEnum, graphql_types_UserProfilePermissionActionEnum as UserProfilePermissionActionEnum, graphql_types_UserProfileTypeEnum as UserProfileTypeEnum, graphql_types_ValueSourceEnum as ValueSourceEnum, graphql_types_VariableCategoryEnum as VariableCategoryEnum, graphql_types_VariableRequireEnum as VariableRequireEnum, graphql_types_WorkflowTimingEnum as WorkflowTimingEnum, graphql_types_WorkflowTriggerTypeEnum as WorkflowTriggerTypeEnum };
package/src/url.js CHANGED
@@ -20,8 +20,11 @@ const isSafeUrl = (url)=>{
20
20
  // Strips scheme and www subdomain from a url
21
21
  //
22
22
  function prettyUrl(url, short) {
23
+ var _url_split_;
23
24
  if (!url) return "";
24
- url = url.split("?")[0];
25
+ // split always yields at least one element, so the fallback is only to satisfy
26
+ // noUncheckedIndexedAccess in the projects that consume this file.
27
+ url = (_url_split_ = url.split("?")[0]) != null ? _url_split_ : url;
25
28
  if (short) {
26
29
  const pretty = url.replace(/^(https?:\/\/[^/]+)/i, "");
27
30
  if (pretty && pretty !== "/") {
@@ -2,6 +2,7 @@ import { __webpack_require__ } from "../../js/runtime.js";
2
2
  import { default as adapters } from "./adapters.js";
3
3
  import { default as connection_monitor } from "./connection_monitor.js";
4
4
  import { logger } from "./logger.js";
5
+ import { default as SseSocket } from "./sse_socket.js";
5
6
  import { INTERNAL as internal } from "./internal.js";
6
7
  import "../../widget/utils/native_globals.js";
7
8
 
@@ -10,6 +11,7 @@ import "../../widget/utils/native_globals.js";
10
11
 
11
12
 
12
13
 
14
+ // PATCH: local module, not part of the upstream bundle
13
15
  // Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.
14
16
  const { message_types: message_types, protocols: protocols } = internal;
15
17
  const supportedProtocols = protocols.slice(0, protocols.length - 1);
@@ -32,7 +34,10 @@ class Connection {
32
34
  if (this.webSocket) {
33
35
  this.uninstallEventHandlers();
34
36
  }
35
- this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
37
+ // START PATCH: the consumer may swap in a non-WebSocket transport. @see SseSocket
38
+ const Transport = this.consumer.transport || this.defaultTransport();
39
+ this.webSocket = new Transport(this.consumer.url, protocols, this.consumer.fallback);
40
+ // END PATCH
36
41
  this.installEventHandlers();
37
42
  this.monitor.start();
38
43
  // START PATCH
@@ -84,6 +89,32 @@ class Connection {
84
89
  return !!this._connectedBefore;
85
90
  }
86
91
  // END PATCH
92
+ // START PATCH
93
+ // Whether it is worth giving up on WebSockets. Only while no socket has ever opened: a blocked
94
+ // upgrade never reaches onopen, but one merely waiting on a slow connect RPC does. Gating on the
95
+ // welcome instead would escalate those too, in bulk, exactly when RPC is already congested.
96
+ canFallback() {
97
+ return !!this.consumer.fallback && !this.consumer.transport && !this.opened;
98
+ }
99
+ // A page can remove WebSocket outright (`window.WebSocket = null`). There is nothing to escalate
100
+ // from then, since constructing the socket throws before the monitor is started to notice it, so
101
+ // the fallback is chosen up front. With none configured this throws as upstream does.
102
+ defaultTransport() {
103
+ if (typeof adapters.WebSocket === "function" || !this.consumer.fallback) {
104
+ return adapters.WebSocket;
105
+ }
106
+ logger.log("WebSocket is unavailable, opening the SSE + HTTP transport instead");
107
+ this.consumer.transport = SseSocket;
108
+ return SseSocket;
109
+ }
110
+ // Swap the transport and reconnect over it. Nothing else has to move: the transport reports a
111
+ // welcome, and this class answers a welcome by resubscribing every channel. @see SseSocket
112
+ fallback() {
113
+ logger.log("Falling back to the SSE + HTTP transport");
114
+ this.consumer.transport = SseSocket;
115
+ return this.reopen();
116
+ }
117
+ // END PATCH
87
118
  // Private
88
119
  isProtocolSupported() {
89
120
  return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
@@ -94,16 +125,21 @@ class Connection {
94
125
  }
95
126
  return indexOf.call(states, this.getState()) >= 0;
96
127
  }
128
+ // START PATCH: read the ready states off the transport in use rather than adapters.WebSocket.
129
+ // A page that removed WebSocket leaves that with no constants to enumerate, which would strand
130
+ // every lookup at null and quietly make isOpen(), and so send(), always false.
97
131
  getState() {
98
132
  if (this.webSocket) {
99
- for(let state in adapters.WebSocket){
100
- if (adapters.WebSocket[state] === this.webSocket.readyState) {
133
+ const transport = this.webSocket.constructor || adapters.WebSocket;
134
+ for(let state in transport){
135
+ if (transport[state] === this.webSocket.readyState) {
101
136
  return state.toLowerCase();
102
137
  }
103
138
  }
104
139
  }
105
140
  return null;
106
141
  }
142
+ // END PATCH
107
143
  installEventHandlers() {
108
144
  for(let eventName in this.events){
109
145
  const handler = this.events[eventName].bind(this);
@@ -177,6 +213,7 @@ Connection.prototype.events = {
177
213
  open () {
178
214
  logger.log("WebSocket onopen event, using '" + this.getProtocol() + "' subprotocol");
179
215
  this.disconnected = false;
216
+ this.opened = true; // PATCH: gates the transport fallback. @see canFallback
180
217
  if (!this.isProtocolSupported()) {
181
218
  logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
182
219
  return this.close({
@@ -84,6 +84,14 @@ class ConnectionMonitor {
84
84
  } else if (this.waitingForConnect()) {
85
85
  logger.log("ConnectionMonitor skipping reopening recent connect waiting. time waiting = " + secondsSince(this.connectWaitingStartedAt) + " s");
86
86
  // END PATCH
87
+ // START PATCH
88
+ } else if (this.connection.canFallback()) {
89
+ // A socket that has never once opened is more likely blocked than flaky -- a proxy that
90
+ // refuses WebSocket upgrades will keep refusing them -- so reopening it forever is futile.
91
+ // Retrying over a transport that only needs plain HTTP is the better next attempt.
92
+ logger.log("ConnectionMonitor falling back to another transport");
93
+ this.connection.fallback();
94
+ // END PATCH
87
95
  } else {
88
96
  logger.log("ConnectionMonitor reopening");
89
97
  this.connection.reopen();
@@ -26,8 +26,14 @@ class Consumer {
26
26
  return this.connection.open();
27
27
  }
28
28
  }
29
- constructor(url){
29
+ constructor(url, options){
30
30
  this._url = url;
31
+ // START PATCH: config for the optional SSE + HTTP transport, used for networks that block
32
+ // WebSocket upgrades. Supplying `{ upstreamUrl }` is what permits Connection to escalate to it.
33
+ // The `options` constructor argument is part of this patch too. @see SseSocket
34
+ this.fallback = options && options.fallback || null;
35
+ this.transport = null;
36
+ // END PATCH
31
37
  this.subscriptions = new Subscriptions(this);
32
38
  this.connection = new connection(this);
33
39
  }
@@ -10,10 +10,13 @@ import { INTERNAL as internal } from "./internal.js";
10
10
 
11
11
 
12
12
 
13
- function createConsumer(url) {
13
+ // START PATCH: pass options through to the Consumer, for the fallback transport config.
14
+ // @see SseSocket
15
+ function createConsumer(url, options) {
14
16
  if (url === void 0) url = getConfig("url") || internal.default_mount_path;
15
- return new Consumer(url);
17
+ return new Consumer(url, options);
16
18
  }
19
+ // END PATCH
17
20
  function getConfig(name) {
18
21
  const element = document.head.querySelector("meta[name='action-cable-" + name + "']");
19
22
  if (element) {
@@ -0,0 +1,262 @@
1
+ import { __webpack_require__ } from "../../js/runtime.js";
2
+ import { logger } from "./logger.js";
3
+ import { INTERNAL as internal } from "./internal.js";
4
+ import "../../widget/utils/native_globals.js";
5
+
6
+ /* provided dependency */ var sse_socket_setTimeout = __webpack_require__(68034).pS;
7
+
8
+
9
+ // PATCH: this whole file is local, with no upstream Action Cable equivalent. Nothing here needs
10
+ // reconciling on an upgrade; the hooks that reach it are marked in connection.js and consumer.js.
11
+ //
12
+ // A WebSocket-shaped transport backed by SSE downstream and HTTP POST upstream, for visitors whose
13
+ // network blocks WebSocket upgrades. Connection only touches `protocol`, `readyState`, the four
14
+ // `on*` handlers, `send` and `close`, so implementing those runs the whole Action Cable protocol
15
+ // layer unchanged.
16
+ //
17
+ // Downstream is anycable-go's SSE endpoint (requires `--sse`, anycable-go >= 1.4.4), which serves
18
+ // one channel per request, so a stream is opened per `subscribe`. Upstream is
19
+ // WidgetAPI::V1::CableFallbackController: anycable-go cannot take commands directly, since its SSE
20
+ // endpoint reads the whole request body before it starts streaming.
21
+ const { message_types: message_types, protocols: protocols } = internal;
22
+ const READY_STATE = {
23
+ CONNECTING: 0,
24
+ OPEN: 1,
25
+ CLOSING: 2,
26
+ CLOSED: 3
27
+ };
28
+ // Browsers reject a `keepalive` request whose body is larger than this outright.
29
+ const KEEPALIVE_MAX_BYTES = 64 * 1024;
30
+ // The credential travels beside the command rather than inside it. Not `Authorization`, which this
31
+ // app already reads as a BearerToken. @see CableFallbackController::CONNECTION_TOKEN_HEADER
32
+ const CONNECTION_TOKEN_HEADER = "X-Cable-Connection-Token";
33
+ // The statuses that refuse the connection rather than the command: the endpoint will not honour the
34
+ // token, or the rows behind it are gone. @see CableFallbackController
35
+ const CONNECTION_REFUSED = [
36
+ 401,
37
+ 404
38
+ ];
39
+ // Frames anycable-go names on the stream that Connection already handles. `welcome` is absent:
40
+ // Connection answers one by reloading subscriptions, which would reopen the streams that just sent
41
+ // it, so the single welcome that starts the session is synthesized in `handshake` instead.
42
+ const FORWARDED_EVENTS = [
43
+ message_types.confirmation,
44
+ message_types.rejection,
45
+ message_types.ping,
46
+ message_types.disconnect
47
+ ];
48
+ class SseSocket {
49
+ send(payload) {
50
+ const { command, identifier, data } = JSON.parse(payload);
51
+ switch(command){
52
+ // Opening the stream is the subscribe: anycable-go builds a subscribe command out of the
53
+ // `identifier` query param, and answers with `confirm_subscription` on the stream.
54
+ case "subscribe":
55
+ return this.openStream(identifier);
56
+ // Likewise, closing the stream ends that session, which unsubscribes it server-side.
57
+ case "unsubscribe":
58
+ return this.closeStream(identifier);
59
+ default:
60
+ return this.enqueueCommand({
61
+ command,
62
+ identifier,
63
+ data
64
+ });
65
+ }
66
+ }
67
+ close() {
68
+ if (this.readyState === READY_STATE.CLOSED) return;
69
+ this.readyState = READY_STATE.CLOSED;
70
+ this.sources.forEach((source)=>source.close());
71
+ this.sources.clear();
72
+ this.pending = [];
73
+ if (this.onclose) this.onclose({});
74
+ }
75
+ // Private
76
+ handshake() {
77
+ if (this.readyState !== READY_STATE.CONNECTING) return;
78
+ this.readyState = READY_STATE.OPEN;
79
+ if (this.onopen) this.onopen({});
80
+ // Optimistic: nothing has been proven reachable yet. It has to be this way round, because
81
+ // Connection will not send the subscribe commands that open the streams until it sees a
82
+ // welcome. A stream that then fails to open reports itself as a disconnect.
83
+ this.deliver({
84
+ type: message_types.welcome
85
+ });
86
+ }
87
+ openStream(identifier) {
88
+ if (this.sources.has(identifier)) return;
89
+ const source = new EventSource(this.streamUrl(identifier));
90
+ this.sources.set(identifier, source);
91
+ FORWARDED_EVENTS.forEach((type)=>{
92
+ source.addEventListener(type, (event)=>this.emit(event.data));
93
+ });
94
+ // Not forwarded either, but it carries the upstream token. One token serves every stream, so
95
+ // only a welcome arriving while there is none to fall back on drops the transport -- as a dead
96
+ // stream, for the monitor to rebuild. Under `message`: @see AnyCable::Connection#welcome_message
97
+ source.addEventListener(message_types.welcome, (event)=>{
98
+ const frame = parse(event.data);
99
+ const token = frame && frame.message && frame.message.connection_token;
100
+ if (token) {
101
+ this.token = token;
102
+ this.flush();
103
+ } else if (!this.token && this.readyState === READY_STATE.OPEN) {
104
+ this.close();
105
+ }
106
+ });
107
+ // Unnamed events carry channel payloads. A GET stream sends only the `message` half of the
108
+ // envelope, so the identifier the stream was opened for has to be put back on.
109
+ source.addEventListener("message", (event)=>{
110
+ const message = parse(event.data);
111
+ if (message) this.deliver({
112
+ identifier,
113
+ message
114
+ });
115
+ });
116
+ // A dead stream is this transport's dropped socket, so it closes rather than reporting a
117
+ // reason, and ConnectionMonitor retries with backoff. Closing also stops EventSource's own
118
+ // retry, which would otherwise race the monitor for ownership of reconnection.
119
+ source.addEventListener("error", ()=>{
120
+ if (this.readyState !== READY_STATE.OPEN) return;
121
+ this.close();
122
+ });
123
+ }
124
+ // Same host and connection params as the socket: anycable-go serves SSE from `/events` by default
125
+ // (--sse_path), where the cable itself is mounted at `/cable`.
126
+ streamUrl(identifier) {
127
+ const url = new URL(this.url.replace(/^ws/, "http"));
128
+ url.pathname = url.pathname.replace(/\/cable$/, "/events");
129
+ url.searchParams.set("identifier", identifier);
130
+ return url.toString();
131
+ }
132
+ closeStream(identifier) {
133
+ const source = this.sources.get(identifier);
134
+ if (!source) return;
135
+ source.close();
136
+ this.sources.delete(identifier);
137
+ }
138
+ // Everything queues, because a command can be unsendable for two reasons that end the same way:
139
+ // the welcome has not brought a token yet, or a request is already in flight. Unbounded is safe
140
+ // -- a transport that stops making progress goes stale, and the reopen drops the queue with it.
141
+ enqueueCommand(body) {
142
+ this.pending.push(body);
143
+ this.flush();
144
+ }
145
+ // One command in flight at a time, each chained behind the answer to the last: two posts on the
146
+ // wire can reach different workers in either order, where a socket could not. It also lets an
147
+ // answer stop what is behind it -- a disconnect closes the transport, and closing drops the
148
+ // queue. An idle queue drains immediately, so a cable that sends as it goes never waits.
149
+ async flush() {
150
+ // Every stream welcomes, so this is reached once per subscription. A second drain racing the
151
+ // first over the same queue is the concurrency this exists to avoid.
152
+ if (!this.token || this.flushing || this.readyState !== READY_STATE.OPEN) return;
153
+ this.flushing = true;
154
+ try {
155
+ // Anything enqueued mid-request is waiting here by the time this comes back round.
156
+ while(this.pending.length){
157
+ await this.postCommand(this.pending.shift());
158
+ }
159
+ } finally{
160
+ this.flushing = false;
161
+ }
162
+ }
163
+ // Only the connection being gone takes the transport down with it. A command that fails leaves it
164
+ // up, because a socket does the same: anycable-go logs a command it could not handle and the
165
+ // session carries on, so a bad command costs the command and nothing more.
166
+ async postCommand(command) {
167
+ const payload = JSON.stringify(command);
168
+ let response;
169
+ try {
170
+ response = await fetch(this.options.upstreamUrl, {
171
+ method: "POST",
172
+ headers: {
173
+ "Content-Type": "application/json; charset=utf-8",
174
+ [CONNECTION_TOKEN_HEADER]: this.token
175
+ },
176
+ credentials: "omit",
177
+ // `keepalive` is what lets a command issued during a navigation still land, but an
178
+ // oversized one is refused rather than sent without it. A command large enough to hit the
179
+ // cap is worth more than the navigation guarantee, so it goes as an ordinary request.
180
+ keepalive: new Blob([
181
+ payload
182
+ ]).size <= KEEPALIVE_MAX_BYTES,
183
+ body: payload
184
+ });
185
+ } catch (unused) {
186
+ // Nothing came back at all, so upstream is unreachable rather than unhappy. Connection#send
187
+ // does not await us, so this is also what keeps the rejection from surfacing as an unhandled
188
+ // one. ConnectionMonitor rebuilds from here, and backs off.
189
+ return this.dropTransport();
190
+ }
191
+ // The reconnect that follows re-runs `connect`, the only thing that can authorize a connection.
192
+ if (CONNECTION_REFUSED.includes(response.status)) return this.dropTransport();
193
+ // An answer that came back unreadable is the same loss as one the endpoint refused: what this
194
+ // command was owed, and nothing the connection can be judged on.
195
+ const body = response.ok ? await response.json().catch(()=>null) : null;
196
+ if (!body) {
197
+ logger.log("Cable command failed: " + response.status + " " + response.statusText);
198
+ return;
199
+ }
200
+ // Sliding expiry: re-issued on every command the endpoint accepts, so only a cable that has
201
+ // been silent for the whole TTL meets an expired one. It buys no authority -- the connection is
202
+ // re-checked per request, so a renewal is refused the moment the old one would have been.
203
+ if (body.connection_token) this.token = body.connection_token;
204
+ // Replies the channel made with `transmit` have no stream to travel on, so the endpoint hands
205
+ // them back here. They are already whole Action Cable frames.
206
+ (body.transmissions || []).forEach((transmission)=>this.deliver(transmission));
207
+ if (body.disconnect) {
208
+ this.deliver({
209
+ type: message_types.disconnect,
210
+ reconnect: false
211
+ });
212
+ }
213
+ }
214
+ // Guarded rather than unconditional: a transport already closing or rebuilt has no stake in the
215
+ // answer to a command the last one sent.
216
+ dropTransport() {
217
+ if (this.readyState !== READY_STATE.OPEN) return;
218
+ this.close();
219
+ }
220
+ // Hand Connection a frame in the shape a socket message arrives in.
221
+ deliver(frame) {
222
+ this.emit(JSON.stringify(frame));
223
+ }
224
+ emit(data) {
225
+ if (this.onmessage) this.onmessage({
226
+ data
227
+ });
228
+ }
229
+ // `options` is the consumer's `fallback` config: `{ upstreamUrl }`. Only the upstream half needs
230
+ // an address; the stream URL is derived from the cable URL, since anycable-go serves both.
231
+ constructor(url, subprotocols, options = {}){
232
+ this.url = url;
233
+ this.options = options;
234
+ this.protocol = protocols[0];
235
+ this.readyState = READY_STATE.CONNECTING;
236
+ this.sources = new Map();
237
+ this.token = null;
238
+ this.pending = [];
239
+ this.onopen = null;
240
+ this.onmessage = null;
241
+ this.onclose = null;
242
+ this.onerror = null;
243
+ // Connection installs its handlers immediately after constructing us, so the handshake has to
244
+ // wait a tick. A real socket does not open synchronously either.
245
+ sse_socket_setTimeout(()=>this.handshake(), 0);
246
+ }
247
+ }
248
+ SseSocket.CONNECTING = READY_STATE.CONNECTING;
249
+ SseSocket.OPEN = READY_STATE.OPEN;
250
+ SseSocket.CLOSING = READY_STATE.CLOSING;
251
+ SseSocket.CLOSED = READY_STATE.CLOSED;
252
+
253
+ function parse(data) {
254
+ if (typeof data !== "string" || data.length === 0) return null;
255
+ try {
256
+ return JSON.parse(data);
257
+ } catch (unused) {
258
+ return null;
259
+ }
260
+ }
261
+
262
+ export default SseSocket;
@@ -1,4 +1,5 @@
1
1
  import { default as WidgetObject } from "./widget_object.js";
2
+ import { isCapabilityAllowed } from "./capabilities.js";
2
3
  import { default as google_analytics_tracker } from "./analytics/google_analytics_tracker.js";
3
4
  import { default as google_tag_manager_tracker } from "./analytics/google_tag_manager_tracker.js";
4
5
  import { default as facebook_tracker } from "./analytics/facebook_tracker.js";
@@ -9,8 +10,15 @@ import { _extends } from "../js/4101.js";
9
10
 
10
11
 
11
12
 
13
+
12
14
  class Analytics extends WidgetObject {
13
15
  init() {
16
+ // QAI-5864: no third-party analytics egress (GA / GTM / Facebook) unless the consumer allowed
17
+ // the "analytics" capability. This is the single chokepoint — skipping it both leaves every
18
+ // tracker uninstantiated and never registers the `received` listener that feeds them, so
19
+ // nothing reaches `window.gtag` / `window.dataLayer` / `window.fbq`. Allow-all for the hosted
20
+ // widget (no boundary installed); default-deny once an npm consumer enrols via setup().
21
+ if (!isCapabilityAllowed("analytics")) return;
14
22
  const trackers = [];
15
23
  if (this.config.analytics.googleAnalytics.trackEvents) {
16
24
  trackers.push(new google_analytics_tracker(this.config.analytics.googleAnalytics.propertyId));