@hellotext/hellotext 2.5.7 → 2.5.8

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 (102) hide show
  1. package/README.md +0 -25
  2. package/dist/hellotext.js +1 -1
  3. package/index.d.ts +0 -6
  4. package/lib/api/acks.cjs +17 -31
  5. package/lib/api/acks.js +17 -42
  6. package/lib/api/businesses.cjs +14 -28
  7. package/lib/api/businesses.js +13 -36
  8. package/lib/api/events.cjs +26 -40
  9. package/lib/api/events.js +28 -52
  10. package/lib/api/forms.cjs +24 -40
  11. package/lib/api/forms.js +24 -57
  12. package/lib/api/identifications.cjs +15 -29
  13. package/lib/api/identifications.js +15 -40
  14. package/lib/api/index.cjs +25 -51
  15. package/lib/api/index.js +27 -54
  16. package/lib/api/push/identities.cjs +30 -46
  17. package/lib/api/push/identities.js +30 -63
  18. package/lib/api/response.cjs +30 -52
  19. package/lib/api/response.js +31 -60
  20. package/lib/api/submissions.cjs +18 -34
  21. package/lib/api/submissions.js +18 -48
  22. package/lib/api/webchat/messages.cjs +44 -64
  23. package/lib/api/webchat/messages.js +44 -80
  24. package/lib/api/webchats.cjs +37 -56
  25. package/lib/api/webchats.js +37 -65
  26. package/lib/api/whatsapp_widgets.cjs +49 -72
  27. package/lib/api/whatsapp_widgets.js +48 -91
  28. package/lib/builders/input_builder.cjs +36 -48
  29. package/lib/builders/input_builder.js +36 -48
  30. package/lib/builders/logo_builder.cjs +10 -29
  31. package/lib/builders/logo_builder.js +20 -28
  32. package/lib/channels/application_channel.cjs +136 -178
  33. package/lib/channels/application_channel.js +137 -180
  34. package/lib/channels/webchat_channel.cjs +125 -170
  35. package/lib/channels/webchat_channel.js +125 -170
  36. package/lib/controllers/form_controller.cjs +82 -121
  37. package/lib/controllers/form_controller.js +82 -130
  38. package/lib/controllers/message_controller.cjs +211 -282
  39. package/lib/controllers/message_controller.js +209 -284
  40. package/lib/controllers/mixins/usePopover.cjs +3 -6
  41. package/lib/controllers/mixins/usePopover.js +17 -22
  42. package/lib/controllers/webchat/emoji_picker_controller.cjs +106 -150
  43. package/lib/controllers/webchat/emoji_picker_controller.js +105 -170
  44. package/lib/controllers/webchat/useBehaviour.js +5 -5
  45. package/lib/controllers/webchat/useOpeningSequence.js +6 -6
  46. package/lib/controllers/webchat/useTeaser.js +9 -9
  47. package/lib/controllers/webchat_controller.cjs +916 -1088
  48. package/lib/controllers/webchat_controller.js +926 -1152
  49. package/lib/core/configuration/forms.cjs +21 -35
  50. package/lib/core/configuration/forms.js +20 -35
  51. package/lib/core/configuration/locale.cjs +36 -71
  52. package/lib/core/configuration/locale.js +36 -70
  53. package/lib/core/configuration/push.cjs +9 -21
  54. package/lib/core/configuration/push.js +8 -20
  55. package/lib/core/configuration/webchat.cjs +142 -182
  56. package/lib/core/configuration/webchat.js +145 -189
  57. package/lib/core/configuration/whatsapp.cjs +76 -102
  58. package/lib/core/configuration/whatsapp.js +76 -105
  59. package/lib/core/configuration.cjs +60 -78
  60. package/lib/core/configuration.js +59 -78
  61. package/lib/core/event.cjs +36 -59
  62. package/lib/core/event.js +35 -61
  63. package/lib/core/sanitize_html.js +4 -4
  64. package/lib/errors/invalid_event.cjs +5 -26
  65. package/lib/errors/invalid_event.js +5 -26
  66. package/lib/errors/not_initialized_error.cjs +5 -26
  67. package/lib/errors/not_initialized_error.js +5 -26
  68. package/lib/hellotext.cjs +185 -223
  69. package/lib/hellotext.js +188 -247
  70. package/lib/index.js +1 -1
  71. package/lib/models/business.cjs +114 -152
  72. package/lib/models/business.js +117 -162
  73. package/lib/models/cookies.cjs +34 -51
  74. package/lib/models/cookies.js +34 -51
  75. package/lib/models/fingerprint.cjs +8 -23
  76. package/lib/models/fingerprint.js +25 -58
  77. package/lib/models/form.cjs +106 -142
  78. package/lib/models/form.js +105 -153
  79. package/lib/models/form_collection.cjs +63 -101
  80. package/lib/models/form_collection.js +61 -107
  81. package/lib/models/page.cjs +106 -129
  82. package/lib/models/page.js +106 -131
  83. package/lib/models/push.cjs +278 -322
  84. package/lib/models/push.js +284 -357
  85. package/lib/models/query.cjs +21 -41
  86. package/lib/models/query.js +21 -41
  87. package/lib/models/session.cjs +33 -65
  88. package/lib/models/session.js +30 -63
  89. package/lib/models/user.cjs +29 -51
  90. package/lib/models/user.js +29 -51
  91. package/lib/models/utm.cjs +15 -27
  92. package/lib/models/utm.js +17 -32
  93. package/lib/models/webchat.cjs +52 -76
  94. package/lib/models/webchat.js +52 -90
  95. package/lib/models/whatsapp_widget.cjs +41 -59
  96. package/lib/models/whatsapp_widget.js +41 -73
  97. package/lib/vanilla.cjs +4 -7
  98. package/lib/vanilla.js +2 -1
  99. package/package.json +1 -9
  100. package/src/index.bundle.js +0 -1
  101. package/src/vanilla.js +2 -1
  102. package/styles/index.css +0 -30
@@ -6,189 +6,144 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _application_channel = _interopRequireDefault(require("./application_channel"));
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
11
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
12
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
13
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
14
- function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
15
- function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
16
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
17
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
18
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
19
- function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
20
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
21
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
23
- let WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
24
- _inherits(WebchatChannel, _ApplicationChannel);
25
- var _super = _createSuper(WebchatChannel);
26
- function WebchatChannel(id, session, conversation) {
27
- var _this;
28
- _classCallCheck(this, WebchatChannel);
29
- _this = _super.call(this);
30
- _this.id = id;
31
- _this.session = session;
32
- _this.conversation = conversation;
9
+ class WebchatChannel extends _application_channel.default {
10
+ constructor(id, session, conversation) {
11
+ super();
12
+ this.id = id;
13
+ this.session = session;
14
+ this.conversation = conversation;
33
15
  // Keep our own subscription intent instead of trusting the socket state.
34
16
  // The shared WebSocket can reconnect independently, but an explicit
35
17
  // unsubscribe means this channel should not silently join again.
36
- _this.subscribed = false;
37
- _this.awaitingReconnectConfirmation = false;
38
- _this.reconnectCallbacks = new Set();
18
+ this.subscribed = false;
19
+ this.awaitingReconnectConfirmation = false;
20
+ this.reconnectCallbacks = new Set();
39
21
 
40
22
  // ActionCable confirms subscriptions at the socket level. This channel
41
23
  // listens for those confirmations so the controller can wait until Rails has
42
24
  // accepted this exact WebchatChannel subscription before fetching missed
43
25
  // messages from the REST catch-up endpoint.
44
- _this.onSubscriptionConfirmed(identifier => _this.handleSubscriptionConfirmed(identifier));
45
- _this.subscribe();
46
- return _this;
26
+ this.onSubscriptionConfirmed(identifier => this.handleSubscriptionConfirmed(identifier));
27
+ this.subscribe();
47
28
  }
48
- _createClass(WebchatChannel, [{
49
- key: "subscribe",
50
- value: function subscribe() {
51
- this.subscribed = true;
52
- const params = {
53
- channel: 'WebchatChannel',
54
- id: this.id,
55
- session: this.session,
56
- conversation: this.conversation
57
- };
58
- this.send({
59
- command: 'subscribe',
60
- identifier: params
61
- });
62
- }
63
- }, {
64
- key: "unsubscribe",
65
- value: function unsubscribe() {
66
- this.subscribed = false;
67
- const params = {
68
- channel: 'WebchatChannel',
69
- id: this.id,
70
- session: this.session,
71
- conversation: this.conversation
72
- };
73
- this.send({
74
- command: 'unsubscribe',
75
- identifier: params
76
- });
77
- }
78
- }, {
79
- key: "resubscribe",
80
- value: function resubscribe() {
81
- if (this.subscribed === false) return;
29
+ subscribe() {
30
+ this.subscribed = true;
31
+ const params = {
32
+ channel: 'WebchatChannel',
33
+ id: this.id,
34
+ session: this.session,
35
+ conversation: this.conversation
36
+ };
37
+ this.send({
38
+ command: 'subscribe',
39
+ identifier: params
40
+ });
41
+ }
42
+ unsubscribe() {
43
+ this.subscribed = false;
44
+ const params = {
45
+ channel: 'WebchatChannel',
46
+ id: this.id,
47
+ session: this.session,
48
+ conversation: this.conversation
49
+ };
50
+ this.send({
51
+ command: 'unsubscribe',
52
+ identifier: params
53
+ });
54
+ }
55
+ resubscribe() {
56
+ if (this.subscribed === false) return;
82
57
 
83
- // Reconnect recovery has two phases: send the subscription command first,
84
- // then wait for ActionCable to confirm it. Catch-up work should run after
85
- // that confirmation so broadcasts and REST backfill are pointed at the same
86
- // live conversation subscription.
87
- this.awaitingReconnectConfirmation = true;
88
- this.subscribe();
89
- }
90
- }, {
91
- key: "onReconnect",
92
- value: function onReconnect(callback) {
93
- this.reconnectCallbacks.add(callback);
94
- }
95
- }, {
96
- key: "handleSubscriptionConfirmed",
97
- value: function handleSubscriptionConfirmed(identifier) {
98
- if (!this.awaitingReconnectConfirmation || !this.matchesIdentifier(identifier)) return;
58
+ // Reconnect recovery has two phases: send the subscription command first,
59
+ // then wait for ActionCable to confirm it. Catch-up work should run after
60
+ // that confirmation so broadcasts and REST backfill are pointed at the same
61
+ // live conversation subscription.
62
+ this.awaitingReconnectConfirmation = true;
63
+ this.subscribe();
64
+ }
65
+ onReconnect(callback) {
66
+ this.reconnectCallbacks.add(callback);
67
+ }
68
+ handleSubscriptionConfirmed(identifier) {
69
+ if (!this.awaitingReconnectConfirmation || !this.matchesIdentifier(identifier)) return;
99
70
 
100
- // Only the first matching confirmation completes the reconnect cycle. This
101
- // prevents unrelated subscription confirmations on the shared socket from
102
- // triggering duplicate catch-up requests.
103
- this.awaitingReconnectConfirmation = false;
104
- this.reconnectCallbacks.forEach(callback => callback());
71
+ // Only the first matching confirmation completes the reconnect cycle. This
72
+ // prevents unrelated subscription confirmations on the shared socket from
73
+ // triggering duplicate catch-up requests.
74
+ this.awaitingReconnectConfirmation = false;
75
+ this.reconnectCallbacks.forEach(callback => callback());
76
+ }
77
+ matchesIdentifier(identifier) {
78
+ let params;
79
+ try {
80
+ params = typeof identifier === 'string' ? JSON.parse(identifier) : identifier;
81
+ } catch {
82
+ return false;
105
83
  }
106
- }, {
107
- key: "matchesIdentifier",
108
- value: function matchesIdentifier(identifier) {
109
- let params;
110
- try {
111
- params = typeof identifier === 'string' ? JSON.parse(identifier) : identifier;
112
- } catch {
113
- return false;
114
- }
115
84
 
116
- // ActionCable sends the same identifier payload we used when subscribing.
117
- // Matching every routing key keeps a confirmation for another webchat,
118
- // session, or conversation from being treated as this channel's reconnect.
119
- return params.channel === 'WebchatChannel' && params.id === this.id && params.session === this.session && params.conversation === this.conversation;
120
- }
121
- }, {
122
- key: "startTypingIndicator",
123
- value: function startTypingIndicator() {
124
- const params = {
125
- channel: 'WebchatChannel',
126
- id: this.id,
127
- session: this.session,
128
- conversation: this.conversation
129
- };
130
- this.send({
131
- command: 'message',
132
- identifier: params,
133
- data: {
134
- action: 'started_typing'
135
- }
136
- });
137
- }
138
- }, {
139
- key: "stopTypingIndicator",
140
- value: function stopTypingIndicator() {
141
- const params = {
142
- channel: 'WebchatChannel',
143
- id: this.id,
144
- session: this.session,
145
- conversation: this.conversation
146
- };
147
- this.send({
148
- command: 'typing:stop',
149
- identifier: params,
150
- data: {
151
- action: 'stopped_typing'
152
- }
153
- });
154
- }
155
- }, {
156
- key: "onMessage",
157
- value: function onMessage(callback) {
158
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
159
- if (message.type !== 'message') return;
85
+ // ActionCable sends the same identifier payload we used when subscribing.
86
+ // Matching every routing key keeps a confirmation for another webchat,
87
+ // session, or conversation from being treated as this channel's reconnect.
88
+ return params.channel === 'WebchatChannel' && params.id === this.id && params.session === this.session && params.conversation === this.conversation;
89
+ }
90
+ startTypingIndicator() {
91
+ const params = {
92
+ channel: 'WebchatChannel',
93
+ id: this.id,
94
+ session: this.session,
95
+ conversation: this.conversation
96
+ };
97
+ this.send({
98
+ command: 'message',
99
+ identifier: params,
100
+ data: {
101
+ action: 'started_typing'
102
+ }
103
+ });
104
+ }
105
+ stopTypingIndicator() {
106
+ const params = {
107
+ channel: 'WebchatChannel',
108
+ id: this.id,
109
+ session: this.session,
110
+ conversation: this.conversation
111
+ };
112
+ this.send({
113
+ command: 'typing:stop',
114
+ identifier: params,
115
+ data: {
116
+ action: 'stopped_typing'
117
+ }
118
+ });
119
+ }
120
+ onMessage(callback) {
121
+ super.onMessage(message => {
122
+ if (message.type !== 'message') return;
123
+ callback(message);
124
+ });
125
+ }
126
+ onReaction(callback) {
127
+ super.onMessage(message => {
128
+ if (message.type === 'reaction.create' || message.type === 'reaction.destroy') {
160
129
  callback(message);
161
- });
162
- }
163
- }, {
164
- key: "onReaction",
165
- value: function onReaction(callback) {
166
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
167
- if (message.type === 'reaction.create' || message.type === 'reaction.destroy') {
168
- callback(message);
169
- }
170
- });
171
- }
172
- }, {
173
- key: "onTypingStart",
174
- value: function onTypingStart(callback) {
175
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
176
- if (message.type === 'started_typing') {
177
- callback(message);
178
- }
179
- });
180
- }
181
- }, {
182
- key: "updateSubscriptionWith",
183
- value: function updateSubscriptionWith(conversation) {
184
- this.unsubscribe();
185
- setTimeout(() => {
186
- this.conversation = conversation;
187
- this.subscribe();
188
- }, 1000);
189
- }
190
- }]);
191
- return WebchatChannel;
192
- }(_application_channel.default);
130
+ }
131
+ });
132
+ }
133
+ onTypingStart(callback) {
134
+ super.onMessage(message => {
135
+ if (message.type === 'started_typing') {
136
+ callback(message);
137
+ }
138
+ });
139
+ }
140
+ updateSubscriptionWith(conversation) {
141
+ this.unsubscribe();
142
+ setTimeout(() => {
143
+ this.conversation = conversation;
144
+ this.subscribe();
145
+ }, 1000);
146
+ }
147
+ }
193
148
  var _default = WebchatChannel;
194
149
  exports.default = _default;
@@ -1,186 +1,141 @@
1
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
3
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
4
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
5
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
- function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
7
- function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
8
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
9
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
10
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
11
- function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
12
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
13
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
14
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
15
1
  import ApplicationChannel from './application_channel';
16
- var WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
17
- _inherits(WebchatChannel, _ApplicationChannel);
18
- var _super = _createSuper(WebchatChannel);
19
- function WebchatChannel(id, session, conversation) {
20
- var _this;
21
- _classCallCheck(this, WebchatChannel);
22
- _this = _super.call(this);
23
- _this.id = id;
24
- _this.session = session;
25
- _this.conversation = conversation;
2
+ class WebchatChannel extends ApplicationChannel {
3
+ constructor(id, session, conversation) {
4
+ super();
5
+ this.id = id;
6
+ this.session = session;
7
+ this.conversation = conversation;
26
8
  // Keep our own subscription intent instead of trusting the socket state.
27
9
  // The shared WebSocket can reconnect independently, but an explicit
28
10
  // unsubscribe means this channel should not silently join again.
29
- _this.subscribed = false;
30
- _this.awaitingReconnectConfirmation = false;
31
- _this.reconnectCallbacks = new Set();
11
+ this.subscribed = false;
12
+ this.awaitingReconnectConfirmation = false;
13
+ this.reconnectCallbacks = new Set();
32
14
 
33
15
  // ActionCable confirms subscriptions at the socket level. This channel
34
16
  // listens for those confirmations so the controller can wait until Rails has
35
17
  // accepted this exact WebchatChannel subscription before fetching missed
36
18
  // messages from the REST catch-up endpoint.
37
- _this.onSubscriptionConfirmed(identifier => _this.handleSubscriptionConfirmed(identifier));
38
- _this.subscribe();
39
- return _this;
19
+ this.onSubscriptionConfirmed(identifier => this.handleSubscriptionConfirmed(identifier));
20
+ this.subscribe();
40
21
  }
41
- _createClass(WebchatChannel, [{
42
- key: "subscribe",
43
- value: function subscribe() {
44
- this.subscribed = true;
45
- var params = {
46
- channel: 'WebchatChannel',
47
- id: this.id,
48
- session: this.session,
49
- conversation: this.conversation
50
- };
51
- this.send({
52
- command: 'subscribe',
53
- identifier: params
54
- });
55
- }
56
- }, {
57
- key: "unsubscribe",
58
- value: function unsubscribe() {
59
- this.subscribed = false;
60
- var params = {
61
- channel: 'WebchatChannel',
62
- id: this.id,
63
- session: this.session,
64
- conversation: this.conversation
65
- };
66
- this.send({
67
- command: 'unsubscribe',
68
- identifier: params
69
- });
70
- }
71
- }, {
72
- key: "resubscribe",
73
- value: function resubscribe() {
74
- if (this.subscribed === false) return;
22
+ subscribe() {
23
+ this.subscribed = true;
24
+ const params = {
25
+ channel: 'WebchatChannel',
26
+ id: this.id,
27
+ session: this.session,
28
+ conversation: this.conversation
29
+ };
30
+ this.send({
31
+ command: 'subscribe',
32
+ identifier: params
33
+ });
34
+ }
35
+ unsubscribe() {
36
+ this.subscribed = false;
37
+ const params = {
38
+ channel: 'WebchatChannel',
39
+ id: this.id,
40
+ session: this.session,
41
+ conversation: this.conversation
42
+ };
43
+ this.send({
44
+ command: 'unsubscribe',
45
+ identifier: params
46
+ });
47
+ }
48
+ resubscribe() {
49
+ if (this.subscribed === false) return;
75
50
 
76
- // Reconnect recovery has two phases: send the subscription command first,
77
- // then wait for ActionCable to confirm it. Catch-up work should run after
78
- // that confirmation so broadcasts and REST backfill are pointed at the same
79
- // live conversation subscription.
80
- this.awaitingReconnectConfirmation = true;
81
- this.subscribe();
82
- }
83
- }, {
84
- key: "onReconnect",
85
- value: function onReconnect(callback) {
86
- this.reconnectCallbacks.add(callback);
87
- }
88
- }, {
89
- key: "handleSubscriptionConfirmed",
90
- value: function handleSubscriptionConfirmed(identifier) {
91
- if (!this.awaitingReconnectConfirmation || !this.matchesIdentifier(identifier)) return;
51
+ // Reconnect recovery has two phases: send the subscription command first,
52
+ // then wait for ActionCable to confirm it. Catch-up work should run after
53
+ // that confirmation so broadcasts and REST backfill are pointed at the same
54
+ // live conversation subscription.
55
+ this.awaitingReconnectConfirmation = true;
56
+ this.subscribe();
57
+ }
58
+ onReconnect(callback) {
59
+ this.reconnectCallbacks.add(callback);
60
+ }
61
+ handleSubscriptionConfirmed(identifier) {
62
+ if (!this.awaitingReconnectConfirmation || !this.matchesIdentifier(identifier)) return;
92
63
 
93
- // Only the first matching confirmation completes the reconnect cycle. This
94
- // prevents unrelated subscription confirmations on the shared socket from
95
- // triggering duplicate catch-up requests.
96
- this.awaitingReconnectConfirmation = false;
97
- this.reconnectCallbacks.forEach(callback => callback());
64
+ // Only the first matching confirmation completes the reconnect cycle. This
65
+ // prevents unrelated subscription confirmations on the shared socket from
66
+ // triggering duplicate catch-up requests.
67
+ this.awaitingReconnectConfirmation = false;
68
+ this.reconnectCallbacks.forEach(callback => callback());
69
+ }
70
+ matchesIdentifier(identifier) {
71
+ let params;
72
+ try {
73
+ params = typeof identifier === 'string' ? JSON.parse(identifier) : identifier;
74
+ } catch {
75
+ return false;
98
76
  }
99
- }, {
100
- key: "matchesIdentifier",
101
- value: function matchesIdentifier(identifier) {
102
- var params;
103
- try {
104
- params = typeof identifier === 'string' ? JSON.parse(identifier) : identifier;
105
- } catch (_unused) {
106
- return false;
107
- }
108
77
 
109
- // ActionCable sends the same identifier payload we used when subscribing.
110
- // Matching every routing key keeps a confirmation for another webchat,
111
- // session, or conversation from being treated as this channel's reconnect.
112
- return params.channel === 'WebchatChannel' && params.id === this.id && params.session === this.session && params.conversation === this.conversation;
113
- }
114
- }, {
115
- key: "startTypingIndicator",
116
- value: function startTypingIndicator() {
117
- var params = {
118
- channel: 'WebchatChannel',
119
- id: this.id,
120
- session: this.session,
121
- conversation: this.conversation
122
- };
123
- this.send({
124
- command: 'message',
125
- identifier: params,
126
- data: {
127
- action: 'started_typing'
128
- }
129
- });
130
- }
131
- }, {
132
- key: "stopTypingIndicator",
133
- value: function stopTypingIndicator() {
134
- var params = {
135
- channel: 'WebchatChannel',
136
- id: this.id,
137
- session: this.session,
138
- conversation: this.conversation
139
- };
140
- this.send({
141
- command: 'typing:stop',
142
- identifier: params,
143
- data: {
144
- action: 'stopped_typing'
145
- }
146
- });
147
- }
148
- }, {
149
- key: "onMessage",
150
- value: function onMessage(callback) {
151
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
152
- if (message.type !== 'message') return;
78
+ // ActionCable sends the same identifier payload we used when subscribing.
79
+ // Matching every routing key keeps a confirmation for another webchat,
80
+ // session, or conversation from being treated as this channel's reconnect.
81
+ return params.channel === 'WebchatChannel' && params.id === this.id && params.session === this.session && params.conversation === this.conversation;
82
+ }
83
+ startTypingIndicator() {
84
+ const params = {
85
+ channel: 'WebchatChannel',
86
+ id: this.id,
87
+ session: this.session,
88
+ conversation: this.conversation
89
+ };
90
+ this.send({
91
+ command: 'message',
92
+ identifier: params,
93
+ data: {
94
+ action: 'started_typing'
95
+ }
96
+ });
97
+ }
98
+ stopTypingIndicator() {
99
+ const params = {
100
+ channel: 'WebchatChannel',
101
+ id: this.id,
102
+ session: this.session,
103
+ conversation: this.conversation
104
+ };
105
+ this.send({
106
+ command: 'typing:stop',
107
+ identifier: params,
108
+ data: {
109
+ action: 'stopped_typing'
110
+ }
111
+ });
112
+ }
113
+ onMessage(callback) {
114
+ super.onMessage(message => {
115
+ if (message.type !== 'message') return;
116
+ callback(message);
117
+ });
118
+ }
119
+ onReaction(callback) {
120
+ super.onMessage(message => {
121
+ if (message.type === 'reaction.create' || message.type === 'reaction.destroy') {
153
122
  callback(message);
154
- });
155
- }
156
- }, {
157
- key: "onReaction",
158
- value: function onReaction(callback) {
159
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
160
- if (message.type === 'reaction.create' || message.type === 'reaction.destroy') {
161
- callback(message);
162
- }
163
- });
164
- }
165
- }, {
166
- key: "onTypingStart",
167
- value: function onTypingStart(callback) {
168
- _get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
169
- if (message.type === 'started_typing') {
170
- callback(message);
171
- }
172
- });
173
- }
174
- }, {
175
- key: "updateSubscriptionWith",
176
- value: function updateSubscriptionWith(conversation) {
177
- this.unsubscribe();
178
- setTimeout(() => {
179
- this.conversation = conversation;
180
- this.subscribe();
181
- }, 1000);
182
- }
183
- }]);
184
- return WebchatChannel;
185
- }(ApplicationChannel);
123
+ }
124
+ });
125
+ }
126
+ onTypingStart(callback) {
127
+ super.onMessage(message => {
128
+ if (message.type === 'started_typing') {
129
+ callback(message);
130
+ }
131
+ });
132
+ }
133
+ updateSubscriptionWith(conversation) {
134
+ this.unsubscribe();
135
+ setTimeout(() => {
136
+ this.conversation = conversation;
137
+ this.subscribe();
138
+ }, 1000);
139
+ }
140
+ }
186
141
  export default WebchatChannel;