@areumtecnologia/wasockets 2.0.0 → 2.3.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 (75) hide show
  1. package/README.md +1987 -1649
  2. package/lib/Client/Builders/Buttons.js +127 -0
  3. package/lib/Client/Builders/EventBuilder.js +122 -0
  4. package/lib/Client/Builders/InteractiveMessage.js +150 -0
  5. package/lib/Client/Builders/Lists.js +78 -0
  6. package/lib/Client/Builders/PollBuilder.js +84 -0
  7. package/lib/Client/Builders/index.js +21 -0
  8. package/lib/Client/Constants.js +54 -0
  9. package/lib/Client/Context/CallContext.js +96 -0
  10. package/lib/Client/Context/MediaObject.js +155 -0
  11. package/lib/Client/Context/MessageContext.js +146 -0
  12. package/lib/Client/Modules/BusinessManager.js +155 -0
  13. package/lib/Client/Modules/ChannelManager.js +144 -0
  14. package/lib/Client/Modules/ChatManager.js +113 -0
  15. package/lib/Client/Modules/CommunityManager.js +136 -0
  16. package/lib/Client/Modules/GroupManager.js +194 -0
  17. package/lib/Client/Modules/LabelManager.js +123 -0
  18. package/lib/Client/Modules/MessageManager.js +198 -0
  19. package/lib/Client/Modules/PresenceManager.js +68 -0
  20. package/lib/Client/Modules/PrivacyManager.js +98 -0
  21. package/lib/Client/Modules/ProfileManager.js +92 -0
  22. package/lib/Client/Modules/UserManager.js +92 -0
  23. package/lib/Client/Modules/VoipManager.js +117 -0
  24. package/lib/Client/Modules/index.js +29 -0
  25. package/lib/Client/Normalizers/EventNormalizer.js +82 -0
  26. package/lib/Client/Normalizers/JidNormalizer.js +93 -0
  27. package/lib/Client/Normalizers/MessageNormalizer.js +134 -0
  28. package/lib/Client/WaClient.js +438 -0
  29. package/lib/Client/index.d.ts +464 -0
  30. package/lib/Client/index.js +76 -0
  31. package/lib/Defaults/baileys-version.json +1 -1
  32. package/lib/Defaults/connection.js +14 -1
  33. package/lib/Socket/index.js +51 -48
  34. package/lib/Socket/messages-recv.js +74 -13
  35. package/lib/Socket/messages-send.js +50 -25
  36. package/lib/Socket/socket.js +13 -0
  37. package/lib/Socket/voip.js +123 -0
  38. package/lib/Store/make-cache-manager-store.js +14 -5
  39. package/lib/Types/index.d.ts +4 -0
  40. package/lib/Utils/auth-utils.js +16 -1
  41. package/lib/Utils/browser-utils.js +6 -2
  42. package/lib/Utils/generics.js +47 -8
  43. package/lib/Utils/index.d.ts +1 -0
  44. package/lib/Utils/messages-media.js +44 -21
  45. package/lib/Utils/pre-key-manager.js +16 -1
  46. package/lib/Utils/validate-connection.js +10 -11
  47. package/lib/VoIP/VoIPCrypto.js +150 -0
  48. package/lib/VoIP/VoIPManager.js +469 -0
  49. package/lib/VoIP/VoIPMediaEngine.js +224 -0
  50. package/lib/VoIP/VoIPProtocol.js +354 -0
  51. package/lib/VoIP/VoIPRelayTransport.js +173 -0
  52. package/lib/VoIP/VoIPSession.js +314 -0
  53. package/lib/VoIP/assets/wasm/loader.js +5 -0
  54. package/lib/VoIP/assets/wasm/whatsapp.wasm +0 -0
  55. package/lib/VoIP/assets/wasm/worker-modules.js +305 -0
  56. package/lib/VoIP/engine/audio-feeder.d.mts +15 -0
  57. package/lib/VoIP/engine/audio-feeder.mjs +243 -0
  58. package/lib/VoIP/engine/index.d.mts +91 -0
  59. package/lib/VoIP/engine/index.mjs +1683 -0
  60. package/lib/VoIP/engine/relay-transport.d.mts +43 -0
  61. package/lib/VoIP/engine/relay-transport.mjs +607 -0
  62. package/lib/VoIP/engine/signaling.d.mts +44 -0
  63. package/lib/VoIP/engine/signaling.mjs +893 -0
  64. package/lib/VoIP/engine/types.d.mts +183 -0
  65. package/lib/VoIP/engine/types.mjs +17 -0
  66. package/lib/VoIP/engine/wasm-engine.d.mts +103 -0
  67. package/lib/VoIP/engine/wasm-engine.mjs +1397 -0
  68. package/lib/VoIP/engine/worker-bootstrap.mjs +1049 -0
  69. package/lib/VoIP/index.js +51 -0
  70. package/lib/VoIP/utils/audio.d.ts +28 -0
  71. package/lib/VoIP/utils/audio.js +148 -0
  72. package/lib/WABinary/generic-utils.js +22 -6
  73. package/lib/index.d.ts +382 -274
  74. package/lib/index.js +5 -0
  75. package/package.json +51 -49
@@ -0,0 +1,127 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ /**
6
+ * Quick Reply Button - user clicks and sends a predetermined text/id response
7
+ */
8
+ class QuickReplyButton {
9
+ constructor(displayText, id) {
10
+ this.displayText = displayText || ''
11
+ this.id = id || displayText || 'quick_reply'
12
+ }
13
+
14
+ build() {
15
+ return {
16
+ name: 'quick_reply',
17
+ buttonParamsJson: JSON.stringify({
18
+ display_text: this.displayText,
19
+ id: this.id
20
+ })
21
+ }
22
+ }
23
+ }
24
+
25
+ /**
26
+ * URL Button - user clicks and opens a webpage
27
+ */
28
+ class UrlButton {
29
+ constructor(displayText, url, merchantUrl) {
30
+ this.displayText = displayText || ''
31
+ this.url = url || ''
32
+ this.merchantUrl = merchantUrl || url || ''
33
+ }
34
+
35
+ build() {
36
+ return {
37
+ name: 'cta_url',
38
+ buttonParamsJson: JSON.stringify({
39
+ display_text: this.displayText,
40
+ url: this.url,
41
+ merchant_url: this.merchantUrl
42
+ })
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Copy Code Button - user clicks to copy a coupon/token to clipboard
49
+ */
50
+ class CopyCodeButton {
51
+ constructor(displayText, copyCode, id) {
52
+ this.displayText = displayText || ''
53
+ this.copyCode = copyCode || ''
54
+ this.id = id || 'copy_code'
55
+ }
56
+
57
+ build() {
58
+ return {
59
+ name: 'cta_copy',
60
+ buttonParamsJson: JSON.stringify({
61
+ display_text: this.displayText,
62
+ id: this.id,
63
+ copy_code: this.copyCode
64
+ })
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Call Button - user clicks to initiate a standard voice call
71
+ */
72
+ class CallButton {
73
+ constructor(displayText, phoneNumber) {
74
+ this.displayText = displayText || ''
75
+ this.phoneNumber = phoneNumber || ''
76
+ }
77
+
78
+ build() {
79
+ return {
80
+ name: 'cta_call',
81
+ buttonParamsJson: JSON.stringify({
82
+ display_text: this.displayText,
83
+ phone_number: this.phoneNumber
84
+ })
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Native PIX Payment Button (WhatsApp Payment Info)
91
+ */
92
+ class PixButton {
93
+ /**
94
+ * @param {string} displayText - Text displayed on button (e.g., 'Pagar com PIX')
95
+ * @param {string} pixKey - Chave PIX (CPF/CNPJ, Email, Telefone ou EVP)
96
+ * @param {string} [keyType='CPF'] - Tipo da chave: 'CPF', 'EMAIL', 'PHONE', 'EVP'
97
+ * @param {string} [merchantName='Comerciante'] - Nome do beneficiário exibido
98
+ */
99
+ constructor(displayText, pixKey, keyType = 'CPF', merchantName = 'Comerciante') {
100
+ this.displayText = displayText || 'Pagar via PIX'
101
+ this.pixKey = pixKey || ''
102
+ this.keyType = (keyType || 'CPF').toUpperCase()
103
+ this.merchantName = merchantName || 'Comerciante'
104
+ }
105
+
106
+ build() {
107
+ return {
108
+ name: 'payment_info',
109
+ buttonParamsJson: JSON.stringify({
110
+ payment_settings: [{
111
+ type: 'pix_static_code',
112
+ pix_static_code: {
113
+ merchant_name: this.merchantName,
114
+ key: this.pixKey,
115
+ key_type: this.keyType
116
+ }
117
+ }]
118
+ })
119
+ }
120
+ }
121
+ }
122
+
123
+ exports.QuickReplyButton = QuickReplyButton
124
+ exports.UrlButton = UrlButton
125
+ exports.CopyCodeButton = CopyCodeButton
126
+ exports.CallButton = CallButton
127
+ exports.PixButton = PixButton
@@ -0,0 +1,122 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ /**
6
+ * Fluent builder for WhatsApp Calendar / Group Event Messages
7
+ */
8
+ class EventBuilder {
9
+ constructor() {
10
+ this._name = ''
11
+ this._description = ''
12
+ this._startTime = null
13
+ this._endTime = null
14
+ this._location = null
15
+ this._call = null
16
+ }
17
+
18
+ /**
19
+ * Sets event title
20
+ * @param {string} name
21
+ * @returns {this}
22
+ */
23
+ setName(name) {
24
+ this._name = name || ''
25
+ return this
26
+ }
27
+
28
+ /**
29
+ * Sets event description
30
+ * @param {string} description
31
+ * @returns {this}
32
+ */
33
+ setDescription(description) {
34
+ this._description = description || ''
35
+ return this
36
+ }
37
+
38
+ /**
39
+ * Sets start time as Date, timestamp in seconds or milliseconds
40
+ * @param {Date|number} date
41
+ * @returns {this}
42
+ */
43
+ setStartDate(date) {
44
+ if (date instanceof Date) {
45
+ this._startTime = Math.floor(date.getTime() / 1000)
46
+ } else if (typeof date === 'number') {
47
+ this._startTime = date > 10000000000 ? Math.floor(date / 1000) : Math.floor(date)
48
+ }
49
+ return this
50
+ }
51
+
52
+ /**
53
+ * Sets end time as Date, timestamp in seconds or milliseconds
54
+ * @param {Date|number} date
55
+ * @returns {this}
56
+ */
57
+ setEndDate(date) {
58
+ if (date instanceof Date) {
59
+ this._endTime = Math.floor(date.getTime() / 1000)
60
+ } else if (typeof date === 'number') {
61
+ this._endTime = date > 10000000000 ? Math.floor(date / 1000) : Math.floor(date)
62
+ }
63
+ return this
64
+ }
65
+
66
+ /**
67
+ * Sets event location
68
+ * @param {string} name - Location name
69
+ * @param {number} [degreesLatitude]
70
+ * @param {number} [degreesLongitude]
71
+ * @returns {this}
72
+ */
73
+ setLocation(name, degreesLatitude, degreesLongitude) {
74
+ this._location = {
75
+ name: name || '',
76
+ degreesLatitude: degreesLatitude || 0,
77
+ degreesLongitude: degreesLongitude || 0
78
+ }
79
+ return this
80
+ }
81
+
82
+ /**
83
+ * Sets WhatsApp voice or video call for the event
84
+ * @param {'voice'|'video'|1|2} callType
85
+ * @returns {this}
86
+ */
87
+ setCall(callType = 'voice') {
88
+ this._call = {
89
+ callType: callType === 'video' || callType === 2 ? 2 : 1
90
+ }
91
+ return this
92
+ }
93
+
94
+ /**
95
+ * Compiles event into a payload ready for sendMessage()
96
+ * @returns {Object}
97
+ */
98
+ build() {
99
+ if (!this._name) {
100
+ throw new Error('EventBuilder requires an event title via setName().')
101
+ }
102
+
103
+ const nowSec = Math.floor(Date.now() / 1000)
104
+ const startTime = this._startTime || (nowSec + 3600) // Default 1 hour from now
105
+
106
+ const eventPayload = {
107
+ name: this._name,
108
+ description: this._description || undefined,
109
+ startTime,
110
+ endTime: this._endTime || undefined,
111
+ location: this._location || undefined,
112
+ call: this._call || undefined
113
+ }
114
+
115
+ return {
116
+ event: eventPayload
117
+ }
118
+ }
119
+ }
120
+
121
+ exports.EventBuilder = EventBuilder
122
+ exports.default = EventBuilder
@@ -0,0 +1,150 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ const { ListButton } = require("./Lists")
6
+
7
+ /**
8
+ * Fluent builder for Interactive WhatsApp Messages (Buttons, Cards, Menus, PIX)
9
+ */
10
+ class InteractiveMessage {
11
+ constructor() {
12
+ this._title = ''
13
+ this._subtitle = ''
14
+ this._text = ''
15
+ this._footer = ''
16
+ this._header = null
17
+ this._buttons = []
18
+ }
19
+
20
+ /**
21
+ * Sets card title
22
+ * @param {string} title
23
+ * @returns {this}
24
+ */
25
+ setTitle(title) {
26
+ this._title = title || ''
27
+ return this
28
+ }
29
+
30
+ /**
31
+ * Sets subtitle or secondary header
32
+ * @param {string} subtitle
33
+ * @returns {this}
34
+ */
35
+ setSubtitle(subtitle) {
36
+ this._subtitle = subtitle || ''
37
+ return this
38
+ }
39
+
40
+ /**
41
+ * Sets the main text body (required)
42
+ * @param {string} text
43
+ * @returns {this}
44
+ */
45
+ setText(text) {
46
+ this._text = text || ''
47
+ return this
48
+ }
49
+
50
+ /**
51
+ * Sets smaller footer text at the bottom
52
+ * @param {string} footer
53
+ * @returns {this}
54
+ */
55
+ setFooter(footer) {
56
+ this._footer = footer || ''
57
+ return this
58
+ }
59
+
60
+ /**
61
+ * Sets an image header for the interactive card
62
+ * @param {string|Buffer|{ url: string }} image
63
+ * @returns {this}
64
+ */
65
+ setHeaderImage(image) {
66
+ this._header = {
67
+ image: typeof image === 'string' ? { url: image } : image
68
+ }
69
+ return this
70
+ }
71
+
72
+ /**
73
+ * Sets a video header for the interactive card
74
+ * @param {string|Buffer|{ url: string }} video
75
+ * @returns {this}
76
+ */
77
+ setHeaderVideo(video) {
78
+ this._header = {
79
+ video: typeof video === 'string' ? { url: video } : video
80
+ }
81
+ return this
82
+ }
83
+
84
+ /**
85
+ * Adds an interactive button (QuickReply, Url, CopyCode, Call, Pix or ListButton)
86
+ * @param {Object} button
87
+ * @returns {this}
88
+ */
89
+ addButton(button) {
90
+ if (button) {
91
+ this._buttons.push(button)
92
+ }
93
+ return this
94
+ }
95
+
96
+ /**
97
+ * Adds multiple buttons at once
98
+ * @param {Array<Object>} buttons
99
+ * @returns {this}
100
+ */
101
+ addButtons(buttons) {
102
+ if (Array.isArray(buttons)) {
103
+ for (const b of buttons) {
104
+ this.addButton(b)
105
+ }
106
+ }
107
+ return this
108
+ }
109
+
110
+ /**
111
+ * Compiles the interactive message into a payload ready for sock.sendMessage()
112
+ * @returns {Object}
113
+ */
114
+ build() {
115
+ if (!this._text && !this._title) {
116
+ throw new Error('InteractiveMessage requires at least a text or title.')
117
+ }
118
+
119
+ // Check if there is a ListButton
120
+ const listBtn = this._buttons.find(b => b instanceof ListButton || b.sections)
121
+
122
+ if (listBtn) {
123
+ const builtList = typeof listBtn.build === 'function' ? listBtn.build() : listBtn
124
+ return {
125
+ text: this._text,
126
+ title: this._title || undefined,
127
+ subtitle: this._subtitle || undefined,
128
+ footer: this._footer || undefined,
129
+ buttonText: builtList.buttonText,
130
+ sections: builtList.sections,
131
+ ...(this._header || {})
132
+ }
133
+ }
134
+
135
+ // Standard interactive buttons
136
+ return {
137
+ text: this._text,
138
+ title: this._title || undefined,
139
+ subtitle: this._subtitle || undefined,
140
+ footer: this._footer || undefined,
141
+ ...(this._header || {}),
142
+ interactiveButtons: this._buttons.map(btn => (
143
+ typeof btn.build === 'function' ? btn.build() : btn
144
+ ))
145
+ }
146
+ }
147
+ }
148
+
149
+ exports.InteractiveMessage = InteractiveMessage
150
+ exports.default = InteractiveMessage
@@ -0,0 +1,78 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ /**
6
+ * Individual row in an interactive list section
7
+ */
8
+ class ListRow {
9
+ constructor(title, description = '', rowId = '') {
10
+ this.title = title || ''
11
+ this.description = description || ''
12
+ this.rowId = rowId || title || 'row'
13
+ }
14
+
15
+ build() {
16
+ return {
17
+ title: this.title,
18
+ description: this.description,
19
+ rowId: this.rowId
20
+ }
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Categorized section containing multiple rows
26
+ */
27
+ class ListSection {
28
+ constructor(title, rows = []) {
29
+ this.title = title || ''
30
+ this.rows = Array.isArray(rows) ? rows : []
31
+ }
32
+
33
+ addRow(titleOrRow, description, rowId) {
34
+ if (titleOrRow instanceof ListRow) {
35
+ this.rows.push(titleOrRow)
36
+ } else {
37
+ this.rows.push(new ListRow(titleOrRow, description, rowId))
38
+ }
39
+ return this
40
+ }
41
+
42
+ build() {
43
+ return {
44
+ title: this.title,
45
+ rows: this.rows.map(row => typeof row.build === 'function' ? row.build() : row)
46
+ }
47
+ }
48
+ }
49
+
50
+ /**
51
+ * List Dropdown Button configuration
52
+ */
53
+ class ListButton {
54
+ constructor(buttonText, sections = []) {
55
+ this.buttonText = buttonText || 'Ver Opções'
56
+ this.sections = Array.isArray(sections) ? sections : []
57
+ }
58
+
59
+ addSection(titleOrSection, rows) {
60
+ if (titleOrSection instanceof ListSection) {
61
+ this.sections.push(titleOrSection)
62
+ } else {
63
+ this.sections.push(new ListSection(titleOrSection, rows))
64
+ }
65
+ return this
66
+ }
67
+
68
+ build() {
69
+ return {
70
+ buttonText: this.buttonText,
71
+ sections: this.sections.map(sec => typeof sec.build === 'function' ? sec.build() : sec)
72
+ }
73
+ }
74
+ }
75
+
76
+ exports.ListRow = ListRow
77
+ exports.ListSection = ListSection
78
+ exports.ListButton = ListButton
@@ -0,0 +1,84 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ /**
6
+ * Fluent builder for WhatsApp Polls
7
+ */
8
+ class PollBuilder {
9
+ constructor() {
10
+ this._name = ''
11
+ this._options = []
12
+ this._selectableCount = 1
13
+ }
14
+
15
+ /**
16
+ * Sets poll question / title
17
+ * @param {string} name
18
+ * @returns {this}
19
+ */
20
+ setName(name) {
21
+ this._name = name || ''
22
+ return this
23
+ }
24
+
25
+ /**
26
+ * Adds an option to the poll
27
+ * @param {string} option
28
+ * @returns {this}
29
+ */
30
+ addOption(option) {
31
+ if (option && typeof option === 'string') {
32
+ this._options.push(option.trim())
33
+ }
34
+ return this
35
+ }
36
+
37
+ /**
38
+ * Adds multiple options to the poll
39
+ * @param {Array<string>} options
40
+ * @returns {this}
41
+ */
42
+ addOptions(options) {
43
+ if (Array.isArray(options)) {
44
+ for (const opt of options) {
45
+ this.addOption(opt)
46
+ }
47
+ }
48
+ return this
49
+ }
50
+
51
+ /**
52
+ * Sets how many options can be selected (1 for single choice, > 1 for multiple choices)
53
+ * @param {number} count
54
+ * @returns {this}
55
+ */
56
+ setSelectableCount(count) {
57
+ this._selectableCount = Math.max(1, Number(count) || 1)
58
+ return this
59
+ }
60
+
61
+ /**
62
+ * Compiles poll into a payload for sendMessage()
63
+ * @returns {Object}
64
+ */
65
+ build() {
66
+ if (!this._name) {
67
+ throw new Error('PollBuilder requires a question name via setName().')
68
+ }
69
+ if (this._options.length < 2) {
70
+ throw new Error('PollBuilder requires at least 2 options.')
71
+ }
72
+
73
+ return {
74
+ poll: {
75
+ name: this._name,
76
+ values: this._options,
77
+ selectableCount: this._selectableCount
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ exports.PollBuilder = PollBuilder
84
+ exports.default = PollBuilder
@@ -0,0 +1,21 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ const { InteractiveMessage } = require("./InteractiveMessage")
6
+ const { QuickReplyButton, UrlButton, CopyCodeButton, CallButton, PixButton } = require("./Buttons")
7
+ const { ListButton, ListSection, ListRow } = require("./Lists")
8
+ const { PollBuilder } = require("./PollBuilder")
9
+ const { EventBuilder } = require("./EventBuilder")
10
+
11
+ exports.InteractiveMessage = InteractiveMessage
12
+ exports.QuickReplyButton = QuickReplyButton
13
+ exports.UrlButton = UrlButton
14
+ exports.CopyCodeButton = CopyCodeButton
15
+ exports.CallButton = CallButton
16
+ exports.PixButton = PixButton
17
+ exports.ListButton = ListButton
18
+ exports.ListSection = ListSection
19
+ exports.ListRow = ListRow
20
+ exports.PollBuilder = PollBuilder
21
+ exports.EventBuilder = EventBuilder
@@ -0,0 +1,54 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ /**
6
+ * High-level semantic event names for WaClient
7
+ */
8
+ const Events = Object.freeze({
9
+ // Connection Lifecycle
10
+ STATUS_CHANGE: 'status.change',
11
+ QR_CODE: 'qr',
12
+ PAIRING_CODE: 'pairing.code',
13
+ CONNECTED: 'connected',
14
+ DISCONNECTED: 'disconnected',
15
+ LOGGED_OUT: 'logged.out',
16
+
17
+ // Messages
18
+ MESSAGE_RECEIVED: 'message.received',
19
+ MESSAGE_SENT: 'message.sent',
20
+ MESSAGE_UPDATE: 'message.update',
21
+ MESSAGE_DELETE: 'message.delete',
22
+
23
+ // Presence & Contacts
24
+ PRESENCE_UPDATE: 'presence.update',
25
+ CONTACTS_UPSERT: 'contacts.upsert',
26
+
27
+ // VoIP & Calls
28
+ CALL_INCOMING: 'call.incoming',
29
+ CALL_STATUS: 'call.status',
30
+
31
+ // Group & Community Events
32
+ GROUP_PARTICIPANTS_UPDATE: 'group.participants.update',
33
+
34
+ // Generic Error
35
+ ERROR: 'error'
36
+ })
37
+
38
+ /**
39
+ * Connection states for WaClient state machine
40
+ */
41
+ const ConnectionStatus = Object.freeze({
42
+ IDLE: 'idle',
43
+ INITIALIZING: 'initializing',
44
+ CONNECTING: 'connecting',
45
+ QR_READY: 'qr_ready',
46
+ PAIRING_READY: 'pairing_ready',
47
+ CONNECTED: 'connected',
48
+ RECONNECTING: 'reconnecting',
49
+ LOGGED_OUT: 'logged_out',
50
+ DISCONNECTED: 'disconnected'
51
+ })
52
+
53
+ exports.Events = Events
54
+ exports.ConnectionStatus = ConnectionStatus