@cometchat/calls-sdk-react-native 4.4.2-beta.1 → 5.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +85 -19
  2. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  4. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  5. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  6. package/android/.gradle/8.9/gc.properties +0 -0
  7. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  8. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  9. package/android/.gradle/vcs-1/gc.properties +0 -0
  10. package/android/build.gradle +13 -12
  11. package/android/src/main/AndroidManifest.xml +15 -6
  12. package/android/src/main/java/com/callingv5/AudioDeviceHandlerConnectionService.java +185 -0
  13. package/android/src/main/java/com/callingv5/AudioDeviceHandlerGeneric.java +254 -0
  14. package/android/src/main/java/com/{CometChatCalls → callingv5}/AudioModeModule.java +93 -56
  15. package/android/src/main/java/com/callingv5/ConnectionService.java +451 -0
  16. package/android/src/main/java/com/callingv5/KeepAwakeModule.java +53 -0
  17. package/android/src/main/java/com/callingv5/MyAppPackage.java +35 -0
  18. package/android/src/main/java/com/callingv5/RNConnectionService.java +244 -0
  19. package/android/src/main/java/com/callingv5/ToastModule.java +29 -0
  20. package/android/src/main/java/com/callingv5/utils/CometChatLogger.java +88 -0
  21. package/cometchat-calls-sdk-react-native.podspec +9 -10
  22. package/dist/index.d.mts +4066 -0
  23. package/dist/index.d.ts +4066 -9
  24. package/dist/index.js +11116 -132
  25. package/dist/index.js.map +1 -0
  26. package/dist/index.mjs +11085 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/polyfills/RTCPeerConnection.js +19 -0
  29. package/dist/polyfills/Storage.js +192 -0
  30. package/dist/polyfills/browser.js +337 -0
  31. package/dist/polyfills/index.js +1 -0
  32. package/dist/polyfills/ipv6utils.js +197 -0
  33. package/dist/polyfills/webrtc.js +11 -0
  34. package/ios/{JitsiAudioSession+Private.h → Audio/CometChatAudioSession+Private.h} +2 -3
  35. package/ios/{LogUtils.h → Audio/CometChatAudioSession.h} +9 -6
  36. package/ios/{JitsiAudioSession.m → Audio/CometChatAudioSession.m} +4 -3
  37. package/ios/{AudioMode.m → Modules/AudioMode.m} +15 -49
  38. package/ios/Modules/KeepAwake.h +4 -0
  39. package/ios/Modules/KeepAwake.m +29 -0
  40. package/package.json +24 -110
  41. package/LICENSE.md +0 -3
  42. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerGeneric.java +0 -213
  43. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerLegacy.java +0 -213
  44. package/android/src/main/java/com/CometChatCalls/BluetoothHeadsetMonitor.java +0 -187
  45. package/android/src/main/java/com/CometChatCalls/CallNotificationService.java +0 -93
  46. package/android/src/main/java/com/CometChatCalls/CallNotificationServiceModule.java +0 -48
  47. package/android/src/main/java/com/CometChatCalls/CometChatCallsPackage.java +0 -56
  48. package/android/src/main/java/com/CometChatCalls/CometChatCommonModule.java +0 -48
  49. package/android/src/main/java/com/CometChatCalls/PictureInPictureModule.java +0 -133
  50. package/android/src/main/res/drawable-mdpi/callingcomponent_icons_headphones_pluged.png +0 -0
  51. package/dist/CometChatErrorConstants.d.ts +0 -124
  52. package/dist/Constants.d.ts +0 -724
  53. package/dist/Helper copy.d.ts +0 -1
  54. package/dist/Helper.d.ts +0 -7
  55. package/dist/api/APIHandler.d.ts +0 -42
  56. package/dist/api/endpoints.d.ts +0 -7
  57. package/dist/api/helper.d.ts +0 -69
  58. package/dist/api/index.d.ts +0 -2
  59. package/dist/constants/CallConstants.d.ts +0 -136
  60. package/dist/constants/index.d.ts +0 -1
  61. package/dist/defaultCallsettings.d.ts +0 -2
  62. package/dist/models/CallAppSettings.d.ts +0 -42
  63. package/dist/models/CallGroup.d.ts +0 -14
  64. package/dist/models/CallLog.d.ts +0 -276
  65. package/dist/models/CallLogFilterParams.d.ts +0 -97
  66. package/dist/models/CallSettings.d.ts +0 -330
  67. package/dist/models/CallUser.d.ts +0 -14
  68. package/dist/models/CometChatCallLogs.d.ts +0 -193
  69. package/dist/models/CometChatCalls.d.ts +0 -110
  70. package/dist/models/CometChatCallsComponent.d.ts +0 -13
  71. package/dist/models/CometChatCallsComponentCore.d.ts +0 -18
  72. package/dist/models/CometChatCallsException.d.ts +0 -7
  73. package/dist/models/CometChatPresenterComponent.d.ts +0 -13
  74. package/dist/models/ErrorModel.d.ts +0 -11
  75. package/dist/models/Listner.d.ts +0 -69
  76. package/dist/models/ListnerHandler.d.ts +0 -10
  77. package/dist/models/MessageComponent.d.ts +0 -7
  78. package/dist/models/Participant.d.ts +0 -184
  79. package/dist/models/PresenterSettings.d.ts +0 -208
  80. package/dist/models/RTCUser.d.ts +0 -18
  81. package/dist/models/Recording.d.ts +0 -86
  82. package/dist/models/index.d.ts +0 -9
  83. package/dist/types/ICallAppSettings.d.ts +0 -6
  84. package/dist/types/ICallSettings.d.ts +0 -61
  85. package/dist/types/RTCUser.d.ts +0 -6
  86. package/dist/types/callEvents.d.ts +0 -54
  87. package/dist/types/common.d.ts +0 -18
  88. package/dist/types/index.d.ts +0 -2
  89. package/ios/AudioMode.h +0 -11
  90. package/ios/CometChatCommonModule.h +0 -6
  91. package/ios/CometChatCommonModule.m +0 -29
  92. package/ios/JitsiAudioSession.h +0 -17
  93. package/ios/react-native-calls2.xcodeproj/project.pbxproj +0 -269
@@ -0,0 +1,19 @@
1
+ import { RTCPeerConnection as PC } from 'react-native-webrtc';
2
+
3
+ import { synthesizeIPv6Addresses } from './ipv6utils';
4
+
5
+ /**
6
+ * Override PeerConnection to synthesize IPv6 addresses.
7
+ */
8
+ export default class RTCPeerConnection extends PC {
9
+
10
+ /**
11
+ * Synthesize IPv6 addresses before calling the underlying setRemoteDescription.
12
+ *
13
+ * @param {Object} description - SDP.
14
+ * @returns {Promise<undefined>} A promise which is resolved once the operation is complete.
15
+ */
16
+ async setRemoteDescription(description) {
17
+ return super.setRemoteDescription(await synthesizeIPv6Addresses(description));
18
+ }
19
+ }
@@ -0,0 +1,192 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+
3
+ /**
4
+ * A Web Sorage API implementation used for polyfilling
5
+ * {@code window.localStorage} and/or {@code window.sessionStorage}.
6
+ * <p>
7
+ * The Web Storage API is synchronous whereas React Native's builtin generic
8
+ * storage API {@code AsyncStorage} is asynchronous so the implementation with
9
+ * persistence is optimistic: it will first store the value locally in memory so
10
+ * that results can be served synchronously and then persist the value
11
+ * asynchronously. If an asynchronous operation produces an error, it's ignored.
12
+ */
13
+ export default class Storage {
14
+ /**
15
+ * Initializes a new {@code Storage} instance. Loads all previously
16
+ * persisted data items from React Native's {@code AsyncStorage} if
17
+ * necessary.
18
+ *
19
+ * @param {string|undefined} keyPrefix - The prefix of the
20
+ * {@code AsyncStorage} keys to be persisted by this storage.
21
+ */
22
+ constructor(keyPrefix) {
23
+ /**
24
+ * The prefix of the {@code AsyncStorage} keys persisted by this
25
+ * storage. If {@code undefined}, then the data items stored in this
26
+ * storage will not be persisted.
27
+ *
28
+ * @private
29
+ * @type {string}
30
+ */
31
+ this._keyPrefix = keyPrefix;
32
+
33
+ // Perform optional asynchronous initialization.
34
+ const initializing = this._initializeAsync();
35
+
36
+ if (initializing) {
37
+ // Indicate that asynchronous initialization is under way.
38
+ this._initializing = initializing;
39
+
40
+ // When the asynchronous initialization completes, indicate its
41
+ // completion.
42
+ initializing.finally(() => {
43
+ if (this._initializing === initializing) {
44
+ this._initializing = undefined;
45
+ }
46
+ });
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Removes all keys from this storage.
52
+ *
53
+ * @returns {void}
54
+ */
55
+ clear() {
56
+ for (const key of Object.keys(this)) {
57
+ this.removeItem(key);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Returns the value associated with a specific key in this storage.
63
+ *
64
+ * @param {string} key - The name of the key to retrieve the value of.
65
+ * @returns {string|null} The value associated with {@code key} or
66
+ * {@code null}.
67
+ */
68
+ getItem(key) {
69
+ return this.hasOwnProperty(key) ? this[key] : null;
70
+ }
71
+
72
+ /**
73
+ * Returns the value associated with a specific key in this {@code Storage}
74
+ * in an async manner. The method is required for the cases where we need
75
+ * the stored data but we're not sure yet whether this {@code Storage} is
76
+ * already initialized (e.g. On app start).
77
+ *
78
+ * @param {string} key - The name of the key to retrieve the value of.
79
+ * @returns {Promise}
80
+ */
81
+ _getItemAsync(key) {
82
+ return (
83
+ (this._initializing || Promise.resolve())
84
+ .catch(() => { /* _getItemAsync should always resolve! */ })
85
+ .then(() => this.getItem(key)));
86
+ }
87
+
88
+ /**
89
+ * Performs asynchronous initialization of this {@code Storage} instance
90
+ * such as loading all keys from {@link AsyncStorage}.
91
+ *
92
+ * @private
93
+ * @returns {Promise}
94
+ */
95
+ _initializeAsync() {
96
+ if (typeof this._keyPrefix !== 'undefined') {
97
+ // Load all previously persisted data items from React Native's
98
+ // AsyncStorage.
99
+
100
+ return new Promise(resolve => {
101
+ AsyncStorage.getAllKeys().then((...getAllKeysCallbackArgs) => {
102
+ // XXX The keys argument of getAllKeys' callback may or may
103
+ // not be preceded by an error argument.
104
+ const keys
105
+ = getAllKeysCallbackArgs[
106
+ getAllKeysCallbackArgs.length - 1
107
+ ].filter(key => key.startsWith(this._keyPrefix));
108
+
109
+ AsyncStorage.multiGet(keys)
110
+ .then((...multiGetCallbackArgs) => {
111
+ // XXX The result argument of multiGet may or may not be
112
+ // preceded by an errors argument.
113
+ const result
114
+ = multiGetCallbackArgs[
115
+ multiGetCallbackArgs.length - 1
116
+ ];
117
+ const keyPrefixLength
118
+ = this._keyPrefix && this._keyPrefix.length;
119
+
120
+ // eslint-disable-next-line prefer-const
121
+ for (let [ key, value ] of result) {
122
+ key = key.substring(keyPrefixLength);
123
+
124
+ // XXX The loading of the previously persisted data
125
+ // items from AsyncStorage is asynchronous which
126
+ // means that it is technically possible to invoke
127
+ // setItem with a key before the key is loaded from
128
+ // AsyncStorage.
129
+ if (!this.hasOwnProperty(key)) {
130
+ this[key] = value;
131
+ }
132
+ }
133
+
134
+ resolve();
135
+ });
136
+ });
137
+ });
138
+ }
139
+
140
+ return undefined;
141
+ }
142
+
143
+ /**
144
+ * Returns the name of the nth key in this storage.
145
+ *
146
+ * @param {number} n - The zero-based integer index of the key to get the
147
+ * name of.
148
+ * @returns {string} The name of the nth key in this storage.
149
+ */
150
+ key(n) {
151
+ const keys = Object.keys(this);
152
+
153
+ return n < keys.length ? keys[n] : null;
154
+ }
155
+
156
+ /**
157
+ * Returns an integer representing the number of data items stored in this
158
+ * storage.
159
+ *
160
+ * @returns {number}
161
+ */
162
+ get length() {
163
+ return Object.keys(this).length;
164
+ }
165
+
166
+ /**
167
+ * Removes a specific key from this storage.
168
+ *
169
+ * @param {string} key - The name of the key to remove.
170
+ * @returns {void}
171
+ */
172
+ removeItem(key) {
173
+ delete this[key];
174
+ typeof this._keyPrefix === 'undefined'
175
+ || AsyncStorage.removeItem(`${String(this._keyPrefix)}${key}`);
176
+ }
177
+
178
+ /**
179
+ * Adds a specific key to this storage and associates it with a specific
180
+ * value. If the key exists already, updates its value.
181
+ *
182
+ * @param {string} key - The name of the key to add/update.
183
+ * @param {string} value - The value to associate with {@code key}.
184
+ * @returns {void}
185
+ */
186
+ setItem(key, value) {
187
+ value = String(value); // eslint-disable-line no-param-reassign
188
+ this[key] = value;
189
+ typeof this._keyPrefix === 'undefined'
190
+ || AsyncStorage.setItem(`${String(this._keyPrefix)}${key}`, value);
191
+ }
192
+ }
@@ -0,0 +1,337 @@
1
+ import { DOMParser } from '@xmldom/xmldom';
2
+ import { atob, btoa } from 'abab';
3
+ import { Platform } from 'react-native';
4
+ import BackgroundTimer from 'react-native-background-timer';
5
+ import { TextDecoder, TextEncoder } from 'text-encoding';
6
+
7
+ import 'promise.allsettled/auto'; // Promise.allSettled.
8
+ import 'react-native-url-polyfill/auto'; // Complete URL polyfill.
9
+
10
+ import Storage from './Storage';
11
+
12
+ /**
13
+ * Implements an absolute minimum of the common logic of
14
+ * {@code Document.querySelector} and {@code Element.querySelector}. Implements
15
+ * the most simple of selectors necessary to satisfy the call sites at the time
16
+ * of this writing (i.e. Select by tagName).
17
+ *
18
+ * @param {Node} node - The Node which is the root of the tree to query.
19
+ * @param {string} selectors - The group of CSS selectors to match on.
20
+ * @returns {Element} - The first Element which is a descendant of the specified
21
+ * node and matches the specified group of selectors.
22
+ */
23
+ function _querySelector(node, selectors) {
24
+ let element = null;
25
+
26
+ node && _visitNode(node, n => {
27
+ if (n.nodeType === 1 /* ELEMENT_NODE */
28
+ && n.nodeName === selectors) {
29
+ element = n;
30
+
31
+ return true;
32
+ }
33
+
34
+ return false;
35
+ });
36
+
37
+ return element;
38
+ }
39
+
40
+ /**
41
+ * Visits each Node in the tree of a specific root Node (using depth-first
42
+ * traversal) and invokes a specific callback until the callback returns true.
43
+ *
44
+ * @param {Node} node - The root Node which represents the tree of Nodes to
45
+ * visit.
46
+ * @param {Function} callback - The callback to invoke with each visited Node.
47
+ * @returns {boolean} - True if the specified callback returned true for a Node
48
+ * (at which point the visiting stopped); otherwise, false.
49
+ */
50
+ function _visitNode(node, callback) {
51
+ if (callback(node)) {
52
+ return true;
53
+ }
54
+
55
+ /* eslint-disable no-param-reassign, no-extra-parens */
56
+
57
+ if ((node = node.firstChild)) {
58
+ do {
59
+ if (_visitNode(node, callback)) {
60
+ return true;
61
+ }
62
+ } while ((node = node.nextSibling));
63
+ }
64
+
65
+ /* eslint-enable no-param-reassign, no-extra-parens */
66
+
67
+ return false;
68
+ }
69
+
70
+ (global => {
71
+ // DOMParser
72
+ //
73
+ // Required by:
74
+ // - lib-jitsi-meet requires this if using WebSockets
75
+ global.DOMParser = DOMParser;
76
+
77
+ // addEventListener
78
+ //
79
+ // Required by:
80
+ // - jQuery
81
+ if (typeof global.addEventListener === 'undefined') {
82
+ // eslint-disable-next-line no-empty-function
83
+ global.addEventListener = () => {};
84
+ }
85
+
86
+ // removeEventListener
87
+ //
88
+ // Required by:
89
+ // - features/base/conference/middleware
90
+ if (typeof global.removeEventListener === 'undefined') {
91
+ // eslint-disable-next-line no-empty-function
92
+ global.removeEventListener = () => {};
93
+ }
94
+
95
+ // document
96
+ //
97
+ // Required by:
98
+ // - jQuery
99
+ // - Strophe
100
+ if (typeof global.document === 'undefined') {
101
+ const document
102
+ = new DOMParser().parseFromString(
103
+ '<html><head></head><body></body></html>',
104
+ 'text/xml');
105
+
106
+ // document.addEventListener
107
+ //
108
+ // Required by:
109
+ // - jQuery
110
+ if (typeof document.addEventListener === 'undefined') {
111
+ // eslint-disable-next-line no-empty-function
112
+ document.addEventListener = () => {};
113
+ }
114
+
115
+ // document.cookie
116
+ //
117
+ // Required by:
118
+ // - herment
119
+ if (typeof document.cookie === 'undefined') {
120
+ document.cookie = '';
121
+ }
122
+
123
+ // document.implementation.createHTMLDocument
124
+ //
125
+ // Required by:
126
+ // - jQuery
127
+ if (typeof document.implementation.createHTMLDocument === 'undefined') {
128
+ document.implementation.createHTMLDocument = function(title = '') {
129
+ const htmlDocument
130
+ = new DOMParser().parseFromString(
131
+ `<html>
132
+ <head><title>${title}</title></head>
133
+ <body></body>
134
+ </html>`,
135
+ 'text/xml');
136
+
137
+ Object.defineProperty(htmlDocument, 'body', {
138
+ get() {
139
+ return htmlDocument.getElementsByTagName('body')[0];
140
+ }
141
+ });
142
+
143
+ return htmlDocument;
144
+ };
145
+ }
146
+
147
+ // Element.querySelector
148
+ //
149
+ // Required by:
150
+ // - lib-jitsi-meet/modules/xmpp
151
+ const elementPrototype
152
+ = Object.getPrototypeOf(document.documentElement);
153
+
154
+ if (elementPrototype) {
155
+ if (typeof elementPrototype.querySelector === 'undefined') {
156
+ elementPrototype.querySelector = function(selectors) {
157
+ return _querySelector(this, selectors);
158
+ };
159
+ }
160
+
161
+ // Element.remove
162
+ //
163
+ // Required by:
164
+ // - lib-jitsi-meet ChatRoom#onPresence parsing
165
+ if (typeof elementPrototype.remove === 'undefined') {
166
+ elementPrototype.remove = function() {
167
+ if (this.parentNode !== null) {
168
+ this.parentNode.removeChild(this);
169
+ }
170
+ };
171
+ }
172
+
173
+ // Element.innerHTML
174
+ //
175
+ // Required by:
176
+ // - jQuery's .append method
177
+ if (!elementPrototype.hasOwnProperty('innerHTML')) {
178
+ Object.defineProperty(elementPrototype, 'innerHTML', {
179
+ get() {
180
+ return this.childNodes.toString();
181
+ },
182
+
183
+ set(innerHTML) {
184
+ // MDN says: removes all of element's children, parses
185
+ // the content string and assigns the resulting nodes as
186
+ // children of the element.
187
+
188
+ // Remove all of element's children.
189
+ this.textContent = '';
190
+
191
+ // Parse the content string.
192
+ const d
193
+ = new DOMParser().parseFromString(
194
+ `<div>${innerHTML}</div>`,
195
+ 'text/xml');
196
+
197
+ // Assign the resulting nodes as children of the
198
+ // element.
199
+ const documentElement = d.documentElement;
200
+ let child;
201
+
202
+ // eslint-disable-next-line no-cond-assign
203
+ while (child = documentElement.firstChild) {
204
+ this.appendChild(child);
205
+ }
206
+ }
207
+ });
208
+ }
209
+
210
+ // Element.children
211
+ //
212
+ // Required by:
213
+ // - lib-jitsi-meet ChatRoom#onPresence parsing
214
+ if (!elementPrototype.hasOwnProperty('children')) {
215
+ Object.defineProperty(elementPrototype, 'children', {
216
+ get() {
217
+ const nodes = this.childNodes;
218
+ const children = [];
219
+ let i = 0;
220
+ let node = nodes[i];
221
+
222
+ while (node) {
223
+ if (node.nodeType === 1) {
224
+ children.push(node);
225
+ }
226
+ i += 1;
227
+ node = nodes[i];
228
+ }
229
+
230
+ return children;
231
+ }
232
+ });
233
+ }
234
+ }
235
+
236
+ global.document = document;
237
+ }
238
+
239
+ // location
240
+ if (typeof global.location === 'undefined') {
241
+ global.location = {
242
+ href: '',
243
+
244
+ // Required by:
245
+ // - lib-jitsi-meet/modules/xmpp/xmpp.js
246
+ search: ''
247
+ };
248
+ }
249
+
250
+ const { navigator } = global;
251
+
252
+ if (navigator) {
253
+ // userAgent
254
+ //
255
+ // Required by:
256
+ // - lib-jitsi-meet/modules/browser/BrowserDetection.js
257
+ let userAgent = navigator.userAgent || '';
258
+
259
+ // react-native/version
260
+ const { name, version } = require('react-native/package.json');
261
+ let rn = name || 'react-native';
262
+
263
+ version && (rn += `/${version}`);
264
+ if (userAgent.indexOf(rn) === -1) {
265
+ userAgent = userAgent ? `${rn} ${userAgent}` : rn;
266
+ }
267
+
268
+ // (OS version)
269
+ const os = `(${Platform.OS} ${Platform.Version})`;
270
+
271
+ if (userAgent.indexOf(os) === -1) {
272
+ userAgent = userAgent ? `${userAgent} ${os}` : os;
273
+ }
274
+
275
+ navigator.userAgent = userAgent;
276
+ }
277
+
278
+ // WebRTC
279
+ require('./webrtc');
280
+
281
+ // Performance API
282
+
283
+ // RN only provides the now() method, since the polyfill refers the global
284
+ // performance object itself we extract it here to avoid infinite recursion.
285
+ const performanceNow = global.performance.now;
286
+
287
+ const perf = require('react-native-performance');
288
+
289
+ global.performance = perf.default;
290
+ global.performance.now = performanceNow;
291
+ global.PerformanceObserver = perf.PerformanceObserver;
292
+
293
+ // Timers
294
+ //
295
+ // React Native's timers won't run while the app is in the background, this
296
+ // is a known limitation. Replace them with a background-friendly alternative.
297
+ if (Platform.OS === 'android') {
298
+ global.clearTimeout = BackgroundTimer.clearTimeout.bind(BackgroundTimer);
299
+ global.clearInterval = BackgroundTimer.clearInterval.bind(BackgroundTimer);
300
+ global.setInterval = BackgroundTimer.setInterval.bind(BackgroundTimer);
301
+ global.setTimeout = (fn, ms = 0) => BackgroundTimer.setTimeout(fn, ms);
302
+ }
303
+
304
+ // localStorage
305
+ if (typeof global.localStorage === 'undefined') {
306
+ global.localStorage = new Storage('@jitsi-meet/');
307
+ }
308
+
309
+ // sessionStorage
310
+ //
311
+ // Required by:
312
+ // - herment
313
+ // - Strophe
314
+ if (typeof global.sessionStorage === 'undefined') {
315
+ global.sessionStorage = new Storage();
316
+ }
317
+
318
+ global.TextDecoder = TextDecoder;
319
+ global.TextEncoder = TextEncoder;
320
+
321
+ // atob
322
+ //
323
+ // Required by:
324
+ // - Strophe
325
+ if (typeof global.atob === 'undefined') {
326
+ global.atob = atob;
327
+ }
328
+
329
+ // btoa
330
+ //
331
+ // Required by:
332
+ // - Strophe
333
+ if (typeof global.btoa === 'undefined') {
334
+ global.btoa = btoa;
335
+ }
336
+
337
+ })(global || window || this); // eslint-disable-line no-invalid-this
@@ -0,0 +1 @@
1
+ import './browser';